← Knowledge

Spec-Driven Development for AI Coding Agents

A technical lesson on using typed specifications as an agent control plane for preserving intent, governing delegated work, and verifying effects when generated code is cheap.

Spec-driven development for AI coding agents is a software-development method in which durable specifications, constraints, and verification evidence guide delegated implementation. It treats generated code as a replaceable artifact and preserves product intent in documents and tests that can be inspected across agent sessions.

The method addresses a bottleneck created by fast code generation. When implementation becomes cheap, teams can produce plausible patches faster than they can establish whether those patches preserve intended behavior. The scarce work moves from typing code to defining the desired state, grounding the work in the actual repository, mapping claims to evidence, and recording what happened.

At its strongest, the method does more than prepare better tasks. A typed specification corpus can become an agent control plane: it defines the product's ontology, assigns authority, routes work, gates effects, and records the evidence that allows a change to become canonical. Human judgment remains responsible for unresolved design and taste rather than being reduced to line-by-line approval.

This lesson begins with a practical baseline:

specification surface + repository grounding + verification map + execution receipts = delegable software work

It then develops the stronger control-plane form, in which those layers become operationally binding. The model is a synthesis of emerging research and production practice. Its direction is useful, but several supporting studies are recent preprints or self-reported production accounts rather than settled evidence.

Definition and scope

A useful specification is an operational state object rather than a wish list. It records:

  • what exists now;
  • what should change;
  • what must not change;
  • which files, interfaces, and user workflows are in scope;
  • which non-goals prevent scope expansion;
  • which constraints are hard invariants;
  • which tests, evaluations, or observations would demonstrate success.

This is related to test-driven development, but it covers a larger surface. Test-driven development places executable expectations before implementation. Spec-driven development keeps enough of the product model explicit that work can be delegated, resumed, reviewed, and corrected across multiple agent contexts.

The important distinction is between a prompt and an artifact. A prompt is an instruction delivered during one interaction. A specification is durable state that later agents and reviewers can inspect.

Four layers

Specification surface

The specification surface is the set of documents that define what a system claims to support. Depending on the project, it can include product intent, workflows, constraints, non-goals, invariants, interfaces, acceptance criteria, risks, and decision records.

GitHub Spec Kit separates these concerns into a constitution, specification, implementation plan, task list, and convergence pass. The exact file structure is less important than the separation of responsibilities:

  • the constitution records standing constraints;
  • the specification records desired behavior;
  • the plan records implementation strategy;
  • tasks record executable decomposition;
  • implementation changes code;
  • convergence repairs disagreement among those artifacts.

OpenSpec: current truth and proposed deltas

OpenSpec is a concrete, brownfield-first implementation of this separation. It keeps the system's agreed current behavior under openspec/specs/, organized by domain, while each proposed modification receives a self-contained folder under openspec/changes/.

A change can contain four related artifacts:

  • proposal.md records intent and scope;
  • delta specs record requirements being added, modified, or removed;
  • design.md records technical decisions;
  • tasks.md records the implementation checklist.

When the change is archived, its deltas merge into the current specs and the complete change folder moves into an archive. The repository therefore retains both the current behavioral contract and the history of how that contract changed.

OpenSpec's important move is temporal: current truth and proposed change are different objects. A reviewer can inspect the requirement delta before reading the implementation, and multiple changes can remain separate until each is ready to alter the shared specification. Its artifact dependency graph is configurable and deliberately fluid; dependencies describe which artifacts can be produced from existing context rather than imposing an irreversible waterfall.

This pattern strengthens the specification surface, but it does not supply the other three layers by itself. OpenSpec can validate artifact structure and exposes an optional verification command, but Git-backed Markdown alone does not establish that repository assumptions are current, select the right regression evidence, or prove that an external effect occurred. Repository grounding, verification maps, and execution receipts remain separate obligations.

The specification needs enough precision to constrain work without freezing every implementation detail. A cathedral of Markdown is still a cathedral, even when the clergy are agents.

Repository grounding

A specification must refer to the repository that actually exists. Before planning, an agent should inspect current files, interfaces, dependencies, tests, documentation, and recent changes. After each major phase, it should validate that its proposed paths and assumptions remain true.

