Spec Drift: Fix the Spec, Fix It Once

Home
/
Insights
/
Spec Drift: Fix the Spec, Fix It Once
Table of contents
Preamble

Spec drift happens when a developer fixes agent-generated code by hand and leaves the specification unchanged. The fix works today, but the spec now describes a different system from the one in production, and the next regeneration can bring the bug straight back. The remedy is to put the fix in the spec and regenerate.

We see this in our own delivery work. Ned Lowe, our Co-Founder and CTO, wrote it up as a dev tip for our developers on 24 September 2026, and a short version became a LinkedIn post. This is the longer version for a deeper dive into the topic.

How spec drift starts with a two-minute fix

Spec drift usually begins with a sensible decision. An agent generates auth middleware from the spec, and the middleware mostly works. Expired tokens, though, slip past the checks and come back as a 500 error. The developer reviewing it can see the three lines at fault, corrects them and moves on.

The tests pass and the ticket closes. But the knowledge of how expired tokens should behave now lives only in the code. The spec still says nothing about token expiry, and the spec is the first thing the next agent, and the next engineer, will read.

Why spec drift compounds when agents do the building

In a hand-written codebase, a patch stays where you put it. With agents, code gets regenerated, sometimes a whole module at a time, from whatever the spec says. So a fix that exists only in code is one regeneration away from disappearing. Ned's note sketched the likely sequence: a few weeks later someone regenerates the auth module for an unrelated change and ships the same 500 again.

There is a second cost that is easier to miss. Agents build against the context they are given and fill any gap with a guess. A spec that has drifted from the system produces output that is wrong in the same way every time, which makes the problem harder to spot than a one-off bug. And everyone who reads that spec to understand the system learns something slightly untrue.

The Validate stage rule in ACDC

ACDC, our Agent Centric Development Cycle, is the delivery method we use for agent-built software, and its Validate stage carries a simple rule. The specification is the source of truth, and code sits downstream of it. When validation turns up a defect, the correction goes into the spec first.

That rule follows from where we spend our time. In ACDC around half of a sprint goes on getting the specification right, as we set out in Uncomfortably Simple in the Age of AI. If the spec is where the effort goes, it has to stay accurate, or that effort is wasted the first time someone patches around it. The exposure is growing too. Sonar has reported that 42 percent of committed code is now AI-generated or assisted, a figure we discussed in Agents, Insurance, and the End of Vibe Coding.

A worked example: the expired token

Take the middleware again. Instead of editing the handler, the developer opens the spec and adds one line under Edge Cases:

“Expired JWT returns 401 with error code token_expired; client must not retry without refresh.”

Then they regenerate the module. The agent now produces a handler that returns a 401 with a named error code, and because the behaviour is written down, a test can check for it. Every agent that touches auth from that point on inherits the rule, and so does every engineer who opens the spec.

The spec update costs roughly five extra minutes compared with the hand-patch. We think that is a fair price. A hand-patch has to be repeated after every regeneration that loses it, and each repeat starts with someone rediscovering the bug and then working out why it came back.

Is code only a derivative of the spec?

We should be careful about how far this goes. Ned's own note allowed that code may not be entirely derivative of the spec, and called that an open point of debate. Our On A Mission newsletter made a similar case in Specs, Code, and the Closing Frontier. Generating code from a spec is probabilistic, so every regeneration differs a little, and pinning every detail down in the spec would just reinvent source code in a fuzzier language.

So the rule applies to intent and behaviour. How the system should respond to an expired token belongs in the spec. The exact regex that validates an email field probably belongs in code. The drift to worry about is behaviour that matters to users or to other services and exists nowhere except the implementation.

How to stop spec drift on your team this week

Ned's suggestion for the week was a small experiment, and we would start there. The next time you are about to hand-edit agent output, stop. Write the missing line into the spec, regenerate, and time how long it really took. In our experience the gap is smaller than people expect.

After that, make it a review habit. When a pull request touches agent-generated code, ask whether the spec changed with it. If it did not, either the change was cosmetic or the spec has just drifted. And if your team keeps fixing the same problem in agent output, look in the spec first, because that is usually where the repeat is coming from.

{
Work with us
}

Start with one contained project.

Bring us the part that is stuck, whether in a team or a workflow.
Book 30 minutes with an engineer who has taken agentic delivery into production inside a regulated business.