Engineering Atlas › Problem Solving & Incidents (AI era)

Spec-Driven Development with Agents

11 min read · last reviewed 2026-10-17

Open in the interactive app: practice, quiz, mock interview →

In one minute

How it works

Why prompts are not enough

A prompt is a conversation; a spec is a contract. Prompts drift, get lost when the session ends, and mix what you want with how you said it. When five agents and three humans touch a feature over a month, the only thing that keeps them consistent is a document that says what the system must do, which everyone, human or agent, reads first. That is why tools such as GitHub's Spec Kit, OpenSpec and AWS Kiro all center on a spec file that lives in the repository next to the code. Spec Kit's phases are specify, plan, tasks, implement (GitHub blog, 2025); Kiro's feature specs produce requirements.md, design.md and tasks.md (Kiro docs).

The tools differ in how long the spec lives. Martin Fowler's comparison names three levels: spec-first (written before the code, then possibly discarded), spec-anchored (kept and evolved with the feature) and spec-as-source (humans edit only the spec). Most tools today are spec-first; spec-as-source showed non-deterministic output between runs, and he warns it could inherit both the rigidity of model-driven development and the randomness of LLMs (Fowler).

The loop

  1. Specify. Write the problem, users, requirements and non-goals. Requirements are numbered and testable.
  2. Plan. Decide the design: components, data model, problem shapes and mechanisms. For high-stakes work this is the whiteboard step.
  3. Tasks. Break the plan into small tasks, each naming the requirement IDs it satisfies and the tests that prove it.
  4. Implement. The agent works task by task, writing tests first where possible.
  5. Verify. Tests run, traceability is checked, a human reviews the diff against the spec.

Writing testable requirements

Vague requirements produce plausible code. "The system should be fast and handle errors well" gives an agent nothing to verify. Two formats help:

Use RFC 2119 words consistently: MUST for hard rules, SHOULD for strong defaults (valid reasons to deviate must be understood and weighed), MAY for options (RFC 2119). Only the capitalised forms carry that meaning (RFC 8174), so tell agents and authors to capitalise on purpose. Write numbers, not adjectives: "p99 under 200 ms at 500 requests per second", not "fast".

Non-goals and invariants

The most useful lines in a spec are often what the system must not do and what must always hold. "Non-goal: multi-currency in v1" stops an eager agent from building it. "Invariant: an account balance never goes negative" becomes a property test that runs on every change. Agents expand scope by default, because adding features looks helpful; non-goals are how you stop that.

Keeping specs alive

A spec written once and never updated becomes misleading, which is worse than no spec. Treat changes like code: propose a spec change, review it, apply it, then change the code. OpenSpec models exactly this cycle: a change folder is proposed, applied, then archived and merged into the live specs/ folder (OpenSpec). The rule for agents is simple: if the code and the spec disagree, stop and ask which one is right.

Down the stack

Layer 1The contract

A spec-driven workflow promises that every merged behaviour traces to a requirement, every requirement has at least one passing test, and a change in behaviour starts as a change in the spec. Reviewers can check it mechanically: a script lists requirements without tests and tests without requirements, and CI fails if either list is non-empty.

Layer 2The mechanism

In practice the spec is Markdown in the repository, for example specs/refunds/spec.md with requirements tagged REQ-1 to REQ-n, plus plan.md and tasks.md. Tests reference IDs in their names or with markers, such as test_req3_repeat_key_returns_original or a pytest marker @pytest.mark.req("REQ-3"). A traceability script greps the spec for requirement IDs and the test suite for references, then reports gaps. Agent instructions in CLAUDE.md or AGENTS.md say: read the spec first, implement one task at a time, write the test named after the requirement before the code, and never edit the spec without asking.

Layer 3The machine

Specs help agents for a concrete reason: an agent's context window is finite and every token competes for attention (Anthropic). A 2,000-token spec with numbered requirements gives the model a dense, stable description of the goal that survives across sessions, while a long chat history is lossy: earlier turns get summarised or dropped as the context fills. Tests then provide the ground truth that text cannot: a test run is a process with an exit code, 0 or not, which the agent's runtime reads directly. The spec narrows what the model generates; the tests check what it generated.

Why it's built this way

  1. Agents generate code quickly but have no stable memory of intent across sessions.
  2. Intent must therefore live in a durable document both humans and agents read.
  3. Documents drift from reality unless each claim is checked.
  4. Tests check claims, but only if each requirement is written precisely enough to test.
  5. So: numbered, testable requirements, linked to tests, enforced in CI.

Diagram

flowchart LR
  S["Spec: REQ-1..n, non-goals, invariants"] --> P["Plan: design and shapes"]
  P --> T["Tasks: each lists REQ ids"]
  T --> I["Agent implements, tests first"]
  I --> V{"Traceability and tests pass?"}
  V -->|no| I
  V -->|yes| R["Human review against spec"]
  R -->|behaviour change| S

Worked example

A team adds refunds to a support agent. The spec has six requirements. REQ-1: a refund MUST NOT exceed the captured amount of the order. REQ-2: refunds over 200 dollars MUST require human approval. REQ-3: repeating an idempotency key with the same parameters MUST return the original result. REQ-4: repeating a key with different parameters MUST be rejected. REQ-5: every refund MUST write an audit record with actor, amount and reason. REQ-6: p99 latency SHOULD be under 2 seconds excluding the payment provider. Non-goals: partial refunds of bundled items; refunds in a different currency.

The agent produces 14 tests and the implementation in about 40 minutes. The traceability script reports REQ-5 has no test: the agent wrote the audit record but never tested it. It also reports a test named test_refund_currency_conversion, which maps to no requirement: the agent started building a non-goal. Both are caught by a 30-line script before a human reads a single line of code. The reviewer then spends their time on the part machines cannot judge: whether 200 dollars is the right approval threshold.

In the wild

Trade-offs

ApproachStrengthsWeaknessesChoose when
Full SDD (spec, plan, tasks)Durable intent, traceable, reviewableProcess overheadFeatures that last, teams of several people or agents
Light spec plus testsQuick, still testableLess design contextSmall features, clear scope
Prompt onlyFastest startDrift, scope creep, no recordThrowaway prototypes
Spec as source, code regeneratedCode stays aligned with intentImmature tooling, nondeterministic outputExperiments, generated adapters

Pitfalls in production

Leadership lens

Check yourself

  1. Why is "the system shall handle errors gracefully" a bad requirement for an agent?

    Show answer

    It is not testable, so the agent cannot verify it and will interpret it however is most convenient; a good requirement names a trigger and an observable response.

  2. What do non-goals add to a spec when an agent implements it?

    Show answer

    They stop scope creep: agents tend to add plausible features, and an explicit non-goal lets both the agent and the traceability check flag work that was not asked for.

  3. A test references no requirement. What could that mean?

    Show answer

    Either a missing requirement that should be added to the spec, or work outside the spec, such as a non-goal the agent built; both need a human decision.

  4. Why should behaviour changes start in the spec rather than the code?

    Show answer

    Otherwise the spec drifts from reality, and the next agent or engineer who reads it builds on false information.

Sources and further study

Primary

Systems docs

Books

Free resources

Open in the interactive app: practice, quiz, mock interview →