This prevents context blindness: the tendency of an agent to invent nearby-looking APIs, file paths, or architectural patterns when it has not inspected the relevant source. “Remember to check the repository” is weak procedural advice. A read-only discovery phase followed by explicit file and interface checks is auditable evidence.

Verification map

A verification map connects each intended behavior or protected invariant to evidence. The map can include:

  • unit and integration tests;
  • type and lint checks;
  • API contract tests;
  • browser or interface smoke tests;
  • evaluations;
  • migration dry-runs;
  • runtime logs and traces;
  • manual acceptance criteria when no automated test is suitable.

Tests are therefore evidence of intent, not a complete substitute for intent. A supplied test can specify an interface, edge case, or expected output while leaving product-level constraints unstated.

The distinction between fail-to-pass and pass-to-pass tests is particularly useful. Fail-to-pass tests show that the reported defect was repaired. Pass-to-pass tests protect neighboring behavior that worked before the patch. A fix that passes its new test while breaking unrelated behavior is still a regression, merely one with excellent paperwork.

Execution receipts

Long-running agent work needs receipts that connect the specification to the resulting artifact. A completion receipt should identify:

  • the specification version used;
  • the tasks attempted;
  • the files changed;
  • the acceptance criteria addressed;
  • the checks that ran, failed, or were skipped;
  • assumptions that changed during implementation;
  • unresolved follow-up work.

Receipts make incomplete or interrupted work resumable. They also reveal drift: if implementation forced a design change, the specification should change with it rather than leaving the next agent to begin from a false description of the system.

Specifications as an agent control plane

The four layers make software work delegable. A stronger implementation makes them binding. In this model, the specification corpus is a control plane: the part of the system that determines which descriptions are authoritative, who may act, which work is eligible, and what evidence permits a result to alter canonical state.

An agent working under this model is not merely following a better prompt. It is acting within an explicit jurisdiction.

Typed product ontology

A folder full of prose does not become a control plane merely because agents read it. The corpus needs typed roles and single ownership for each kind of truth.

One practical division is:

  • laws state product-wide promises and invariants;
  • specifications define the exact behavior and completion criteria for one system;
  • knowledge pages describe present implementation reality;
  • logs and decision records preserve historical evidence without silently becoming current authority;
  • generated indexes project status and dependencies without becoming a second place to edit them.

This division is visible in the public Misaligned design corpus. Its spec status board is generated from owning specification pages rather than maintained as a competing checklist. Status, stage, dependencies, acceptance criteria, and protected design references are part of the product model, not administrative decoration.

Typing matters because apparently contradictory documents may have different authority. A log can accurately describe an old decision while a later specification supersedes it. A roadmap can point at ready work without owning the behavior that work must produce. An implementation note can describe what exists without granting permission to change what the product promises.

The corpus therefore represents more than requirements. It is a product ontology: a durable account of what kinds of things exist, which relationships are valid, which stages are currently admissible, and where each decision belongs.

Authority, dispatch, and parallel work

Autonomous agents need jurisdiction more than supervision. A useful control plane makes several boundaries explicit:

  • the owning law or specification for a behavior;
  • the human or agent role allowed to amend it;
  • the work item's current stage, status, and dependencies;
  • the likely code and document surfaces it may touch;
  • the checks and observations required before completion;
  • the conditions that require a design decision rather than local invention.

The Misaligned roadmap demonstrates this distinction. It is a generated dispatch board, not a second specification. It points agents toward bounded work orders, identifies dependency and conflict classes, and leaves binding behavior in the owning spec.

That structure supports high autonomy inside hard invariants. Agents can choose implementation details, investigate the repository, repair defects, and reconcile evidence without waiting for approval at every step. They do not get to invent a new product ontology because it makes a local patch easier. When the corpus cannot decide a real design question, the agent should return that question to the design authority rather than smuggling an answer into code.

Parallelism also becomes a scheduling problem rather than a motivational slogan. Work claims, isolated worktrees, likely edit surfaces, and one bounded item per agent make overlap visible. The point is not to eliminate every merge conflict. It is to keep concurrent agents from unknowingly exercising authority over the same state.

Effect gating, not checklist completion

A specification becomes operationally meaningful when it can make a change fail.

For a behavior-changing patch, that can mean requiring the owning law or specification to change in the same commit, checking that acceptance criteria and status remain structurally valid, and rejecting source changes that have no corresponding design authority. A test suite may be green while the patch is still unauthorized because it implements a behavior the governing corpus does not permit.

