Spec-Driven Development Needs an Exit Strategy
AI coding teams need small change briefs, native engineering artifacts, and enough judgment to stop Markdown specifications becoming a second codebase.
Open a repository after six months of spec-driven agent work and you may find a second system sitting next to the code. Requirements, research notes, high-level designs, low-level designs, implementation plans, task lists, review reports, and a growing stack of Markdown that explains what the code is supposed to mean.
The code changed last Tuesday. Half the documents did not.
I understand how teams get there. Agents produce code quickly, so we try to move more thought in front of implementation. We ask for clearer requirements, more design, and stronger acceptance criteria. Then we turn that into a workflow. Before long, every change has fifteen stages and enough generated prose to use most of the context window before the agent reads the relevant class.
That is not a specification system. It is a second codebase with weaker tooling.
We still need specifications. The mistake is treating a specification as a permanent natural-language copy of the software. A useful spec describes the next change, exposes the decisions that matter, and gives us something to verify. After the change ships, most of it should disappear.
What remains should move into the artifacts software teams already know how to maintain: code, schemas, tests, policies, configuration, telemetry, and a small number of decision records.
Code becomes the fact
Code is actual behavior. Once that behavior reaches production, users and connected systems start to depend on it. A mistake can become an observed contract because it has behaved the same way for three years. When the system fails, the running behavior matters more than the design document that described something else.
For existing behavior, start with the code and the production system. Reading a natural-language summary instead is rarely an improvement.
The code still cannot decide what the next version should do. It does not know which behavior must stay stable, which policy changed, which workaround can disappear, or which user outcome matters most. A repository can show that an account-closing function deletes a record. It may not show that regulation requires seven years of retention or that another company consumes an undocumented export every night.
That context has to come from somewhere else. But it does not follow that we need a permanent prose description of the whole system.
We need enough context to decide the delta: the difference between what exists and what should exist next.
Specs are for the delta
A change specification earns its cost when it helps a team decide and review that delta. It should name the outcome, non-goals, constraints that differ from current behavior, and evidence required for acceptance. A technical design belongs there when the change crosses an architectural boundary or contains a decision that will be expensive to reverse.
That is enough for many changes:
the intended outcome and non-goals;
known unknowns and decisions that need human judgment;
affected system boundaries and authoritative interface artifacts;
functional and non-functional constraints that differ from today;
acceptance evidence proportionate to the risk.
I prefer calling this a change brief. “Specification” now carries too much baggage. It suggests a complete description, and completeness is exactly where these methods become expensive.
Teams have tried exhaustive specification before. They produced requirement documents, high-level designs, low-level designs, and architecture records for every decision. The collection grew until finding the right document cost more than reading the code. Humans stopped looking. The documentation stayed complete in the administrative sense and became useless in the engineering sense.
Agents can recreate the same failure much faster. A long workflow produces research, requirements, design, planning, and review artifacts on demand. Every stage makes the process look more controlled. It also creates more material to read, reconcile, retrieve, and keep current.
Research notes, prototypes, and design records should be added when uncertainty justifies them. They resolve a specific problem. They should not become required stages for every pull request.
The map will always be incomplete
A prompt, ticket, or spec is a map of the work. The territory includes the codebase, users, runtime environment, historical constraints, connected systems, and decisions that nobody wrote down.
Real work keeps producing new information. The agent reads a module and finds an unexpected dependency. A prototype exposes a usability problem. A test reveals an undocumented edge case. Production data contradicts the design assumption.
A recent field guide on finding unknowns in agent work makes this point well. Some unknowns are visible at the start. Others appear only when we inspect references, build prototypes, or compare a result with judgment we could not express beforehand.
So discovery has to stay open:
Before implementation, inspect the current system, identify decisions that could change the architecture or user experience, and build a cheap prototype when preferences are hard to state.
During implementation, record meaningful deviations and stop when a new unknown changes the risk or direction of the work.
After implementation, read the code, run the checks, and compare the result with the original intent.
The spec participates in that loop. It cannot complete the loop before coding begins.
Keep durable facts in their native form
The phrase “promote durable constraints” needs care. It can sound like an instruction to write permanent Markdown. That would recreate the problem.
Software engineering already has better homes for most durable facts:
API shape and compatibility belong in OpenAPI, AsyncAPI, protocol schemas, types, and compatibility tests.
Data invariants belong in types, database constraints, validation, and migration checks.
Security rules belong in access policy, static analysis, dependency policy, and runtime enforcement.
Architecture boundaries belong in module structure, dependency rules, and focused architecture tests.
Reliability requirements belong in load tests, service objectives, telemetry, and alerts.
Release rules belong in continuous integration and deployment policy.
These artifacts participate in delivery. A failed schema check or alert demands attention. A paragraph in an old design directory usually does not.
Natural language still has a place. Business policy, trade-offs, and architectural rationale do not always fit into an executable artifact. Keep that prose short, owned, and close to the thing it explains. An architecture decision record is worth keeping when a future team might otherwise repeat an expensive investigation. Recording every local choice just hides the few decisions that matter.
Ask which fact must survive and what its authoritative form should be.
Judgment belongs in the workflow
Heavy specification methods try to control quality by prescribing the path. Every change produces the same documents, reviews, and test categories.
That consistency can spend attention on low-risk work while hiding the judgment needed for the hard parts. A copy change and a payment-flow change do not need the same process or testing strategy.
Simon Willison describes a simpler instruction: let the coding agent apply judgment about how to perform the work instead of spelling out every procedural branch. I think the advice is right.
Judgment does not mean unconstrained autonomy. The team still defines the outcome, safety boundaries, ownership, and acceptance authority. The agent can choose tactics inside those boundaries. It should surface uncertainty and ask for a decision when the consequences exceed its authority.
The workflow can then follow the risk:
a small, familiar change can move from a short brief to implementation and review;
unfamiliar code calls for factual research before design;
unclear user experience calls for prototypes and comparison;
an architectural change needs explicit human alignment;
high-consequence behavior needs stronger independent evidence and approval.
The process expands when the work demands it. Starting every change at maximum weight wastes time and context.
Context is an engineering budget
Large specifications cost more than authoring and maintenance time. They compete with the code and evidence the agent needs for the current decision.
Every requirement, design note, repository instruction, and tool definition consumes part of a limited working context. Important rules become harder to apply when stale and duplicated material surrounds them. A spec that leaves too little room for the repository defeats its own purpose.
Progressive disclosure is a better fit. Give the agent a small map, stable rules that apply broadly, and pointers to deeper material. Retrieve the relevant schema, decision, or module guide when the work crosses that boundary.
A concise AGENTS.md can document build commands, repository layout, and architectural boundaries. It should not narrate every class or repeat API documentation. The file helps humans for the same reason: it tells them where to look without pretending to replace what they will find.
Experience with Research-Plan-Implement shows the cost of getting this wrong. The original workflow moved human review before implementation, but teams ended up with large prompts and plans that could reach 1,000 lines. Engineers reviewed the plan while treating generated code almost like compiler output. That approach worked better on simple greenfield tasks than on complex changes to existing systems.
In Everything We Got Wrong About Research-Plan-Implement, Dexter Horthy retracts that position. Teams shipped more code and then spent much of the gain cleaning up earlier output. The implementation could also diverge from the reviewed plan, which forced engineers to reconstruct what happened from the code anyway.
The revised workflow uses smaller contexts for factual research, design alignment, structure, implementation, and review. The correction is simple: research and design create leverage, but engineers still read and own the code.
Modernization makes this obvious
A mature application contains several kinds of behavior in the same codebase. Some logic represents durable business policy. Some implements a published interface. Some exists because an old platform imposed a technical limit. Some came from an incident fix whose context is gone. Some is simply a defect that survived long enough to look intentional.
An agent that treats all code as the target specification can translate those layers faithfully into a new language or architecture. You get a cleaner version of the same debt. Efficient, but not helpful.
Modernization starts by classifying observed behavior:
Preserve durable business invariants and externally required behavior.
Verify behavior that appears active but lacks clear ownership or evidence.
Redesign logic tied to obsolete architectural constraints.
Remove dead paths, duplicated logic, and confirmed defects.
Code analysis reveals dependencies and current behavior. Runtime data shows which paths are still used. Tests establish a baseline. Business, architecture, risk, and operational context decide which behavior belongs in the target system.
The code is the starting evidence because it is the behavior we have. The change brief is temporary because its job is to decide the delta. The new implementation and its native checks become the next durable state.
Small specs still need real evidence
Keeping specifications small does not mean returning to a loose prompt followed by hopeful review.
An agent can turn an underspecified request into a coherent implementation before the missing decisions become obvious. The result may compile, pass the available tests, and look internally consistent. Coherence can hide a business decision that nobody approved.
Research on repairing ambiguous natural-language requirements found that targeted repairs improved code-generation results, while direct ambiguity resolution often produced irrelevant or inconsistent clarification. SWT-Bench found that generated tests could filter proposed fixes and double the precision of a software-repair agent.
Formal specification does not remove review either. A 2026 evaluation asked 30 models to translate natural-language requirements into TLA+ specifications. The best result reached 26.6% syntactic correctness and 8.6% semantic correctness. Preserving meaning between representations remained the hard part.
These results support focused clarification and independent checks. They do not support generating the longest spec or letting one reasoning path define the requirement, implementation, and evidence without challenge.
The amount of independence should follow the risk. A small internal refactor may need ordinary tests and code review. A change to authorization, money movement, or regulated data needs stronger separation, adversarial review, and explicit approval.
A lighter operating model
The method does not need fifteen stages:
Start from the code and operational evidence that describe the current system.
Define the intended delta, important boundaries, and known unknowns.
Add research, prototypes, design alignment, or stronger verification where risk requires them.
Read and review the implementation, not only the plan.
At release, discard temporary reasoning and preserve each surviving fact in its native authoritative artifact.
That is enough structure to guide the work without building a natural-language replica of the software.
Before implementation, the change brief describes the intended delta. During implementation, it helps people and agents align while new information changes the plan. After release, code and production behavior become the primary evidence of what the system does.
Durable obligations survive in the forms we already know how to maintain: schemas, tests, policies, configuration, telemetry, and short records for rationale that cannot be encoded elsewhere. Most planning detail should expire.
The teams that benefit most from coding agents will not produce the most documentation. They will know what to specify, what to discover, what to verify, and what to let go.





