← cd ~/timeline
AI Harness

2025

AI Harness

The system that helps me build better software, faster.

$ cat build.log

What I built

  1. 01

    Discover — turn a fuzzy idea into clear, written requirements

  2. 02

    Model the data it will store and how that state is owned

  3. 03

    Architect the system — data model, call graph, and the data contract both sides obey

  4. 04

    Verify every requirement and the contract against the real codebase

  5. 05

    Design the journey and interface against that verified contract

  6. 06

    Plan the build as small, independently checkable phases

  7. 07

    Lint the plan — a deterministic readiness check before any code is written

  8. 08

    Write the failing tests first

  9. 09

    Build phase by phase behind quality gates, then ship a reviewed pull request

The most recent piece: a harness that makes building software itself faster and safer — skills, rules and checks that raise the floor on everything I ship, including this site.

The problem

AI is non-deterministic, and it ships with no guardrails of its own. Ask it the same question twice and you can get two different answers. Hand it a gap in a spec and it will fill that gap — with an assumption, a guess, or an outright fabrication — and present all three with the same even confidence. Left to run unsupervised, it doesn't stop at the edge of what it knows; it improvises past that edge and reports the improvisation as fact.

The most expensive version of this isn't the bug you can spot in a diff. It's the confident, wrong claim you can't: "tests pass," when they were never run; "that function exists," when it was renamed weeks ago; "fixed," with no check to show for it. The model isn't lying — it's pattern-matching "this looks done" and reporting a confidence it hasn't earned.

And that is uniquely dangerous precisely because AI is fast. The same speed that compresses a week of work into an afternoon lets a wrong claim reach production before a human ever looks at it. "Be more careful" is not a fix: care doesn't scale, and it doesn't survive a long session. The only thing that scales is a check that actually ran.

My approach

I approached it the way I'd approach any product problem — understand the failure, then design a system that structurally prevents it, rather than hoping for better behaviour. Two ideas from the field shaped that system. The first is Andrej Karpathy's work on building with AI: his framing of fast, AI-assisted "vibe coding," and his self-improving research loop — mutate an approach, score it against a hard, binary check, and keep only what measurably improves — which the harness now ships as a skill of its own. The second is Google's New SDLC with Vibe Coding whitepaper, which reframes the lifecycle around two moves: a contract — the exact shape of any data that crosses a boundary, agreed once, before code, and enforced so a mismatch becomes a compile error rather than a production incident — and a continuous-quality flywheel: evaluate, diagnose, optimise, verify, monitor. Vibe coding supplies the speed; the contract and the flywheel are what stop that speed from turning into the confident-wrong-claim problem above. The harness runs all of it at once — it keeps the pace of building with AI, but wraps every step in a lifecycle that has to prove its own work.

Four principles hold it together. No "done" without proof — never claim something passes, works, or exists without running a check and showing its output. Independence beats self-review — a model that grades its own work inherits its own blind spots, so the load-bearing checks go to a fresh session, or to a different model told to disprove the work. Knowledge has to compound — every durable fact has exactly one home and one format, so the next session starts informed instead of re-deriving what the last one already learned. And keep the human in the loop only on the decisions that are genuinely theirs — the outcomes, not the mechanics — and let the machine settle the rest.

What I built

A portable engineering harness that sits on top of Claude Code, built from three kinds of part. Rules are always-on constraints the model must obey. Skills are around forty named workflows I invoke by command. Hooks are scripts that fire automatically and mechanically block an action — a commit without proof, a merge while the tests are red — so a rule can't be quietly forgotten fifteen thousand tokens into a session. Rules say what should happen; hooks make it happen whether the model remembers or not.

On top of that sit two distinct ways of working, matched to the size of the job. The first is the planning pipeline, for anything non-trivial: discovery, architecture, a technical feasibility pass, then a phased plan, tests-first, and build. Two rules give it its spine. Architecture produces a contract — the exact shape of the data that moves between the parts of the system — and every later stage is checked against it, so a front-end and a back-end can't quietly drift out of agreement: a mismatch shows up as a failed build, not a bug a user finds. And each stage runs in its own fresh session with no memory of the last, so every step evaluates the work cold instead of rubber-stamping the reasoning that produced it, with independent review by a separate model woven through the chain. That second rule matters more than it sounds: when planning and building happen in a single continuous session, the plan just reflects what the session already talked itself into. Measured on the project I extracted this from, plans written that way failed independent evaluation roughly three times in four. Fresh eyes at every step — and a contract to check against — are what close that gap.

The second is a fast lane for everyday work — a reported bug or a small change. It runs end to end on its own: diagnose the symptom, file an issue, write a failing test that reproduces it, make the fix, run four independent layers of verification, and open a single pull request — with no back-and-forth in between. A change that touches something sensitive, like authentication or the data schema, automatically routes through one extra approval gate; everything else simply ships to a PR for review. The point is proportionality: not every fix deserves the full pipeline, but the four-layer quality bar never drops, however small the change.

Underneath both runs the part I'm most pleased with: a loop that makes the harness better at catching its own mistakes. Every failure is logged; recurring ones are promoted into named failure modes; and each is closed not with a reminder to try harder but with a structural fix — a new check, a new gate, a retargeted rule. That is the flywheel's monitor–diagnose–optimise arc made real, and the same self-improving pattern Karpathy describes: measure what went wrong, change the machine, keep only the changes that hold. And the whole thing is genuinely portable — I extracted it from one codebase, and it installs into a new repo and runs. It built this site.

Why it mattered

It changed what "done" means. Done is no longer a feeling; it's a check that ran, with output I can point to. Big changes get evaluated by something other than the thing that made them. The second time I hit a class of problem is cheaper than the first. And I'm only ever asked the questions that are genuinely mine to answer.

But the real reason it matters is that everything else I build runs on it. The research engine that scores ideas, the experiment engine that puts landing pages in front of real users, the Product-AI suite that pressure-tests my decisions, the tools that handle distribution and SEO — every one of them is built and shipped through this harness, held to the same standard. That's what turns a set of AI-first tools into a system you can actually trust rather than a pile of impressive prototypes. It's the foundation that lets a single product leader operate with the reach of a team without giving up quality or control — and it's the clearest evidence of how I'd set the standard for how a team builds, not just what it builds.

What I learned

The failure that matters most with AI isn't the error you can see in a diff — it's the confident, wrong claim you can't. You beat it with systems, not vigilance, because a check scales and good intentions don't.

The decision that paid off most was independence: the moment you let the thing that did the work also judge the work, you've lost the only reviewer with fresh eyes. And the through-line under all of it is that this was a product-management problem the whole time — define the way of working, encode it, enforce it mechanically, and let it compound. It's the same discipline I bring to a product organisation, pointed at how I build with AI: the standard lives in the system, not in anyone's memory.

$ ls skills/

Skills obtained

  • AI-first systems design
  • Contract-first data design
  • Ways-of-working design
  • Prompt & context engineering
  • Test-first verification
  • Multi-agent orchestration
  • Claude Code: rules, skills, hooks
  • Self-improving eval loops