The public Misaligned workflow applies this principle through corpus gates, proportional implementation checks, task worktrees, generated-index validation, and landing checks. The exact scripts are project-specific. The general contract is not:

the agent says it followed the spec.

It is:

the system can identify the governing spec version, the authorized change, the evidence produced, and the exact effect that became canonical.

Completion should therefore include reconciliation against current state, not only success inside the agent's original branch or context. A run that began from an obsolete specification or repository version may still contain useful work, but it cannot prove current conformance without refresh or rebase. A clean worktree is not a landed change; a passing local process is not a remote receipt; a deployment declaration is not observed runtime behavior.

Repository corpus and runtime state

Git-backed Markdown is one implementation of this architecture, not its definition. A more general control plane can store the same model as versioned runtime state:

  • canonical documents and immutable document versions;
  • owners, roles, and amendment authority;
  • subscriptions and document selectors;
  • semantic change events;
  • bounded work items and claims;
  • context manifests recording the versions a run actually saw;
  • run status, reports, and effect receipts;
  • staleness and conflict state when the world changes underneath active work.

In that form, the filesystem is an authoring and transport adapter rather than necessarily the canonical database. Different agent systems may receive the same governed state through prompt packets, generated files, application programming interfaces, or task-boundary manifests. The core contract owns context identity and freshness; adapters own how each heterogeneous agent consumes it.

This distinction matters for long-running work. Shared documents create awareness, but awareness alone does not prevent conflicting effects. A run should declare the document and repository versions it started from. The control plane can then reject a stale write, require a refresh, or preserve the result as evidence without treating it as current implementation.

Human design authority and the taste boundary

Formalization has a boundary. A specification can establish that a behavior conforms to stated rules. It cannot by itself prove that the resulting product is coherent, playable, legible, beautiful, or worth using.

Those are separate evidence surfaces:

  1. Corpus conformance: the laws, specifications, status, stage, and dependencies agree.
  2. Implementation evidence: tests, types, contracts, and migrations support the required behavior.
  3. Observed product behavior: the relevant runtime or interface was actually exercised.
  4. Product judgment: the result has the intended feel, clarity, and integrity in the hand.

Collapsing these into one completion label creates false confidence. Documentation can be complete while implementation is absent. Tests can pass while the interface is incomprehensible. A feature can work while the larger product becomes uglier or less coherent.

The human role is therefore not to bless every generated line. It is to define the product ontology and hard invariants, adjudicate genuine design questions, and judge the experiential result where formal proof ends. Agents should carry broad implementation authority inside that boundary and produce evidence precise enough that human attention is reserved for the decisions only a product owner can make.

This keeps spec-driven development from collapsing into either micromanagement or paperwork. Agents gain autonomy because authority, evidence, and completion are explicit. Humans retain authorship of the product rather than becoming a merge queue.

Evidence from coding-agent research

The empirical literature is young and uneven, but several results support the general direction.

The test-driven code-generation study found that providing public tests improved model performance over problem statements alone on function-level benchmarks, and that remediation loops produced further gains. Private evaluation tests still mattered because passing only the supplied tests can reward overfitting.

SWE-bench moved coding-agent evaluation from isolated functions to repository-level issue resolution. Its fail-to-pass tests made real bug repair measurable. Later work has emphasized that issue-specific success does not establish the absence of collateral damage, which is why regression-oriented pass-to-pass checks remain important.

The TDAD preprint reports that verbose instructions to “do test-driven development” were less useful than supplying a test-impact map tied to the changed files. In its reported experiments, graph-grounded test context reduced regressions substantially. The sample and model sizes limit generalization, but the mechanism is plausible: exact context is more useful than procedural scolding.

Bun's Rust rewrite

Bun's July 2026 account of rewriting Bun in Rust is a production case study in process control around large-scale agentic implementation. Bun reported a rewrite from roughly 535,000 lines of Zig over eleven days, with thousands of commits and dozens of concurrent agents.

