Coding agents are good at writing code and bad at guessing what you meant. Give one a two-line prompt for a feature and it will happily fill every gap with its own assumptions: a data model you would not choose, an edge case it decided was out of scope, a library you have never heard of. The code compiles. It is just not the feature you wanted.
Spec-driven development (SDD) is the response that has taken shape over the last few months: write down what you want before the agent writes code, review that, and make the written intent the thing the agent works from. AWS launched Kiro, an IDE built around specs, in preview on July 14, 2025. GitHub open-sourced Spec Kit on September 2, 2025. Thoughtworks' Birgitta Böckeler published a comparison of the tools on martinfowler.com on October 15, 2025.
The idea is old (requirements, design docs, test-first). What is new is that the reader of the spec is now also an agent, which changes what a good spec looks like and how much of the downstream work can be generated from it. This cheatsheet covers the loop, the tools, the templates, and where it goes wrong.
1. Definitions
| Term | Meaning |
|---|---|
| Spec | A structured description of the behavior you want: user stories, acceptance criteria, constraints, non-goals. Says WHAT and WHY, not HOW |
| Plan (design) | The technical approach for this spec: architecture, data model, interfaces, dependencies, risks |
| Tasks | An ordered list of small, reviewable work items derived from the spec and plan, each traceable to requirements |
| Constitution / steering | Project-wide rules that apply to every spec: stack, conventions, testing policy, things that are never allowed |
| Spec-driven development | A workflow where the reviewed spec is the source of truth for the agent's work, and code is checked against it |
| Spec drift | The spec and the code disagree, and nobody notices |
Böckeler's article distinguishes three levels of ambition, which are useful when someone says "we do SDD":
| Level | Definition (Böckeler) | In practice |
|---|---|---|
| Spec-first | "A well thought-out spec is written first, and then used in the AI-assisted development workflow for the task at hand." | The spec drives one change, then is archived or forgotten |
| Spec-anchored | "The spec is kept even after the task is complete, to continue using it for evolution and maintenance of the respective feature." | Specs live in the repo next to the code and are updated with it |
| Spec-as-source | "The spec is the main source file over time, and only the spec is edited by the human, the human never touches the code." | Code is a generated artifact. Few teams are here |
Most teams that try SDD today are doing spec-first. Spec-anchored is where most of the long-term value is, and also where the maintenance cost is.
2. The loop: spec, plan, tasks, implement
| Phase | Human provides | Agent produces | Human checks before moving on |
|---|---|---|---|
| 1. Specify | The goal, users, the problem, what success looks like | A detailed spec: stories, acceptance criteria, edge cases, open questions | Does it capture the intent? Are the non-goals right? Are open questions answered? |
| 2. Plan | Technical direction: stack, constraints, architecture rules | A plan: components, data model, interfaces, research notes | Does it fit the existing system and constraints? Is anything over-engineered? |
| 3. Tasks | (Usually nothing new) | Ordered, small tasks, each linked to requirements, including tests | Is every requirement covered? Is each task small enough to review? |
| 4. Implement | Approval to start, one task or batch at a time | Code and tests for each task | Does it meet the acceptance criteria? Do the tests actually test them? |
Two properties make the loop work: each phase is a checkpoint (catching a wrong assumption in a page of spec costs minutes; catching it in a pull request costs a rewrite), and each artifact narrows the next one (the agent plans from the spec and implements from the plan, not from its own guesses).
When the spec turns out to be wrong during implementation (it will), go back and fix the spec, then regenerate the plan or tasks that depend on it. Patching only the code is how spec drift starts.
3. The tools: Spec Kit and Kiro
GitHub Spec Kit (September 2, 2025)
Spec Kit is an open source toolkit from GitHub, announced by Den Delimarsky on the GitHub blog. It is not an IDE or a model; it is a CLI that sets up templates, scripts and slash commands for the coding agent you already use. The announcement names GitHub Copilot, Claude Code and Gemini CLI.
uvx --from git+https://github.com/github/spec-kit.git specify init my-project
At launch, the workflow maps to agent slash commands:
| Command | Phase |
|---|---|
/specify |
Generate a spec from a high-level description |
/plan |
Generate a technical plan from the spec plus your technical direction |
/tasks |
Break the spec and plan into tasks |
| then implement | The agent works through the tasks |
Böckeler's walkthrough adds the pieces around it: a constitution with "high level principles that are immutable", and a set of generated files per feature such as spec.md, plan.md, research.md, data-model.md and tasks.md. The project moves fast, so check the command names in the version you install.
The repo's spec-driven.md document is worth reading even if you never use the CLI. Two of its rules are good practice anywhere:
- Specs focus on "WHAT users need and WHY" and avoid "HOW to implement (no tech stack, APIs, code structure)".
- When the prompt does not specify something, the agent should mark it with
[NEEDS CLARIFICATION]rather than guess.
Its example constitution also includes a test-first article: no implementation code before unit tests are written, approved by the user, and confirmed to fail.
The GitHub post positions SDD for three situations: greenfield projects, feature work in existing systems, and legacy modernization. Its framing: "We're moving from 'code is the source of truth' to 'intent is the source of truth.'"
AWS Kiro (preview, July 14, 2025)
Kiro is an agentic IDE from AWS, built on Code OSS (the open source base of VS Code), announced in preview by Nikhil Swaminathan and Deepak Singh. Specs are a first-class feature:
| Kiro artifact | Content |
|---|---|
requirements.md |
User stories with acceptance criteria in EARS notation, generated from a prompt such as "Add a review system for products" |
design.md |
Technical design from the requirements and the codebase: data flow, interfaces, schemas, endpoints |
tasks.md |
Sequenced tasks linked to requirements, including tests |
| Steering files | Project memory, by default product.md, structure.md and tech.md |
| Agent hooks | Automations triggered by events such as file saves, for example updating tests when a component changes |
Kiro also supports MCP servers and a regular agentic chat for work that does not need a spec. AWS describes specs that stay synced with the codebase in both directions: code changes can update specs, and spec changes can refresh tasks.
Side by side
| Spec Kit | Kiro | |
|---|---|---|
| Form | CLI plus templates for your existing agent | Full IDE |
| Phases | Constitution, specify, plan, tasks, implement | Requirements, design, tasks |
| Project rules | Constitution | Steering files |
| Agent | Bring your own | Built in |
| Weight (Böckeler) | Heavier: many markdown files per feature | "The simplest (or most lightweight) one of the three I tried" |
Böckeler also looked at Tessl (private beta at the time of her article), the only one of the three aiming at spec-anchored and spec-as-source, with a 1:1 mapping between spec files and code files and generated code marked // GENERATED FROM SPEC - DO NOT EDIT.
You do not need any of these tools. A specs/ folder, three templates and a rule in your agent instructions ("read the spec and plan before writing code; stop and ask about anything marked as needing clarification") get you most of the loop.
4. Writing requirements an agent can check: EARS
EARS (Easy Approach to Requirements Syntax) was developed by Alistair Mavin and colleagues at Rolls-Royce and published at the IEEE Requirements Engineering conference in 2009. Kiro uses it for acceptance criteria, and it works well for agents because every requirement has a trigger and an observable response.
| Pattern | Template | Example |
|---|---|---|
| Ubiquitous | The system shall ... | The system shall store amounts in integer cents |
| Event-driven | When ..., the system shall ... | When a refund is requested within 14 days of purchase, the system shall issue a full refund |
| State-driven | While ..., the system shall ... | While the payment provider is unavailable, the system shall queue refund requests |
| Unwanted behavior | If ..., then the system shall ... | If the provider returns a timeout, then the system shall retry once after 2 seconds |
| Optional feature | Where ..., the system shall ... | Where the customer has a business account, the system shall attach an invoice PDF |
Each line is close to a test name. That is the point.
5. Templates
Keep templates short. The agent can expand them; you have to review them.
spec.md
# Feature: Self-service refunds
ID: 001-refunds | Status: approved | Owner: @alice
## Problem
Support handles ~300 refund tickets/week by hand.
## Users and goals
- Customer: get a refund without contacting support.
## Requirements
- REQ-001 When a customer requests a refund within 14 days, the system shall issue a full refund.
- REQ-002 If the payment provider times out, then the system shall retry once.
- REQ-003 The system shall email a receipt for every refund.
## Non-goals
- Partial refunds. Refunds after 14 days.
## Open questions
- [NEEDS CLARIFICATION] Do gift-card purchases qualify?
plan.md
# Plan: 001-refunds
Spec: specs/001-refunds/spec.md | ADRs: ADR-014 (payment provider client)
## Approach
New RefundService in billing/, uses existing PaymentClient.
## Data model
refunds(id, order_id, amount_cents, status, created_at)
## Interfaces
POST /orders/{id}/refunds -> 201 | 409 (already refunded) | 422 (outside window)
## Risks
Provider idempotency: use order_id as idempotency key.
tasks.md
- [ ] T1 Migration for refunds table (REQ-001)
- [ ] T2 RefundService.request() with 14-day rule + tests (REQ-001)
- [ ] T3 Retry on provider timeout + test with fake provider (REQ-002)
- [ ] T4 Receipt email + test (REQ-003)
- [ ] T5 API endpoint + contract tests (REQ-001, REQ-002)
Small habits that pay off: stable requirement IDs, an explicit non-goals section, open questions that block the plan until answered, and every task citing the requirement it serves.
6. Specs, tests and ADRs: who owns what
A spec does not replace tests or architecture decision records. Each answers a different question:
| Artifact | Answers | Lifetime | Who reads it |
|---|---|---|---|
| Spec | What should the system do, for whom, and why? What is out of scope? | As long as the feature exists (if spec-anchored) | Product, engineers, agents |
| Plan | How will this change be built? | Usually one change; then it is history | Engineers, agents |
| ADR | Why did we choose this architecture over the alternatives? | Permanent; superseded, never edited | Future engineers and agents |
| Tests | Does the code do what the spec says, right now? | As long as the code exists | CI |
How they connect:
- Acceptance criteria become tests. Each requirement ID should appear in at least one test. The spec says what; the test proves it, every run.
- Plans cite ADRs, and decisions found during planning become ADRs. Michael Nygard's 2011 ADR format (title, status, context, decision, consequences) is short enough that an agent can draft one from a plan section for you to edit.
- The constitution or steering files are the summary of your accepted ADRs plus conventions, written as rules the agent must follow.
- The tests are the only artifact that cannot drift silently. If a spec says one thing and a test says another, the test is what runs in CI. Make the link between them checkable.
A minimal traceability check, run in CI:
"""Fail CI when a requirement has no test, or a test cites an unknown requirement."""
import re
import sys
from pathlib import Path
REQ = re.compile(r"\bREQ-\d{3}\b")
def ids(paths: list[Path]) -> dict[str, set[Path]]:
found: dict[str, set[Path]] = {}
for p in paths:
for req_id in REQ.findall(p.read_text(encoding="utf-8")):
found.setdefault(req_id, set()).add(p)
return found
specs = ids(sorted(Path("specs").rglob("spec.md")))
tests = ids(sorted(Path("tests").rglob("test_*.py")))
untested = sorted(set(specs) - set(tests))
unknown = sorted(set(tests) - set(specs))
for req_id in untested:
print(f"untested: {req_id} in {', '.join(map(str, specs[req_id]))}")
for req_id in unknown:
print(f"unknown requirement cited by tests: {req_id}")
sys.exit(1 if untested or unknown else 0)
$ python spec_check.py
untested: REQ-003 in specs/001-refunds/spec.md
It is crude (a requirement ID in a docstring counts as coverage) but it catches the two most common forms of drift: requirements nobody tested, and tests for requirements that were removed or renamed.
7. When to use it, and when not
| Situation | Use SDD? | Why |
|---|---|---|
| New feature touching several components | Yes | The plan step catches integration and data-model mistakes early |
| Greenfield service | Yes | Stops the agent from choosing the stack and architecture for you |
| Legacy modernization | Yes | Capturing current behavior as a spec is half the work anyway |
| Unclear requirements | Yes, especially | The spec phase forces the questions out before code exists |
| One-line bug fix | No | Böckeler: "like using a sledgehammer to crack a nut" |
| Exploratory prototype you will throw away | Usually no | Speed matters more than traceability |
Scale the ceremony to the change. A small change can get a five-line spec with acceptance criteria and no plan. A cross-team feature gets all three files and an ADR.
8. Pitfalls
| Pitfall | Symptom | Fix |
|---|---|---|
| Spec drift | Code was patched during implementation; the spec still describes the original idea | Rule: behavior changes start with a spec change. Run the traceability check in CI. Review spec diffs in the same PR as code |
| Over-specification | The spec dictates class names, libraries and file layout; the agent follows it into a bad design | Keep HOW in the plan, not the spec. Specs state behavior and constraints |
| Review fatigue | Hundreds of lines of generated markdown per feature; reviewers skim and approve | Short templates, strict non-goals, review the spec diff, not the whole file. Böckeler found Spec Kit's generated files "very verbose and tedious to review" |
| False sense of control | Detailed specs, but the agent ignores parts of them anyway | Specs guide; tests verify. Böckeler "frequently saw the agent ultimately not follow all the instructions", and also saw it go overboard following them too eagerly |
| Agent-written spec, unread | The agent writes the spec and the human approves without reading | The human owns the spec. If you did not read it, it is not a spec, it is a longer prompt |
| Stale constitution | Project rules still mention the old framework or test runner | Treat steering and constitution files as code: owned, reviewed, updated with ADRs |
| One workflow for every change | Bug fixes go through four phases | Define two or three sizes of workflow and pick one per change |
| Plans that never die | Old plans and task lists contradict the current code and confuse the agent | Archive or delete plans after merge; keep specs (if spec-anchored) and ADRs |
Böckeler's broader warning is worth keeping in mind: model-driven development promised that specs would generate code, and largely did not deliver. She wonders whether spec-as-source, and even spec-anchoring, "might end up with the downsides of both MDD and LLMs: Inflexibility and non-determinism." Use specs to improve the agent's input and your review, not as a promise that code no longer needs reading.
Why this matters
- Agents fill gaps with guesses. A reviewed spec removes the gaps that matter before code exists.
- Reviewing intent is cheaper than reviewing code. A page of requirements is faster to correct than a large diff.
- Specs, tests and ADRs are complementary. Specs state intent, tests enforce it, ADRs explain the architecture.
- The tooling is new and changing. Spec Kit and Kiro are a few months old; the practices (clear requirements, test-first, decision records) are decades old and will outlast them.
- Drift is the main failure mode. A spec that no longer matches the code is worse than no spec, because agents will trust it.
Final Thoughts
Spec-driven development is not a new methodology so much as an old discipline with a new reader. Writing requirements down, agreeing on them before building, and testing against them was always good engineering. Coding agents make it pay off faster, because the same document that aligns the humans also steers the agent.
Start small: one feature, three short files, requirement IDs in the tests, and a CI check that they match. If that makes the agent's first attempt closer to what you wanted, and reviews shorter, scale it up. If you find yourself reviewing more markdown than code, cut the templates down.
Sources
- AWS, Introducing Kiro (Nikhil Swaminathan, Deepak Singh, July 14, 2025): preview launch, requirements in EARS, design and tasks, hooks, steering, MCP, Code OSS.
- Kiro docs, Specs:
requirements.md,design.md,tasks.md. - SiliconANGLE, AWS launches Kiro, a "spec coding" developer environment integrated with AI agents (July 14, 2025): launch date and coverage.
- Den Delimarsky (GitHub), Spec-driven development with AI: Get started with a new open source toolkit (September 2, 2025): phases, commands,
specify init, supported agents, use cases, "intent is the source of truth". - GitHub, spec-kit repository and spec-driven.md: WHAT and WHY vs HOW,
[NEEDS CLARIFICATION], test-first constitution article. - Birgitta Böckeler, Understanding Spec-Driven-Development: Kiro, spec-kit, and Tessl (martinfowler.com, October 15, 2025): spec-first, spec-anchored, spec-as-source; tool comparison; steering files; review overhead, agents ignoring instructions, sledgehammer quote, MDD warning.
- Easy Approach to Requirements Syntax (overview): developed by Alistair Mavin and colleagues at Rolls-Royce, first published at IEEE RE'09 (2009); the five patterns.
- Michael Nygard, Documenting Architecture Decisions (November 15, 2011): ADR format.