"The Spec Is the Product" Is a Slogan Until the Code Leaves Your RepoChronograph<br>SearchSearch
Dark modeLight mode<br>Reader mode
{if(a.slugSegment===\"software-civil-engineering\")return-1;if(b.slugSegment===\"software-civil-engineering\")return 1;if(a.isFolder!==b.isFolder)return a.isFolder?-1:1;let isoDateRegex=/^\\d{4}-\\d{2}(-\\d{2})?$/;return isoDateRegex.test(a.slugSegment)&&isoDateRegex.test(b.slugSegment)?b.slugSegment.localeCompare(a.slugSegment):a.displayName.localeCompare(b.displayName,void 0,{numeric:!0,sensitivity:\"base\"})}","filterFn":"node=>node.slugSegment!==\"tags\"","mapFn":"node=>node"}">Explorer
Graph View
"The Spec Is the Product" Is a Slogan Until the Code Leaves Your Repo<br>Jul 22, 202624 min read<br>Martin Rosén-Lidholm
“The Spec Is the Product” Is a Slogan Until the Code Leaves Your Repo
Everyone agrees verification is the bottleneck. Almost nobody draws the conclusion<br>sitting in their .gitignore.
The bottleneck everyone agrees on
Here is the one thing the whole industry currently agrees on: with LLM agents, producing code is no longer the expensive part. Knowing it is right is. Verification is the bottleneck. Every serious writer on agentic engineering has landed there — the debates are about what to do about it.
The popular answer is “programming in English”: vibe coding, spec kits, spec-first IDEs. Capture intent in a markdown spec, let the agent transform it into code, keep the spec as the durable artifact. And that answer is right about exactly half of it. Intent, not code, should be the durable artifact.
But look at who performs the transformation in every one of those setups: an LLM . Markdown in, probabilistic code out. Every regeneration is a fresh stochastic outcome; diffs don’t compose; every run is a new review event. You declared “the spec is the product” — and then wired the world’s least deterministic compiler between the product and the thing that ships. The verification bottleneck you set out to relieve is now load-bearing on every regeneration.
There is a harder conclusion hiding under the consensus, and this article is about drawing it. It ends with C# files that are not source code, and a git rm that made a build more trustworthy.
The enemy has a name
Start with a question you can answer about your own codebase right now: how many places know that a customer has an email address?
The entity. The DTO. The AutoMapper profile. The EF Core configuration. The SQL column. The migration that created the column. The FluentValidation rule. The OpenAPI schema. The TypeScript interface. The test fixture. Ten representations of one domain fact — and every behavioral change is a coherent edit across ten sites at once.
One domain fact, ten restatements. No compiler error fires when any two of them disagree.
This deserves its own name: representational redundancy . Not “layers”, not “boilerplate” — restatement. The same truth transcribed between representations that no compiler holds together.
The diagnosis has allies in an entirely different tradition. Gîrba and Wardley’s Rewilding Software Engineering argues that manually produced views of a system “constitute beliefs rather than accurate engineering tools”, and their cure, Moldable Development (practiced in their Glamorous Toolkit), is deterministic derivation at read time: regenerate every view from the system on demand, so it cannot be stale. This article is the symmetric case on the write side: derive the system from the spec at build time, so the representations cannot drift.
Humans have always drifted on this — it is why “the documentation lies” became folklore. But notice exactly what LLM agents are worst at: coherent editing across many sites. The benchmarks are blunt about it: agents solve 22% of multi-file refactorings that human developers solve 87% of, and on natural-language feature addition the best models succeed on under a tenth of the instances that require multi-file edits. An agent produces plausible code at every individual site; it is between the sites that things break, and between the sites is precisely where no oracle lives (an oracle: any mechanical judge of correctness, a compiler error, a failing test). No compiler error fires when the validator disagrees with the DTO. No test fails when the OpenAPI schema drifts from the entity — until an integration test, minutes and containers away, maybe.
So representational redundancy is not merely expensive the way it always was. It is expensive precisely where the new workforce is weakest, and cheap verification is precisely what the new workforce needs most. Every restatement you delete is a class of agent error that can no longer occur.
Deterministic derivation does not manage that redundancy. It deletes it.
Who transforms, what verifies
There is a ladder, and the rungs differ in exactly two properties: who performs the transformation from intent to code, and what verifies the result.
Vibe coding. Transformer: an LLM, from English....