For most of the last two decades, writing a detailed spec was something you did because a process demanded it, and then nobody read it. The code diverged within a sprint, the document went stale, and the real specification lived in whoever had been on the team longest.
Coding agents broke that equilibrium, because an agent has no institutional memory. It cannot absorb context from standups or notice that the thing you asked for contradicts a decision made in March. It reads what you give it. Suddenly the quality of your written intent is not a documentation hygiene question, it is a direct input to output quality. That is the real reason spec driven development went from a dusty idea to a tooling category inside about eighteen months.
And then the honest reports started coming in, and they are mixed. One team measured spec tooling runs at roughly ten times slower than iterative prompting for the same work. Another found the lower level documents drifting out of sync with the higher level ones and with the shipped code, so the spec stopped being a source of truth while still costing money to maintain. Enterprise teams found the tools assumed a clean slate they do not have.
So this post is not a pitch. It is an attempt to answer the question that actually matters: specs are an artifact with a cost and a payback period, so which work justifies them, and how do you tell before you have spent a quarter on a methodology.
Why the Economics of Specs Changed
Three things shifted at once.
The bottleneck moved from writing code to specifying it. When a capable agent can implement a well scoped feature in minutes, the expensive, slow, human part of the loop is deciding precisely what should be built. Sean Grove's often quoted framing puts code at roughly 10 to 20 percent of an engineer's value, with the rest in the structured communication around it. You can argue the exact split, but the direction is hard to dispute once you have watched an agent produce a thousand lines from a two sentence prompt and then watched a human spend an hour explaining why those were the wrong thousand lines.
Verification became the new cost center. DORA's 2026 ROI report on AI assisted development names this directly as the verification tax: reviewing AI generated code is now a meaningful chunk of the work, and it is one of the causes of the productivity dip that most organizations should expect before the long term gains arrive. Their model also assumes change failure rate rising from 5 percent to 6 percent after AI adoption, which they offset with automated testing, continuous integration, and small batch sizes. A spec is partly an attempt to front load that verification: if the acceptance criteria are written down before the code exists, review has something to check against other than taste.
Context became the limiting resource. Agents work from what is in their context window. A codebase that carries its own structured intent, in files an agent can read, gives better results than one where intent lives in a commit history and someone's head. That is the strongest version of the SDD argument, and the one I find most convincing: you are not writing documents for humans, you are building a machine readable description of your system's intent.
The thing to notice is that none of those three arguments require a heavyweight process. They require written intent that is accurate and findable. Whether you need a five stage pipeline to produce it is a separate question, and the answer is often no.
The Tooling Landscape
Four distinct approaches, often conflated.
Persistent context files are the lowest cost and highest return item on this page. AGENTS.md is now a widely supported convention for repo level instructions to coding agents, and it sits under the Linux Foundation's Agentic AI Foundation alongside MCP, which gives it some durability as a standard rather than one vendor's format. Kiro extends the same idea with steering files, splitting them into global rules in ~/.kiro/steering/ and project rules in .kiro/steering/ that are checked into the repo and override the global ones. Spec Kit's constitution plays the same role, established once per project.
If you do nothing else from this post, write these. They are a few hundred words, they are read on every single agent invocation, and they stop you re explaining your stack in every prompt.
GitHub Spec Kit is the most structured option. Its current flow is a constitution once per project, then per feature: /speckit-specify, /speckit-plan, /speckit-tasks, /speckit-implement, and /speckit-converge, repeating implement and converge until convergence reports converged. Artifacts land in .specify/. Notably, recent versions have moved away from being a single mandatory pipeline: it now ships three independent entry points, with spec driven development in core plus optional extensions for bug fixing (assess, fix, test) and idea assessment (intake, research, define, shape, decide). The bug extension is a telling addition, because it acknowledges that a one line fix should not go through a feature specification process.
AWS Kiro makes the spec the unit of work inside an agentic IDE. It generates three files per feature: requirements.md with user stories and acceptance criteria, design.md with component breakdown and data flow, and tasks.md as a numbered implementation checklist the agent works through. It adds event driven hooks, defined in YAML with a name, a trigger, and instructions, that can run a linter on save, regenerate tests when implementation files change, update design.md when a module changes, or scan staged files for secrets before a commit and block it. Commit messages and PR descriptions get drawn from the spec. The pitch is that code becomes a build artifact of the spec and the reasoning lives in the repo next to the code.
Plan mode is the minimal version: state the goal and constraints, let the agent read the relevant code, iterate on a single plan document inline, then implement. One document, one round of iteration, then code. No artifact hierarchy, no files to keep in sync.
The Case Against, Taken Seriously
This is the section most SDD content skips, and it is the most useful one.
The token and time cost is real and large. One practitioner comparison found spec tooling runs costing several times more than an equivalent plan mode flow, because hierarchical artifacts get reprocessed on every implementation step. Scott Logic's reported finding was roughly ten times slower than iterative prompting for the same work. The Spec Kit issue tracker has reports of Pro tier users exhausting usage limits in under an hour. If you are running this at team scale, that is a budget line, not a rounding error.
Drift defeats the premise. The whole argument for specs is that they are the source of truth. But in practice, lower level documents fall out of step with higher level ones and with the shipped code, and nothing keeps them synchronized. A spec that no longer describes the system is worse than no spec, because it is confidently wrong and an agent will believe it.
More context is not monotonically better. Large accumulated context can cause models to get distracted by stale plans and repeat themselves, which is the context rot problem. So the extra spend does not just fail to help, it can actively degrade output. That inverts the naive assumption that feeding an agent more documents produces better code.
The quality gain is not reliably there. The honest summary from one careful comparison was that the output was not better, just spread across more files, with more drift, at higher cost. That is a damning result if it generalizes, and it should at minimum stop anyone from assuming the benefit is self evident.
The tools assume greenfield, and most work is not. A March 2026 critique argues that Kiro, Spec Kit, and similar methods assume a clean slate while enterprise teams maintain existing systems with years of accumulated business logic. Kiro's phase pipeline adds overhead even for a one line fix, Spec Kit's generic templates need manual customization for an existing codebase, and the documentation can outweigh the work of building the feature. The named gaps are brownfield support, stakeholder validation of requirements, respect for standardized enterprise stacks, and anything beyond code generation.
That last point connects to the most important number in this whole discussion. The Stanford Software Engineering Productivity research cited in DORA's report found AI delivering a 35 to 40 percent productivity gain on simple greenfield tasks, but 10 percent or less on complex legacy code. Greenfield is where AI already helps most and also where spec tooling is designed to work. Legacy is where most engineering time actually goes and where both the AI gains and the tooling fit are weakest. Any honest assessment of SDD has to sit with that.
So When Do Specs Actually Pay Off?
The useful reframe is to stop asking whether SDD is good and start asking what the spec's lifetime is. A spec costs roughly the same to produce whether it is used once or fifty times. The payback is entirely in the reuse.
The pattern that holds up across both the advocates and the critics: specs earn their cost when they are durable and shared, and lose when they are per feature and disposable.
Concretely, the cases where I would write a real spec:
- A public API or protocol other teams build against
- Anything in a regulated domain where the written requirement is itself a deliverable
- A product surface that several teams will implement separately, such as the same flow on web, iOS, and Android
- A migration or refactor that will run for months across many pull requests
- Anything where the acceptance criteria are genuinely contested and need agreement before code
And the cases where plan mode is the better tool:
- A single feature in a codebase you know, implemented by one person and one agent
- Bug fixes of any size
- Exploratory work where the goal is to learn what is possible
- Anything where you can hold the whole problem in one context window
What a Good Spec Looks Like
If you are going to write one, the format matters less than the properties. Here is a requirements file in roughly the Kiro shape, written the way that actually helps an agent.
# Requirements: Tenant scoped audit log export
## Context
Enterprise customers need to export their own audit events for compliance
review. Existing audit events are written to the `audit_events` table with a
`tenant_id` column. No export path exists today; support engineers run manual
SQL queries, which is the problem this replaces.
## User stories
### US-1: Export own audit events
As a tenant administrator, I want to export my organization's audit events
for a date range, so that I can provide them to our compliance team.
Acceptance criteria:
- GIVEN an authenticated tenant admin
WHEN they request an export for a date range within retention
THEN they receive a signed download URL valid for 15 minutes
- GIVEN a tenant admin from tenant A
WHEN the export runs
THEN the output contains zero rows with tenant_id other than A
- GIVEN a date range exceeding the 400 day retention window
WHEN the export is requested
THEN the request is rejected with 422 and a message naming the window
- GIVEN an export of more than 1,000,000 rows
WHEN the export is requested
THEN it is processed asynchronously and the admin is notified on completion
## Non goals
- Cross tenant or platform wide export. That is a separate internal tool.
- Real time streaming of audit events.
- Custom field selection in v1. Fixed schema only.
## Constraints
- Must not add read load to the primary database. Use the read replica.
- Export files must be encrypted at rest and expire after 7 days.
- Tenant isolation is enforced at the query layer, not in application filtering.
## Open questions
- [ ] Does legal require the export itself to be an audited event? Owner: Priya
- [ ] CSV only, or CSV and JSONL? Owner: productThe properties that make this useful to an agent rather than decorative:
Acceptance criteria are testable. Each one maps to a test somebody could write. "Should be secure" is not a criterion. "Zero rows with a different tenant_id" is.
Non goals are explicit. This is the single highest value section and the one most often missing. An agent will happily expand scope into territory you never intended, and a non goals list is the cheapest possible guardrail.
Constraints capture the things that are not negotiable and that an agent cannot infer from the code, like which database to read from and where isolation is enforced.
Open questions are tracked with owners rather than silently resolved by whoever writes the code. An unresolved question in a spec is honest. An unresolved question that an agent answers by guessing is a bug with a paper trail that says it was intended.
And the companion file that gets read on every invocation, which is where I would start if you are doing one thing:
# AGENTS.md
## Stack
Go 1.24 services, Postgres 16, Kubernetes. Terraform for infra.
Frontend is TypeScript with React, strict mode on.
## Conventions
- All database access goes through the repository layer in internal/store.
Never write raw SQL in handlers.
- Every multi tenant query must take tenant_id as an explicit parameter.
There is no implicit tenant context.
- Errors wrap with fmt.Errorf("%w") and are logged once, at the boundary.
- Structured logging only, with a correlation ID on every log line.
## Testing
- `make test` runs unit tests. `make test-integration` needs Docker.
- New code needs table driven tests. Match the style in internal/store/*_test.go.
- Do not mock the database. Use the test container helper in internal/testutil.
## What not to do
- Do not add new dependencies without asking.
- Do not modify files under api/generated. They are code generated from proto.
- Do not reformat files you are not otherwise changing.That file takes twenty minutes to write and changes the quality of every agent interaction in the repo. The return per word is not close to anything else in this post.
Fitting It Into a Real Workflow
If you adopt any of this, the shape that seems to work is a tiered one rather than a single process applied to everything.
Two things in that diagram are load bearing.
Persistent context feeds both paths. Whether you write a full spec or just a plan, the conventions file is read either way, which is why it is the highest leverage artifact.
Verification loops back to the spec, not just the code. If implementation revealed that the requirement was wrong, the fix is to update the requirement. This is the discipline that prevents drift, and it is the one that teams silently drop first. A spec nobody updates is a liability with a filename.
Metrics Worth Tracking If You Adopt This
If you are going to claim SDD is working, measure it. Otherwise you are running a methodology on vibes, which is what SDD is supposed to replace.
| Metric | What it tells you |
|---|---|
| Rework rate after merge | The core claim of SDD is fewer wrong implementations. If rework does not fall, it is not working. |
| Spec to code drift incidents | Count the times the spec no longer matched the system. This is SDD's main failure mode, so track it explicitly. |
| Time from intent to merged change | Includes the spec writing time, which is the honest denominator. Beware measuring only implementation speed. |
| Token or credit cost per merged change | The cost side of the trade, and the thing practitioners found several times higher with heavy tooling. |
| Review iterations per pull request | A proxy for whether the verification tax is going down. |
| Change failure rate | DORA's modeling assumes AI adoption pushes this up. Specs are supposed to push it back down. Verify. |
| Share of changes needing a full spec | If this is above roughly a quarter of your work, you are probably over applying the process. |
| Open questions resolved before implementation | Measures whether the spec is doing its real job, which is forcing decisions early. |
The one I would put on a wall is rework rate after merge, split by whether the change had a spec or not. That single comparison answers the question this entire category is arguing about, for your team specifically, in about a quarter.
Pitfalls
- Treating SDD as a methodology to adopt wholesale. It is an artifact type with a cost. Apply it where the reuse justifies the cost.
- Running a feature pipeline for a one line fix. The tools themselves have started adding separate lightweight paths for this, which is an admission that the full flow was being over applied.
- Generating specs and never updating them. Drift is the documented primary failure mode. An unmaintained spec actively misleads agents.
- Assuming more context is better. Context rot is real. A tight, current spec beats a sprawling hierarchy of stale ones.
- Importing greenfield tooling into brownfield work. The tools assume a clean slate. Most engineering does not have one, and the AI productivity gain on complex legacy code is reportedly 10 percent or less regardless.
- Skipping the non goals section. It is the cheapest scope control you will ever write.
- Letting an agent resolve open questions silently. An unanswered question should block, not get guessed.
- Measuring implementation speed only. If you count the spec writing time as free, every comparison will flatter SDD.
- Confusing a spec with a plan. A plan is disposable and for one implementation. A spec is durable and for many. Conflating them is how you end up writing durable artifacts for disposable work.
Conclusion
The agentic era genuinely did change the value of written intent. An agent reads what you give it and nothing else, so clear, current, machine readable intent now converts directly into better output. That part of the spec driven development argument is sound and is not going away.
What does not hold up is the leap from there to a heavyweight per feature pipeline. The careful practitioner reports are consistent: several times the cost, roughly ten times slower in at least one measurement, output not meaningfully better, and documents that drift apart from each other and from the code. Meanwhile the one artifact that reliably pays for itself, a short conventions file read on every invocation, takes twenty minutes and shows up in almost none of the methodology discussions.
So the practical position I would take: write the persistent context files today, because they are nearly free and they compound. Default to plan mode for ordinary feature work. Reserve real specifications for intent that outlives a single implementation, which means public contracts, regulated requirements, cross team surfaces, and long running migrations. Then measure rework rate split by whether a spec existed, and let your own data decide where the line sits.
The spec is not the point. Shared, current, verifiable intent is the point, and specs are one way to buy it. Sometimes an expensive way.
References
- GitHub: Spec Kit
- Spec Kit docs: SDD philosophy and methodology
- AWS Builder Center: AWS Kiro, the Agentic IDE That Makes Specs the Unit of Work
- Instil: Spec driven development is dead, long live plan mode
- Martinelli: Why spec driven development tools fail in the enterprise
- InfoQ: New DORA report claims strong engineering foundations drive AI return on investment
- DORA: Research insights
- Isoform: The limits of spec driven development
- Linux Foundation: Agentic AI Foundation, anchored by MCP, goose, and AGENTS.md