Spec-Driven Development
Write a clear spec that an agent implements: goals, scope, acceptance criteria, and constraints as the source of truth.
TL;DR
- For larger work, write a spec the agent implements: goals, scope, acceptance criteria, constraints.
- Acceptance criteria make 'done' checkable, so you can verify the result against the spec.
- The spec is the source of truth; refine it, not the code, when requirements change.
Why Spec First
Right ThingA clear spec aligns the build with what you actually need.
Spec defines the target before
any code is written.Checkable DoneAcceptance criteria let you verify success objectively.
Done = all criteria pass,
not "looks finished".Source Of TruthThe spec, not the code, is what you refine as needs evolve.
Change requirements -> change spec
-> reconcile code.Anatomy Of A Spec
Goal & WhyState the outcome and the reason it matters.
"Let users export orders to CSV so
they can reconcile in Excel."ScopeWhat is included and, explicitly, what is not.
In: CSV export of filtered orders.
Out: PDF, scheduling, email.ConstraintsStack, performance, security, and compatibility limits.
"Stream for >10k rows; owner-only;
no new deps."Acceptance Criteria
Testable StatementsWrite given/when/then so each is verifiable.
"Given 0 orders, when I export,
then I get a header-only CSV."Cover EdgesInclude empty, large, and error cases, not just the happy path.
"Given a failed query, then a 500
with a safe message."Doubles As TestsCriteria map directly to the tests that prove done.
Each criterion -> one test.Drive The Build
Hand Over The SpecGive the agent the spec and ask for a plan against it.
"Here's the spec. Plan the
implementation against it first."Verify Against ItCheck the build criterion by criterion.
"For each acceptance criterion,
show it is met."Keep Spec CurrentWhen scope shifts, update the spec and re-reconcile.
Edit spec -> "reconcile the code
to the updated spec."Tips
- Write acceptance criteria as testable statements ('given X, when Y, then Z').
- State what is explicitly out of scope so the agent does not gold-plate.
Warnings
- A vague spec yields a confident wrong feature; ambiguity in the spec becomes bugs in the build.
- Skipping acceptance criteria leaves 'done' undefined, so you cannot tell if the agent succeeded.
In Practice
A compact spec for a feature, goal, scope, constraints, and testable acceptance criteria, that you hand to an agent as the source of truth. It plans against the spec, builds, and you verify criterion by criterion.
- The goal and why orient the agent toward the real outcome.
- Explicit in-scope and out-of-scope lines prevent gold-plating.
- Constraints pin the stack and the non-functional requirements.
- Testable acceptance criteria define done and double as the test plan.
# Spec: Export orders to CSV
Goal: let an account owner export their filtered orders
to CSV to reconcile in a spreadsheet.
Scope:
- in: a button on the orders page that exports the
currently filtered list as CSV
- out: PDF, scheduled exports, emailing the file
Constraints:
- Next.js 15 route handler; stream for >10k rows
- owner-only (403 otherwise); no new dependencies
Acceptance criteria:
1. Given filtered orders, when I export, the CSV has a
header row + one row per order with id, status,
total, createdAt.
2. Given zero orders, I get a header-only CSV.
3. Given a non-owner, I get 403 and no file.
4. Given >10k orders, the response streams (no OOM).
Implement to this spec. Plan first, then build, then
show how each criterion is met.FAQ
When the work is big enough that a single prompt cannot capture it: a multi-file feature, something with real requirements, or anything you will hand to an agent to build mostly on its own. For a one-function change, a spec is overkill; for a feature, it is the difference between the right thing and a plausible guess.
The goal and why it matters, the scope (and explicitly what is out of scope), user-facing behavior, acceptance criteria that make done checkable, constraints (stack, performance, security), and any data shapes or interfaces involved. It is a PRD focused enough for an implementer to execute without guessing.
They turn 'done' into something you and the agent can both check. Written as testable statements, they double as a test plan and let you verify the build objectively rather than arguing about whether it is finished.
Change the spec, then have the agent reconcile the code to it. Keeping the spec as the single source of truth prevents the drift that happens when you patch the code directly and the spec silently goes stale.