The relevant details are the control surfaces around the generation:

  • PORTING.md and LIFETIMES.tsv recorded durable migration intent;
  • the first pass was deliberately mechanical rather than an opportunistic redesign;
  • implementer and adversarial reviewer agents operated in separate contexts;
  • compiler errors, linker errors, stack traces, and failing tests became explicit work queues;
  • workflows were revised when agents used destructive Git commands or stubbed code merely to make compilation pass;
  • resource isolation eventually required operating-system controls rather than polite prompts;
  • the merge required green cross-platform continuous integration without deleting or skipping tests.

The result is better understood as agent-workflow governance than as raw model capability. Generation supplied volume. Specifications, role separation, execution feedback, tests, and resource controls made the volume reviewable.

Application to persistent agent runtimes

In a persistent runtime such as Letta Code, spec-driven development can be implemented as a compact loop:

  1. Spec intake: record intent, constraints, non-goals, acceptance criteria, and ownership.
  2. Grounding: inspect the real repository, interfaces, tests, documentation, and recent history.
  3. Task compilation: convert the spec into bounded tasks with expected files and checks.
  4. Implementation: change code within the task boundary.
  5. Impact analysis: map changed files and interfaces to tests and evaluations at risk.
  6. Proof run: execute the required checks and capture their results.
  7. Receipt: report the spec version, changes, evidence, failures, skips, and follow-up.
  8. Convergence: update the specification when implementation reveals that an assumption was wrong.

The review target then changes. Reviewers inspect the relationship among intent, invariants, and evidence before treating line-by-line code reading as the only trustworthy validation mechanism.

Failure modes

Paperwork without force

A specification without acceptance criteria, ownership, verification, or update discipline does not constrain implementation. It records aspiration after the fact.

Premature precision

An over-specified document can freeze the wrong abstraction. Good specifications distinguish hard invariants from provisional implementation choices.

Implementer-authored proof

When one agent writes both the implementation and its only tests, the tests can reproduce the same misunderstanding as the code. Independent review, external checks, and protected regression suites reduce this correlated failure.

Stale specification drift

When code changes and the specification does not, future work starts from an inaccurate state model. Updating the spec is part of completion, not a later documentation chore.

Bottleneck preservation

If every generated change still requires the same maintainer to manually bless every line, a new document layer has not changed the review architecture. The purpose is to move human judgment toward product intent, invariants, and proof coverage.

Green gate as product verdict

Automated checks can establish specified properties without establishing that the product is good. Interface-heavy and experiential work still needs an observed running artifact and direct judgment. Treating a green gate as a complete product verdict merely replaces code-shaped overconfidence with test-shaped overconfidence.

Practical rules

  1. Write the invariant before broad implementation begins.
  2. Keep product intent, implementation strategy, and local tasks in separate artifacts.
  3. Make every acceptance criterion evidential, or state why it cannot be.
  4. Ground plans in repository evidence before proposing architecture.
  5. Prefer exact test and interface context over generic procedural reminders.
  6. Track neighboring regressions as well as issue-specific fixes.
  7. Update the specification when evidence disproves an assumption.
  8. Review the proof surface before treating generated code volume as progress.
  9. Give each binding behavior one owning law or specification.
  10. Compile status, stage, dependencies, and conflict surfaces into dispatch rather than maintaining a second manual task truth.
  11. Record the exact document and repository versions each run used, then reject or refresh stale effects.
  12. Keep corpus conformance, implementation proof, observed behavior, and product judgment separately legible.

Evidence limits

This lesson combines peer-reviewed work, active software documentation, recent preprints, a live public design corpus, and self-reported production results. The architecture is more mature than the empirical literature. The control-plane model is a design synthesis grounded partly in one working public project, not an established universal result. Large effects reported in small or recent studies should be treated as hypotheses for local evaluation rather than general performance guarantees.

Sources

  1. GitHub Spec Kit methodology
  2. SWE-bench
  3. Bun: Rewriting Bun in Rust
  4. Test-Driven Development for Code Generation
  5. TDAD: Test-Driven Agentic Development
  6. Spec Kit Agents: Context-Grounded Agentic Workflows
  7. Spec-Driven Development in the Age of AI Coding Assistants
  8. OpenSpec concepts
  9. OpenSpec getting started
  10. Misaligned: how it is built
  11. Misaligned ROADMAP: the dispatch board
  12. Misaligned spec status board
  13. Misaligned workflows

Connections

Related

Linked here

Suggest a correction ↗