Contents
Spec-Driven Development (SDD) treats the specification as the primary artifact of a change. An AI agent generates a plan, a patch, and checks from a contract the team agreed on before the first line of implementation. That is not a cleverer prompt and not vibe coding: the chat vanishes, the ticket goes stale, and the spec stays in git as the oracle for review.
When agents write faster than a team can agree on what “correct” means, the bottleneck is not the model. It is the missing durable artifact that says what must remain true. This guide covers the cycle spec → plan → agent code → verify against the spec, how SDD relates to TDD and BDD, which 2026 tools make the method visible in a repository, and the failure modes that look like “the model is dumb” while the contract is simply wrong.
Key takeaways
The spec is the source of truth; code is a projection. For decades specifications were scaffolding: useful at the start, discarded once “real work” moved into files. Agents invert the economics. Code is cheap to regenerate. Agreed behavior is expensive. If that behavior lives only in a chat transcript, you cannot verify it, hand it to the next model, or review it without replaying a session that nobody else saw.
SDD is not a better prompt. A prompt is an ignition key. It dies with the session, cannot be reviewed apart from the patch, and cannot run in CI as an oracle. A specification lives in the repository, has history, an owner, and completion criteria. A good prompt starts work. A good spec defines when work is finished.
Vibe coding and SDD share an agent and disagree on the judge. In vibe coding the judge is the author’s eye: “looks like it works.” In SDD the judge is a contract: scenarios, invariants, non-goals, and verification commands. A short take on the new SDLC draws the same cultural line. This article is about the artifact that makes the line enforceable.
Make the spec executable where failure is expensive. Prose is fine for motivation and product boundaries. An OpenAPI contract, an order state machine, an authorization matrix, a migration rule — those are not “docs.” They are oracles an agent and a pipeline can fail against. Testing economics gives the proportion: the higher the cost of a miss, the less you may leave truth in a paragraph titled “intent.”
Drift beats “weak models” as the usual outage. An agent will happily write tests that encode the patch it just produced and hand you a green pipeline with the wrong behavior. An oversized spec (“improve checkout”) licenses architectural wandering. A narrow, stale spec forces the next agent to “fix” a correct patch back to last month’s contract. SDD holds only while spec and code land in the same change.
What Spec-Driven Development is — and why it is not another README
Spec-Driven Development is a way to run a change so that intent is written down in a form that can be checked, and only then handed to an agent for implementation. The spec is not a courtesy document and not an onboarding wiki page. It is the primary artifact of the change: humans and models read it, plans are derived from it, and “done” is judged against it.
Code used to be king for a practical reason. Specs lived in documents that drifted from the release in two weeks. Teams learned not to trust the text and to “look at the repo.” That was rational while writing code was expensive and rewriting a cheap paragraph was cheaper. In 2026 generation is cheap and wrong intent is expensive: an agent will multiply a mistake across ten files in an hour, in a confident tone, with green tests.
Roles flip. The spec states what and why, including an explicit “what we will not do.” The plan states how inside the project constitution: stack, module boundaries, migrations. Code is one way to satisfy the contract. If the contract changes, you regenerate or edit the code. If only the code changes and the contract is silent, the team no longer has a source of truth.
A README answers a different question: how to run the project, where a newcomer should look, which commands exist. It may link to specs; it does not define feature behavior. A wiki page often describes the system as of last quarter. A ticket comment lives in another system and falls out of git. An SDD spec sits next to the code, goes through review, and shares the branch with the patch.
Machine-readability is a spectrum, not a checkbox. At one end: numbered prose scenarios that a model understands and a pipeline does not. At the other: a schema, an API contract, a transition table, input–output examples that can be checked without the author in the room. Practical SDD mixes both. Prose carries meaning. Executable fragments close the boundaries where agents invent convenient lies. Prose alone invites the model to fill gaps. Schema alone, with no “why,” invites local optimization that wrecks the product.
Another difference from “just write requirements”: a specification narrows the solution space. A good spec names invariants (“a retried payment must not create a second charge”), non-goals (“do not touch the fiscal module”), acceptance criteria, and how those criteria will be checked. A bad spec restates a stakeholder wish and asks the model to “make it good.” That is the difference between a task for an engineer and a hallway conversation — except the hallway now scales to the whole repository.
Spec vs prompt vs test vs ticket
Confusion starts when a team calls “the spec” any text the model happened to see. Four artifacts answer four questions and live on four clocks. Mixing them in one chat is convenient. Mixing them in a production loop is how SDD becomes a slogan.
A prompt is ignition. It tells the agent where to start, which files to open, what answer shape you want. Its strength is speed: you can refine it in thirty seconds. Its weakness is that it is not a contract. A teammate does not review your session. The next model will not see yesterday’s thread. CI will not execute the prompt as an oracle. Prompt craft is useful. It does not replace a spec any more than a standup opener replaces acceptance criteria.
A ticket is a pointer. It exists for queue, priority, release mapping, and accounting. It usually has a title, a sketch, and a link. If the ticket is the only statement of behavior, that statement sits outside git, outside code review, and outside the context of an agent that reads the repository. The healthy pattern: the ticket points at a spec file on the branch; disputes about behavior happen in the file, not in tracker comments.
A test is a check of a chosen slice. It is indispensable and insufficient. Indispensable because it is an executable signal. Insufficient because it covers what the test author chose to cover. An agent told “write tests” will, more often than teams admit, encode the patch’s actual behavior rather than the intent. A green suite then confirms that the code agrees with itself. That is a mirror, not a source of truth.
A specification is the contract. It names observable behavior, constraints, non-goals, and, where needed, executable fragments. Tests are derived from it or traced back to it. The prompt points at it. The ticket points at it. When those links break, the team is vibe coding again — only with a more expensive autocomplete.
| Artifact | Question it answers | Lifetime | Who reviews it | Runnable in CI |
|---|---|---|---|---|
| Prompt | How do we start the agent now | One session | Usually nobody | No |
| Ticket | Why is this in the queue | While open | Product / lead | No |
| Test | Does this slice hold | Until deleted | Patch reviewer | Yes |
| Spec | What must remain true | While the feature lives | The change’s owners | Partially or yes |
The link to neighboring practices is direct. Agentic engineering is the harness around the agent: context, permissions, orchestration, independent verification. The spec is what the harness is for. Without a contract the harness loops on “make it better.” Without a harness the contract is a pretty file nobody injected into the agent.
The cycle: spec → plan → agent code → verify against the spec
On a slide the SDD loop looks linear. In a repository it is iterative. Linearity exists so you do not start with code. Iteration exists because sharpening intent is engineering, not a failure of the method.
Step one is a behavior spec. A human (sometimes with an agent as a drafting assistant, with sign-off remaining human) records the goal in user or system terms, success and failure scenarios, non-goals, data, invariants, and acceptance criteria. Stack choice is deliberately secondary here: otherwise the team argues about a framework before agreeing what the system must do. In toolkits such as Spec Kit this is close to /speckit.specify: what and why, not which library.
Step two is an implementation plan. Module boundaries, service contracts, migrations, risks, and verification commands appear here. The plan must fit the project constitution: forbidden dependencies, security rules, test expectations. If the plan contradicts the spec, you fix the plan — you do not massage the behavior statement to match a convenient patch. /speckit.plan in this logic is a blueprint, not a replacement for the contract.
Step three is decomposition. A large spec dumped on an agent whole produces a wide patch and an unreviewable diff. Tasks are cut so each has an observable done-condition and a limited file contour. That is the same rule as in agentic engineering: one autonomous unit, one verifiable increment.
Step four is agent code. The model reads the spec, the plan, and repository rules, edits files, and runs environment checks. How AI IDEs work with code explains why the result depends on indexing, context assembly, and tools — not only on “how smart the model is.” SDD does not repeal that machinery. It specifies which document must enter context before the agent starts guessing.
Step five is verification against the spec, not only against tests. Tests can be false-green. A reviewer can read a tidy diff and miss a violated non-goal (“do not change the public contract”). Spec verification means: each acceptance criterion is either evidenced by a command or explicitly marked unchecked. Commands such as /speckit.analyze look for gaps among spec.md, plan.md, and tasks.md: a task with no requirement, a requirement with no task, a plan that contradicts the contract.
Step six, which teams skip, is convergence. After the patch, code and spec must describe the same system again. If the agent discovers that a requirement cannot be met without moving a boundary, you update the spec first, then the code. Otherwise tomorrow’s model will read the stale contract and “repair” a correct patch.
On the diagram this is spec → plan → code → verify. In practice verification often returns you to the spec: an edge case, a new non-goal, a tighter invariant. That is still SDD. Abandoning SDD is the second attempt that starts with “just fix it, you can see the repo.”
Tools in 2026: Spec Kit / OpenSpec, AGENTS.md, Cursor rules, OpenAPI contracts
Tools are not the method. In 2026 the method finally has an obvious shape in the repository. Distinguishing process scaffolding, standing agent rules, and executable contracts matters. Teams often dump all three into one “for AI” folder and recreate a longer prompt.
Spec Kit (github/spec-kit) is an open toolkit for spec-driven work across many agents: Copilot, Claude, Gemini, and a long integration list. The core sequence is project constitution, feature spec, plan, tasks, implementation, consistency analysis. The constitution (often constitution.md) holds inviolable rules: architectural bans, verification requirements, security bounds. Feature specs live separately and describe a concrete change. That fits greenfield work and teams that need a shared ritual of “do not start with code.” The failure mode is believing templates produce quality: an empty spec.md with headings and no invariants will be filled with platitudes.
OpenSpec sits closer to brownfield. The idea is delta specs: describe the change relative to current behavior instead of rewriting “the whole system as it should be” before the first patch. For a five-year-old service that is more honest. A full constitution and a complete requirements catalog from scratch are expensive and often unread. A delta in the pull request reviews as part of the change: here is what was, here is what will be, here are the tasks. The opposite risk is a pile of deltas never merged into a current snapshot — archaeology again.
AGENTS.md is standing rules, not a feature spec. Stack, test commands, forbidden actions, response format, a pointer that “feature specs live here.” That is harness material, covered in depth in agentic engineering. If you pour the next feature’s behavior into AGENTS.md, the file bloats, the context window fills, and reviewers stop reading the rules. Standing file: what is true for every change. Feature spec: what is true for this change.
Cursor project rules (.cursor/rules, skills, user instructions) solve the same problem on the IDE side. Their job is to point the agent at the spec and the constitution, not to restate the spec in another dialect. Duplication creates a third source of truth; the model will pick the most convenient paragraph. A useful rule: “before patching, read the spec file on the branch; do not invent acceptance criteria; if a criterion is missing, stop.” Indexing and agent modes are in the IDE mechanics piece; SDD adds which file must be in the input.
OpenAPI contracts (and kin: JSON Schema, Protobuf, GraphQL SDL) are the clearest executable spec for service boundaries. Teams already needed them for clients, mocks, and compatibility checks. Agents raise the stakes. A model given only the sentence “add a discount field” will invent type, nullability, and error behavior. A model given a contract and a ban on breaking existing operations is constrained by the schema. The contract does not replace product scenarios. It closes the layer where agents fail most often: boundaries, error statuses, idempotency.
The Model Context Protocol strengthens the loop if tools fetch contracts and specs on demand instead of dumping the repository into the window. The production MCP guide is about giving agents sources without shadow integrations. In SDD terms a good tool returns a fragment of OpenAPI or a spec file, not “the entire wiki.”
| Layer | Example | What to expect | What not to expect |
|---|---|---|---|
SDD process |
Spec Kit, OpenSpec |
Ritual, templates, gap analysis | Architecture by itself |
| Standing rules | AGENTS.md, Cursor rules |
How the agent works in this repo | This feature’s behavior |
| Executable contract | OpenAPI, DB schema, state machine |
Machine-checked boundaries | Product motivation and non-goals |
| Environment checks | tests, linter, typechecker | Signal after the patch | Intent that never entered the spec |
SDD vs TDD vs BDD: when the spec should be executable
TDD, BDD, and SDD fight over a single question: which artifact is the primary contract. Teams that “already write tests” often conclude they do not need SDD. Teams that “already write specs” sometimes ship no executable criterion at all. Both edges break against an agent.
In TDD the contract is a unit-level test written before the code. That is strong for an algorithm, a pure function, a reducer, a pricing rule. With an agent, TDD supplies a concrete oracle: while the test is red, the work is not done. The weakness is scale. A test does not explain why the module exists, which non-goals apply, which public contract must not break. An agent optimizing a local red test will happily violate a neighboring invariant. TDD remains an excellent fragment of an executable spec, not a substitute for one.
In BDD the contract is examples in scenario language: given / when / then. That ties product language to checks. The weakness is completeness. A scenario set rarely covers an authorization matrix, API compatibility, or load. Agents love to add three extra scenarios “just in case” that freeze an accidental UI detail. BDD is valuable as a visible slice of user-facing behavior; as the only source of truth it is narrow.
SDD puts an intent document above both, from which BDD scenarios, TDD tests, and interface contracts are derived. That does not retire the red–green loop. It admits that an agent needs a contract wider than one assertion. The spec says: here is the payment invariant, here is the non-goal “do not touch the fiscal contour,” here is the command that proves idempotency. Tests are how you ask the system about that invariant.
When the spec must be executable:
- Boundaries between systems: APIs, events, message schemas. Prose here is an invitation to version drift.
- Money, limits, idempotency, redelivery. The cost of a miss is in failure economics.
- Authorization: roles, resources, a ban on widening access “because it is easier to test.”
- States: order, payment, support ticket. A transition table can be checked; a paragraph “as usual” cannot.
- Data migrations: what happens to old rows, what is irreversible.
When the spec may stay prose (numbered criteria, no schema):
- motivation and market context;
- experiment bounds (“5% of traffic”);
- qualitative UX constraints that a human still accepts by eye;
- explicit non-goals that are hard to test and easy to violate with a wide patch.
Executability is not a coverage fetish. Make executable the layer where an agent would otherwise invent a convenient lie. Leave prose where a lie cannot be computed automatically — and then human review is a required gate, not “one more glance at the diff.”
Where it breaks: spec drift, false-green tests, overly broad specs
The method fails in predictable ways. Three outages show up more often than “the model is not smart enough.”
Spec drift. The code changed and the spec did not — or the reverse. After three agent pull requests the file still says discount is computed on the server while the logic has moved to the client “to be faster.” The next agent reads the contract and reverts a correct decision as a bug. The fix is one rule: spec and code in the same change when behavior changes; a spec-only review when intent changes before implementation. If the spec is absent from the diff, a reviewer may assume behavior did not change — and be wrong.
False-green tests. The agent is told “add coverage” after it has already written the code. It encodes fact, not intent. Worse: it weakens assertions so the pipeline passes. Green then means the test agrees with the patch, not with the contract. Hence: acceptance criteria exist before code; tests trace to spec items; a reviewer may ask “which contract clause does this test check.” No answer means decoration. What a human still has to see after an agent patch is in code review in the AI era.
Overly broad specs. “Improve checkout,” “clean up authorization,” “make it like a modern SaaS.” For a human that is a conversation topic. For an agent it is a license to rewrite a module. A broad spec yields a broad patch, a broad review, and architectural drift nobody chose. The fix: one spec, one behavior change; non-goals as a list; limits on directories and public interfaces. If you cannot list non-goals, the spec is not ready, even if the text is long.
Secondary failures sit nearby. The spec as a novel: twenty pages without invariants. The model loses priorities; humans do not review. Four screens and a transition table beat a chapter of product vision. Dual sources of truth: wiki, README, and spec.md disagree; the agent picks the convenient one. Rotten constitution: rules nobody enforces, so the model learns to ignore them. Reviewing the wrong artifact: comments on formatting while the acceptance criterion is wrong. The line between generation and engineering is the same as in where code generation ends: a pretty patch is not an accepted decision.
A quiet failure: a spec drafted by an agent with no human signature. A model draft of the contract is useful. A source of truth nobody read is vibe coding with an extra file. Sign-off on intent stays with the person who pays for the incident.
Practice for a team and for a solo developer with an agent
A team and a solo developer run the same method with different coordination cost. The mistake is copying a corporate Spec Kit ritual onto an evening side project — or running a production service from chat with no file in git.
For a team, first agree which file is the contract for a change. Keep the constitution short: stack, bans, verification commands, the rule “no spec, no agent patch on behavior.” Definition of Ready includes: goal and non-goals, scenarios, a link to an executable contract if a boundary moves, commands the agent will use as proof. The pull request shows the spec above the code diff: reviewers accept or reject intent before they read implementation. That cuts verification debt, because arguing about “why” across a thousand lines is too late.
Name the roles. Product does not have to write OpenAPI, but does have to confirm scenarios and non-goals. A lead engineer confirms invariants and module boundaries. The pull request author owns convergence of spec and code. The agent is not the author of the contract, even if it drafted it. Multi-agent orchestration only helps if planner and implementer share one signed file, not two paraphrases of a ticket. Otherwise you have three opinions about a blurry sentence — already covered in agentic engineering.
For solo work the ritual is shorter, not zero. Before the agent: twenty minutes on a file — goal, three scenarios, two non-goals, a verification command. The file lives on the branch. After the patch: walk the criteria and mark what you did not check. A personal AGENTS.md can be half a screen if it contains “do not invent acceptance; read the spec.” That already separates vibe coding from SDD. When the feature meets users, a solo developer pays the same failure cost as a team — just alone.
A tool-agnostic minimum:
- One source of truth per change — a file in git, not a chat.
- Non-goals are written down. If there are none, the spec is too broad.
- At least some criteria are executable if money, access, APIs, or states move.
- Tests point at contract clauses or reproduce them literally.
- Behavior and contract merge together.
- A human signs intent. The agent signs the patch only as implementer.
Spec Kit templates and OpenSpec deltas help you not forget sections. They do not help if the sections are filler. An empty invariants table is more honest than a paragraph that says the system “should be reliable.”
FAQ
Do we need SDD if we already write tests?
Yes, if tests are not the full contract for the change. Tests check a chosen slice and are easy to fit to already generated code. A specification states intent, non-goals, and boundaries that tests should follow. Keep pure TDD where the unit of behavior is small and the oracle is obvious. Add SDD when an agent touches several layers and public contracts.
How is this different from “just prompt better”?
A prompt lives in a session and starts work. A specification lives in git and defines done. A better prompt is not reviewed by a colleague, is not versioned with the feature, and is not an oracle a month later when the model has changed. If truth disappears when the chat closes, that is not SDD.
Is this vibe coding under a new name?
No. Vibe coding judges the result with the author’s eyes. SDD judges it with a contract you can show another person and, in part, a pipeline. The same Cursor agent runs in both modes; the oracle changes. The cultural split is sketched in the new SDLC note; this piece is the spec artifact those cultures do or do not keep.
Where do we start in a brownfield repo with no docs?
With a delta on one change, not with an encyclopedia of the system. Describe current observed behavior in a narrow contour and the desired behavior. Keep the constitution to a page: how to run checks, what the agent must not do. A full “how it should be in general” catalog in a legacy service almost never pays for itself before the first delta.
Must we adopt Spec Kit or OpenSpec?
No. You must have a contract in git and a loop that verifies against it. Spec Kit gives a shared ritual and commands across agents. OpenSpec is convenient when deltas matter. If the team already keeps spec.md in the pull request, a constitution, and gap analysis, the tool brand is secondary. A tool without discipline becomes a folder of templates.
Who writes the spec — product or engineering?
Intent and non-goals are confirmed by whoever owns the product of the change. Invariants, boundaries, and executable contracts are confirmed by engineering. An agent may draft. Sign-off on the contract is not delegated to the model: the cost of failure stays human. In practice an engineer often writes the file after a conversation, and product accepts the scenarios.
When should we skip a spec?
When the cost of failure is negligible and the artifact will be thrown away tonight: a UI sketch, a one-off script, a private experiment. Even then a short “what counts as success” list saves iterations. For code users or a neighboring service will see, skipping the spec is a conscious choice of vibe coding.
How do we know the spec is too broad?
If the text implies more than one behavior change, more than one public contract, or “clean this up” with no non-goals. Practical test: a reviewer can accept or reject the contract in ten minutes. If not, split it. A broad spec almost always yields a broad patch and an unreadable review.
The agent added tests and everything is green. Now what?
Treat green as insufficient evidence. Trace each new test to a contract clause. If there is no clause, either add it to the spec (if the behavior is desired) or delete the test and revert the code. A false-green suite is more dangerous than a red one: it fakes readiness and slips past the human review gate.
Does the spec replace architecture and ADRs?
No. An ADR records a choice and its motives (“why Postgres, not a queue”). A feature spec records the behavior of a change. A project constitution records inviolable constraints. Three horizons. Dumping a ten-year decision into the spec.md of a button is how you lose both architecture and acceptance.
Further reading
The spec holds truth for a change. Adjacent pieces cover the harness, the IDE, and verification:
- Agentic engineering in 2026 — context, permissions, orchestration, and verification debt around the agent, not the feature contract.
- How Cursor and other IDEs work with code — index, context assembly, agent modes: how a spec reaches the model.
- Where code generation ends and engineering begins — why a patch without accepted intent is not yet a product.
- Code review in the AI era — what a human must still check when an agent writes the diff.
- The economics of the cost of failure — which parts of the spec to make executable, given the price of a miss.
- MCP in production 2026 — how to give agents tools onto contracts and specs without shadow access.
- The new SDLC: vibe coding and agentic engineering — a short cultural take on the same fork.
Conclusion
Spec-Driven Development answers a 2026 shortage: agents generate changes faster than teams can agree on what counts as correct. You cannot keep the source of truth in a chat, a ticket, and a false-green test suite at once. You keep it in a contract that lives in git, is reviewed before the patch, and, where failure is expensive, is checked by a machine.
SDD does not retire tests, does not replace architecture, and does not make Spec Kit a mandatory brand. It forbids starting with code while behavior is still in dispute, and it forbids calling the work done until the contract is confirmed. The agent harness, IDE mechanics, and human review remain necessary — they orbit the spec, not the mood of the last session.
In Lab terms the specification is the stable unit: split it into “intent in chat” and “files on a branch” and the meaning is gone. While the unit holds, the agent speeds assembly. Once it splits, you are left with fast generation and no engineering.

