ES

Spec-driven development: what it solves, what it costs, when to use it

Leo G.10 minLeer en español

An annotated architectural floor plan with drafting pencils and a ruler on top.
An annotated architectural floor plan with drafting pencils and a ruler on top.

A database requirement was missing from the request. The agent did not ask: it assumed a reasonable default and carried on. By the time someone noticed, that assumption was replicated across dozens of files and removing it cost more than the feature itself. The Nearform team documented the case, and it is the one that best explains why spec-driven development exists.

The idea, in one line: write a specification before generating code, and treat that specification as the project’s source of truth. Below is what problem it actually solves, what it costs —which is not little— and how to decide whether it is worth it for your change or just ceremony. Spoiler for the last part: it is not a methodology you adopt or don’t, it is a dial you turn up or down depending on the size of the change.

What it is, concretely

What SDD inverts is which of the two is in charge: the specification or the code. In ordinary development the code is the truth, and the document describing it is a reflection that ages the moment somebody touches something. Here it is the other way round: the specification lives versioned in the repository alongside the code, and when a requirement changes you edit that document and regenerate what follows from it — never the reverse.

The reference implementation is GitHub’s Spec Kit, and it is worth looking at because it makes concrete something usually explained in the abstract. Five stages, each producing a text file the next one reads:

  1. constitution — the project rules that do not get re-argued on every task: which database is used, that every new API is versioned, that nothing merges without a test. Written once.
  2. specify — turns the request in prose into a structured specification. It defines what the system has to do, without going into how.
  3. plan — only here do the technical decisions appear: the how.
  4. tasks — splits that plan into small pieces that can each be done and verified on their own.
  5. implement — the only step where code gets written.

In between there are review gates. The two most used are clarify, which comes after specify and exists so the agent asks about what is missing instead of assuming it, and validate at the end, which checks that what was implemented matches what the specification said.

And although it is drawn as a list, it is not walked once: any gate can send you back, and the cycle repeats until a full pass produces no changes. Only then is it done.

Other tools have their version of the same scheme: AWS’s Kiro, OpenSpec, BMAD, Tessl, and what Claude Code, Cursor and Antigravity ship. The names change; the shape does not.

The thing to notice when you see the flow laid out is that code shows up in the last step of five. Everything before it is agreeing on what to build.

Not everyone means the same thing by “SDD”

There is a confusion worth clearing up early, because it explains why two people argue about SDD without discussing the same thing. Birgitta Böckeler, of Thoughtworks (opens in a new tab), compared three tools that present themselves as spec-driven —Kiro, spec-kit and Tessl— and found they are not one practice but a ladder of ambition, with three rungs. The names she gave them are the ones in use today:

  • Spec-first. The specification guides the initial generation, and what gets maintained afterwards is the code. The spec was starter fluid, not a permanent structure: once it has done its job, it is left to die. It is the cheapest rung and it already captures most of the benefit.
  • Spec-anchored. The specification stays alive. Changes go through it first and from there down into the code, by regeneration or guided edits. It becomes a permanent governance layer, with the maintenance cost that implies.
  • Spec-as-source. The specification is the only thing you maintain and the code is its compiled output, like a compiler’s binary. It is the highest rung and today it is reserved for environments with deterministic generation.

It is worth noticing where each criticism lands. The “this is waterfall” accusation aims mostly at the top two rungs. And almost everyone who says they do SDD is, in practice, on the first one.

What it solves

There is only one argument in favour, but it is a good one: an agent leaves no gaps.

When a person is missing a detail, they ask, or at least leave a TODO that someone can see. An agent does neither: where a definition is missing, it puts in the most plausible assumption and carries on as if nothing happened. That is not a flaw in the AI model — it is what it does well. The problem is that the assumption then spreads through every file it touches, and by the time the symptom appears there is no single place to fix it; there are twenty.

That is the real value of a spec, and it is worth stating precisely: it is not there to document, it is there to remove ambiguity before generating. It is the difference between finding out you forgot to define something while you are writing it down —free— and finding out once it is implemented across dozens of files.

In practice the difference looks like this. The usual request:

Add CSV export for orders.

