Spec-driven development
The premise: when a coding agent can produce a thousand lines in a minute, the bottleneck moves from writing code to specifying what should exist and verifying that it does. Spec-driven development makes the specification a durable, versioned artifact that the agent works from, rather than a prompt that scrolls out of the chat.
It is a reaction to a real failure mode — an agent that confidently builds the wrong thing, fast — so the interview framing is about control, not ceremony.
The loop
spec ──> plan ──> verify plan ──> implement ──> quality gate
▲ │
└───────────────── spec is updated ─────────────────┘Three artifacts, each a file in the repo, each reviewable in a pull request:
| Artifact | Answers | Reviewed by |
|---|---|---|
| Spec | what and why | a human |
| Plan | how, in steps | a human or verifier |
| Tests | did it work | CI |
The discipline is that the spec is the source of truth and the code is downstream of it. When behaviour needs to change you change the spec, then regenerate or amend the plan. A change made only in code is drift, and the next agent run works from a spec that no longer describes the system.
What goes in a spec
Not a design document. A spec that an agent can work from is closer to an acceptance-test list than to prose:
- The user-visible behaviour, in terms someone outside the codebase uses.
- Explicit non-goals. Cheap to write, and the single highest-value section, because scope creep is what an unconstrained agent does by default.
- Constraints — the existing patterns, libraries and boundaries it must work within.
- Acceptance criteria that can be mechanically checked.
- Open questions, so uncertainty is visible rather than silently resolved by whatever the model guessed.
The last two are what separate this from writing a longer prompt. A prompt is discarded; a spec with acceptance criteria becomes the thing you test against.
The plan-verifier pattern
A second agent reviews the plan before any code is written, with a different prompt and no attachment to the first agent’s reasoning.
plan = planner(spec)
review = verifier(
"Check this plan against the spec. Report only: steps that do not "
"trace to a requirement, requirements with no step, and assumptions "
"not stated in the spec. Default to rejecting.",
spec=spec, plan=plan,
)
if review.blocking:
plan = planner(spec, feedback=review) # one revision, then a humanIt works for the same reason code review does: the cost of finding a wrong approach at plan stage is minutes, and at implementation stage it is the whole change. Two properties make it worth the extra call:
- Independence. A verifier that sees the first agent’s justification tends to agree with it. Give it the spec and the plan, not the reasoning.
- A bias toward rejection. A verifier that approves by default is a rubber stamp that costs tokens. Prompt it to look for gaps in both directions — steps with no requirement, and requirements with no step.
This generalises the adversarial-verification idea from Agent Patterns — Plan-and-Execute, Reflection, Cost, Evaluation to the planning stage.
Quality gates
The gate is what makes the loop closed rather than advisory. It runs in CI and blocks the merge:
- run: ruff check . && ruff format --check .
- run: mypy --strict src/
- run: pytest --cov=src --cov-fail-under=80
- run: python tools/check_spec_coverage.py # every criterion has a testThe last line is the spec-driven part. Acceptance criteria are numbered in the spec and referenced from tests, so a criterion with no test fails the build. Without it, “we have a spec” degrades into a document nobody reads.
For LLM features the gate also includes an eval threshold — see Building eval sets. The principle is identical: a number decided in advance, checked mechanically, blocking release.
Where it does not help
Worth saying, because unqualified enthusiasm reads as inexperience.
- Exploratory work. When you do not know what you are building, writing a spec first is guessing formally. Prototype, then specify what survived.
- Small changes. A one-line fix does not need three artifacts. The ceremony has to be proportionate or people route around it.
- When the spec is not maintained. A stale spec is worse than none, because agents and humans both trust it.
- As a substitute for review. A verified plan is still a plan a model made.
Related
Interview angle 4
- “What is spec-driven development?” - making the specification a versioned artifact in the repo that agents work from, with acceptance criteria that CI can check, so the bottleneck moves from producing code to deciding what should exist and proving it does. Follow-up: how is that different from a long prompt? A prompt is discarded; a spec is reviewed, versioned and tested against.
- “What is a plan-verifier and why bother?” - a second agent that checks the plan against the spec before implementation, prompted to reject by default and given the spec and plan but not the first agent’s reasoning. Catching a wrong approach at plan stage costs minutes rather than the whole change.
- “What stops the spec going stale?” - a gate that fails the build when an acceptance criterion has no test referencing it. Without a mechanical link, the document decays and everyone keeps trusting it.
- “When would you not use this?” - exploratory work where you do not yet know the shape, and small changes where the ceremony outweighs the change. Proportion matters, or people route around the process.