Code from Spec

Could we stop reviewing code?

July 26, 2026

Could we stop reviewing code?

The results I find most interesting (and frustrating) in this project are the ones that go against what I thought I would be building. The theory produced several of them inside its own text; this journal entry is another.

When I started Code from Spec, I wanted review to move to the spec. If specifications were the "source of truth", then reading and approving the spec diff should be the natural path forward. Let the code follow as a consequence.

Even bolder: the GitHub repo keeps only the specs, and the source code is generated by the build pipeline, much like binaries are generated from source code today. There is no code diff to skip, because there is no code in the repo.

The theory went up a week ago, and that was the perfect opportunity to check this against a vocabulary instead of arguing by feel.

It does not hold up

The point of reading what gets deployed is knowing what you are shipping. Approving a spec is knowing what you asked for. They are not the same thing, and the distance between the two is the whole argument.

A spec does not describe one program. It describes a region, the set of every program it would accept. The generator picks one point in that region, and picking is a draw, not a calculation.

So the spec aims but does not bind — the generator can be told exactly what to do and still do something else. The theory calls that nonconformance, and it survives even a perfect spec. The spec diff shows the aim. Where the draw landed is a different fact, recorded in a different place.

Then there are the silences, and those are worse because they are not a failure mode. They are how specs work: a spec only has to state what the generator's prior would otherwise resolve against this project's intent. Everything else it can leave quiet. The quiet is intentional, not accidental, but every silence is a delegation, and the delegation gets resolved by the draw, in the code, and nowhere else. To review it from the spec alone you would have to know how the prior resolves it, and nobody does. You cannot even list the silences: there is no procedure that takes a spec and returns everything it failed to say.

Finally, anchoring. In Anchoring on old code I described it: the spec changes, the agent preserves the old behavior. Anchored code is a valid file that compiles and looks right, because it was the correct answer yesterday. Nothing is wrong with the artifact by itself. The failure is in the relation between the two: the spec asked for movement and the code did not move.

What about the test suite?

That is the natural objection at this point. If the tests are good enough, they catch whatever the reading would have caught, and the reading is redundant.

But look at what a real change does. The spec moves, and the test spec moves with it, because the new behavior is supposed to be verified. Both get regenerated. The suite is not a fixed instrument watching a moving artifact, it is a second artifact moving alongside the first, drawn the same way.

So everything above applies to it again.

The test spec aims, and the generated assert can miss what it says. The test spec has silences, and the generator resolves them from the same prior, so what actually gets checked is partly a draw and not a decision. The test agent also sees the previous test file, so it can preserve the old assertion for the same reasons the implementation agent may preserve the old behavior. When both anchor, the suite goes green on the old behavior and reports success.

None of this makes the suite less valuable, quite the opposite. It is probably the most valuable thing an engineer maintains here. It is behavioral, mechanical, cheap to run, specific to this project, and it fires on every draw. No other check is all five of those at once, and it is also the only part that remembers mechanically. A lesson that lives in the code is erased by the next draw, while a lesson pinned in a test spec survives every one as the instruction of what to check. The check itself is remanufactured when regenerated. Cheap generation makes the case for a dense suite stronger than it has ever been, not weaker.

It is just not a check from outside, it is one more thing the same process drew, and that is why it cannot stand in for the reading.

What only the human reading brings

When no human reads the code, legibility stops mattering. The generator resolves naming and structure from its prior, nobody pushes back, and the cost of that is zero — until somebody has to enter the code. That day comes when the subtle incident arrives, the one that behavioral diagnosis cannot crack. The engineer who walks in finds an artifact that nothing ever optimized for reading. Not reading the code did not remove the need to read it; it moved all of the reading to the worst possible day.

There is also a simpler point. A model reviewing generated output shares the habits that produced it. A human reader was trained differently and fails differently, and that difference is where the catches come from.

One caveat. A reader can only judge intent they personally hold. An engineer holds the engineering intent (cost, structure, failure modes) and reads the business intent as an encoding, like everybody else. A domain expert holds the business intent and cannot read the code at all. It is rare that someone holds both.

Where it would actually work

Take a component whose behavior is fully covered by tests. A small enough domain, a test vector for every input, nothing left to judgment. There, approving the spec diff without reading the generated code is legitimate. Whatever the draw resolved, the test vectors confirm it, and nothing unwritten is at stake.

Now make a substantive change to that component. The spec moves, the test specs move with it, and the asserts get regenerated, re-drawn where the change is. The protection was earned against the old behavior, and the change re-manufactures it exactly where the change is. If the new test vectors are authored by hand (exact input/output pairs, not generated assertions) the corner holds: the draws have nothing left to resolve, and reviewing the vector diff is reviewing the spec. Outside that narrow case, what the change reopened is decided by a draw, and the reading stays. Removing it does not eliminate the cost of the human verdict, it defers it — paid as an incident, on the exact dimension nobody watched, on production's schedule.

What is left of the rationale

The original rationale promised a destination: domain experts contributing specifications inside engineering guardrails, the way product developers ship on a platform team's golden paths. But the domain expert does not read code; so what can they actually do?

Review has two jobs, not one. The first is checking whether we asked for the right thing. The spec can be wrong, and nothing derived from the spec catches that, because the checks agree with the spec by construction. Only somebody holding the intent can catch it. The expert is the one holding the intent, and a test description states expected behavior in the domain's own language, so they can do this job by reading. That is what the expert is for.

The second job is checking whether the generator did what the spec says. That one needs somebody who reads code. The expert taking the first job does not shrink the second.

The first job is real and narrow. It does not catch the generator ignoring what the spec said, because that failure exists only in the code. It does not catch what the spec failed to say, because the scenario nobody wrote is not there to be objected to. It covers what is written, it goes stale as intent moves, and it has to recur. There is also a trap: a green suite plus expert-approved scenarios reads as verified, while the actual risk is the scenarios nobody wrote.

The expert's reading also reprices the spec. Every clause added for their benefit buys a dimension they can rule on, even one the generator never needed. Expert participation is bought with spec length, and that is a real purchase — a longer spec in the domain's language is readable in exactly the way source code never is.

The rationale compares this to a platform team. A product developer deploys without anyone watching because the pipeline covers everything. In spec-driven development, the pipeline does not cover everything. Staleness, confinement, types, tests — those work. But the silences are resolved in the code, and catching one resolved wrong requires that a person read the code. An engineer must stay in the loop, doing work the platform analogy said would go away.

That makes the destination narrower than the rationale described. The expert can contribute where the checks cover everything — a quarterly tax table, a pure function with exact outputs. Outside that, an engineer reads the code, and there is no version of this methodology where that stops being true.

The bottom line

Reviewing the spec tells you what you asked for. Reading the code tells you what you got. You need both. And if the reading stays, it is the constraint. The change a project can absorb is bounded by how much its people can read, not by how much the model can generate. Minimal regeneration is not a stability convenience, it is the mechanism that funds the reading: a small diff is a cheap reading.