The same thing, with no gaps:

Order CSV export

  • Columns: id, date (ISO 8601 format), customer, total, currency.
  • Filters by date range. With no range, exports the last 30 days.
  • Above 10,000 rows it runs in the background and notifies by email.
  • Amounts use a decimal point and two decimals, no thousands separator.
  • Cancelled orders are not exported.

Every one of those lines is a decision the agent will otherwise make on its own, without telling you. And look at the last one: it is the kind nobody remembers to state, that the agent resolves the most obvious way —export everything— and that nobody catches until finance asks why the report totals do not match the system’s.

What it costs

This is where most of what is published turns enthusiastic and should not. The criticisms are concrete and come from people who used it.

The process eats small tasks. On a minor refactor or a UI tweak, you end up spending more time managing the workflow than delivering. There is a published experiment where someone compared OpenSpec against simply writing an Instructions.md file with the guidance, and the plain file turned out faster, cheaper and easier to iterate on.

The discipline evaporates. The accounts agree that the method holds up until the agent starts writing code; from there the spec gets consulted less and less, and what remains is a feeling of control greater than the real thing.

Specifying early fails when the requirement does not exist yet. The typical case: a client asking for “AI insights on this data” who cannot tell you what they need until they see something working. Specifying there is inventing. The recommendation is the reverse — throwaway prototype first, spec afterwards, once you know what you are building.

And the sharpest objection, which is systemic: speeding up code production does not speed up delivery if review, verification and integration keep the capacity they had. Producing twice the code with the same people reviewing does not give you twice the software shipped; it gives you a longer queue in front of the bottleneck. That is the criticism behind the most-read Hacker News thread on the subject being titled “The Waterfall Strikes Back”: for many people this is big design up front under a new name.

One detail worth registering: even the academic paper that systematises the practice closes with a framework for deciding when it is worth it and when something simpler will do. Nobody serious is selling it as universal.

When to use it

The useful question is not whether to adopt SDD, but how much of those five stages is worth running for the change in front of you. Two things decide it: how many files it touches, and what happens if the agent assumes wrong.

The first three cases go by size, smallest to largest.

  • It touches one or two files and a git revert undoes it. Just ask for it, with nothing written up front: a bug that already has a failing test, a string that changes, a rename. Writing the specification here takes longer than making the change.

  • It touches several files, in a part of the system you know. You do not need the whole workflow: two of the five stages are enough, done by hand and kept short. Note down in three or four lines what has to happen and what must not, and before it writes a line of code, ask it to tell you how it plans to solve it. This is the point of the method where the least effort buys the most.

  • It touches many files, or being wrong is expensive. Changing the data model, anything crossing several modules, anything that moves money or decides permissions. Here the full workflow earns its place, review gates included: this is exactly the scenario it was invented for, where one gap does not stay in one file but replicates across all of them.

And one rule that overrides the three above, whatever the size:

  • If you do not know yet what you want, do not specify. When the requirement is not clear —yours or the client’s— a throwaway prototype comes first, and the specification only once you have seen something working. The other way round, all you achieve is writing down very precisely something you are going to throw away.

Put in the terms of the ladder above: for almost everyone the right place is the first rung, spec-first. Climbing to spec-anchored —keeping the specification alive forever— is only justified once several people are working on the same thing and the cost of each understanding it differently outweighs the cost of maintaining the document.

There is also a precondition that has nothing to do with the spec: if the project cannot verify itself, no specification saves it. The agent can hold the most precise document in the world and still be unable to check whether what it wrote satisfies it — we covered that here.

The spec is for before, not after

If you keep one idea: a specification pays when it is written before generating and to close ambiguities, not when it is written afterwards to document. A spec drafted once the code is finished is documentation, with the usual fate: it ages and nobody reads it.

And the practical corollary, less impressive but more useful: almost all of the benefit sits in the cheapest of the five steps. Before the agent writes a line, ask it to tell you what it understood and how it plans to do it. If that does not match what you had in your head, you have just saved yourself the twenty corrections that were coming.

If you got this far and want the practical side —how to write a specification with no gaps, with which templates, and where to start— we continue in the next article.

Comments