Jay Stewart

Working with agents

The generation is the easy half.

A large share of the commits behind the work on this site were written with coding agents. I would rather state that plainly than have it inferred, because the interesting engineering is not in the generation — it is in everything built around it to make the output trustworthy.

The failure mode of agent-assisted development is not bad code. Bad code is caught by the same things that always caught it. The failure mode is plausible code: changes that read correctly, pass a cursory review, and encode a misunderstanding that surfaces weeks later. Volume makes that worse, because review attention is the fixed resource and generation is now effectively unbounded.

So the discipline moved to verification.

Gates that do not rely on my attention

Every mechanism below exists because a human reviewer — me, tired, on a Friday — is the least reliable component in the loop.

  • Ratchets rather than thresholds. Coverage on changed lines, a lint rule that fails only on new violations, a baseline that can improve and never regress. Agents produce a lot of diff; the gate scales with the diff rather than with my patience.
  • Drift guards. A generated document describing test behaviour fails CI when it no longer matches the suite. Documentation that cannot silently diverge is documentation you can still trust in six months.
  • A release gate, not a push. Production advances only after integration and end-to-end suites pass against the exact candidate. No individual commit is trusted on its own merits.
  • Guards against invisible breakage. A mobile over-the-air update that assumes native code the installed binary lacks crashes on launch and cannot be recovered remotely — so CI refuses the build rather than trusting anyone to remember.

Decision records as current policy

Both production systems carry numbered decision records — over two hundred between them. They are not history. They are the constraint set: reversing one means reading it first, and an agent given the relevant record argues from the same constraints I would.

This is the single highest-leverage thing I do. Most bad agent output traces back to missing context rather than missing capability, and a decision log is context in the form that survives being handed to someone — or something — that was not there at the time.

Context that lies

Which leads to the problem underneath all of it. The instruction files we hand agents rot exactly like comments rot, except they areexecuted rather than read sceptically.

An audit of one of my own repositories found environment variables for infrastructure decommissioned months earlier, configuration pointing at a database that no longer existed, and a stated pull-request policy the project had stopped following. Each was true when written. Rotted context is strictly worse than absent context, because it is followed with confidence.

So I wrote groundtruth, a small open-source CLI that turns the checkable claims in an agent-context file into assertions and fails CI when they drift. It is the only public piece of this work.

Where I keep the agent out

Not everywhere is appropriate. Money maths, authentication boundaries and migrations get written and reviewed the slow way — not because an agent cannot produce them, but because I need to hold the whole failure surface in my head, and reviewing something I did not write is not the same as knowing it.

There are also hard blocks. Agents in my main product repository cannot run the test suite locally: it exhausted the development machine’s memory often enough that the guard is enforced by tooling rather than by instruction. Every check runs server-side instead.

The honest summary

Agents let one engineer operate at a scale that would otherwise need several. They also make it trivial to produce more code than one person can genuinely review, which is a failure mode with no precedent in how most teams work.

Everything above is an attempt to keep the second thing from cancelling the first. I would expect to argue about the details with anyone who has run this at team scale, which is one of several reasons I am looking to work alongside people again.