Spec-driven development turns into waterfall when one big spec settles everything up front. When it is worth it, and how much spec a task needs.
Spec-driven development is not waterfall when the spec covers one task, stays short, gets written right before the work, and is checked against the code that comes out of it. It becomes waterfall when one large document tries to settle a whole project up front and nobody revises it once the agent starts building.
Whether it is worth it depends on the change: write the spec when being wrong is expensive, keep it short enough to argue with, and check it against the code that ships. Several objections in the waterfall critique hold up, but the 1970 paper usually blamed for waterfall never uses the word, and its author asked for more documentation, not less. Below: the five strongest objections, what that paper actually said, and a rule for how much spec a change deserves.
Sources: Royce (1970), Managing the Development of Large Software Systems (University of Washington copy)
A disclosure before the specifics: we build TLM Forge, a process layer for Claude Code that shows you a design before it builds, so weigh the product section near the end accordingly. For the basics of the method, start with spec-driven development, explained.
The case against spec-driven development, steelmanned
The sharpest version of the critique is François Zaninotto's November 2025 post "Spec-Driven Development: The Waterfall Strikes Back," which set off a long Hacker News thread. His argument is that spec-driven toolkits like GitHub's Spec Kit, AWS Kiro, Tessl and the BMad Method echo "the Waterfall model, which required massive documentation before coding so that developers could simply translate specifications into code." Here are the strongest objections from that post, the thread, and Asana's three-month report.
Sources: Marmelab: Spec-Driven Development: The Waterfall Strikes Back, Hacker News discussion (item 45935763)
1. The spec is bigger than the change
One of Zaninotto's examples: a developer used Spec Kit to display the current date in a time-tracking app, and the result was 8 files and 1,300 lines of text. His verdict on the reading load is blunt: "Developers spend most of their time reading long Markdown files, hunting for basic mistakes hidden in overly verbose, expert-sounding prose. It's exhausting." And when the spec already contains code, that code gets reviewed, then the implementation gets reviewed again. "As a result, review time doubles."
Sources: Marmelab: Spec-Driven Development: The Waterfall Strikes Back
2. The spec and the code drift apart
The commenter constantcrying, who said they had done professional waterfall development, put the long-run problem this way: "The problems come when you are deep into the project, your spec is a total mess and the tiniest feature you want to add requires extremely complex manipulation of the spec." Asana's engineers, reporting on three months of an internal spec-driven workflow in September 2026, saw a milder version: updating the spec as they learned took effort, and "Afterward, much of that detail repeated the code."
Sources: Hacker News: comment by constantcrying, Hacker News: constantcrying on professional waterfall work, Asana: Spec-driven development: The Good Parts
3. A precise spec is harder to write than the code
Another commenter, zvr, tried the method and gave up: "I find writing specs much harder than writing code, especially when trying to express the finer points of a project." In a February 2026 thread, fl0ki gave the deeper reason: "There is always more detail in implementations than can be specified by any less than the code itself." If only the code describes the behavior precisely, a spec is either vague or a second copy of the program in prose.
Sources: Hacker News: comment by zvr, Hacker News: comment by fl0ki
4. You can't spec what you don't understand yet
The essay behind that thread, "Spec-driven development doesn't work if you're too confused to write the spec," makes the most serious version of the argument. Of a system's business rules, its author says: "Usually we are actually confused about the domain logic." Formalizing them is how you discover the contradictions. "Any spec unambiguous enough to work is already close enough to code that we could just express it as code. Writing that spec is a discovery process."
Sources: deontologician: Spec-driven development doesn't work if you're too confused to write the spec
5. The spec gives false confidence
Zaninotto reports that in one of his examples the agent marked the "verify implementation" task as done without writing a single unit test, producing manual testing instructions instead. Asana describes a worse case: a detailed spec for a data migration, and mid-build the realization that two jobs could race and create duplicate custom fields. "The problem was that the direction was wrong." Spec, code and tests all agreed with each other, and the assumption under them was still wrong.
Sources: Marmelab: Spec-Driven Development: The Waterfall Strikes Back, Asana: Spec-driven development: The Good Parts
Objections 1, 2 and 5 target one kind of spec: long, written early, covering more than one change, and trusted without being checked. Objections 3 and 4 cut deeper, and the sizing table below answers them by skipping the spec where they apply.
What Royce's 1970 waterfall paper actually said
Waterfall is usually traced to Winston Royce's 1970 paper "Managing the Development of Large Software Systems," published in the Proceedings of IEEE WESCON. The paper never uses the word waterfall. It draws the familiar sequence from requirements to operations, then says: "I believe in this concept, but the implementation described above is risky and invites failure."
Sources: Royce (1970), Managing the Development of Large Software Systems (University of Washington copy), Wikipedia: Waterfall model
His complaint was that testing came last, "the first event for which timing, storage, input/output transfers, etc., are experienced as distinguished from analyzed," so a late surprise forced a major redesign. His fixes were five steps: program design comes first, document the design, do it twice, plan, control and monitor testing, and involve the customer. The part the waterfall critique misses: Royce wanted more documentation, not less. His answer to "how much documentation?" was "quite a lot."
Sources: Royce (1970), Managing the Development of Large Software Systems (University of Washington copy)
The failure Royce diagnosed was feedback latency: the gap between writing down an assumption and finding out whether it holds. The commenter 4ndrewl made the same point in the thread, arguing waterfall's problem was never the detailed spec but the multi-year lead time and no cheap way to iterate. Even the Agile Manifesto, often read as anti-documentation, says "while there is value in the items on the right, we value the items on the left more," and comprehensive documentation sits on the right.
Sources: Hacker News: comment by 4ndrewl, Manifesto for Agile Software Development
So a spec is waterfall-like in proportion to how long it sits before running code tests it. A spec for a task an agent finishes in an hour, checked by a test suite, gets its answer within that hour, not after the multi-year lead time 4ndrewl described.
What separates a waterfall spec from a useful one
A useful spec is scoped to one task, short, written just before the work, revisable, and ends in checks that run. Spec Kit's own methodology document claims this shift, saying "requirements and design become continuous activities rather than discrete phases."
Sources: GitHub Spec Kit: spec-driven.md
| Trait | Waterfall-style spec | Useful task spec |
|---|---|---|
| Scope | A whole project or milestone | One change an agent can finish and you can review |
| Size | Hundreds of lines, several files | Short enough to read before you approve it |
| When written | Weeks or months before the code | Minutes or hours before the code |
| Open questions | Filled with plausible guesses | Marked as questions and answered by a person |
| Acceptance criteria | Prose descriptions of behavior | Tests or checks that pass or fail |
| After coding starts | Frozen, or quietly abandoned | Revised when the code teaches you something |
| Checked against | Nothing, or a final sign-off | The actual diff, by someone who did not write it |
| After merge | Kept as an authoritative document | Shrunk to the decisions and risks worth keeping |
On open questions, Spec Kit's templates are good: they require a [NEEDS CLARIFICATION] marker for each ambiguity, to stop the model making "plausible but potentially incorrect assumptions." Anthropic's Claude Code guidance says the most useful specs "name the files and interfaces involved, state what is out of scope, and end with an end-to-end verification step that proves the feature works." And Asana learned the after-merge row late: "We now think a working spec should grow while the project is uncertain and shrink once the code can explain the implementation."
Sources: GitHub Spec Kit: spec-driven.md, Claude Code docs: Best practices, Asana: Spec-driven development: The Good Parts
For the mechanics, see how to write a spec an AI coding agent can follow. This post is about whether you need one.
Is spec-driven development worth it? Scale the spec to the risk
Scale the spec to the cost of being wrong, not the size of the diff. A three-line permission-check change can deserve more written intent than a 400-line UI component: one fails quietly in production, the other loudly in a screenshot. Two questions settle most cases: could you describe the diff in one sentence, and if the agent's assumption is wrong, what breaks and who notices?
| Kind of change | How much spec | Example |
|---|---|---|
| Clear, local, one-sentence diff | None. Prompt the agent directly. | Fix a typo, add a log line, rename a variable |
| Small fix with a known cause | Two or three lines in the prompt plus a failing test that proves the bug | Off-by-one in a pagination helper |
| Multi-file feature, approach unclear | A short plan with acceptance criteria and out-of-scope items, approved before code | Add OAuth login to an existing session flow |
| Touches data, money, auth or a public contract | A written spec naming invariants, failure modes, migration and rollback, reviewed by a second person | A data migration, a schema change, a wire-format change |
| Spans sessions, people or many agent tasks | A living spec kept current during the work, then trimmed to decisions and risks | A batch of related migrations run by several agents |
| You do not yet understand the domain | No spec yet. Build a throwaway spike, then write the spec from what you learned | A prototype of a new pricing rule engine |
The first row comes from Claude Code's documentation, which says plan mode "adds overhead" and advises: "If you could describe the diff in one sentence, skip the plan." Asana reached the same place from the other side: "For most small, local changes, a conversation or short plan is enough." The last row is a small version of Royce's "do it twice" step, and it answers the too-confused-to-spec objection directly: when the domain is unclear, the spike is the discovery process, and the spec comes after it.
Sources: Claude Code docs: Best practices, Asana: Spec-driven development: The Good Parts, Royce (1970), Managing the Development of Large Software Systems (University of Washington copy)
The fifth row is where the clearest evidence sits. Asana's team used its workflow to move 66 Admin Console settings onto shared frameworks, roughly 150 migrations, each run by a cloud agent from its own ticket, and the team running that effort reported that 91% needed no revision after review. That figure is the team's own report, not a controlled measurement, but it is the right shape of task for a spec: many related changes, several agents, one direction that must survive handoffs.
Sources: Asana: Spec-driven development: The Good Parts
A wrong spec is cheaper than a wrong diff
The critics compare spec-driven development to writing the code yourself. With an agent, the real alternative to a spec is an agent that guesses, and its guesses do not vanish because nobody wrote them down. They land in the diff, where they are harder to see.
A wrong spec is a paragraph. A reviewer reads it in two minutes, says "that is not how refunds work," and nothing is thrown away. A wrong diff from an agent that never asked arrives looking finished: it compiles, passes tests the agent wrote against its own assumption, and spreads that assumption across a dozen files. Claude Code's documentation names the risk: "Letting Claude jump straight to coding can produce code that solves the wrong problem."
Sources: Claude Code docs: Best practices
Asana's migration story reads as a warning against trusting a spec, and it is one. Read it the other way too. The engineer caught the problem, stopped, wrote a one-page design document, and tagged a couple of coworkers for input. Asana's key line: "The agent could build out that idea faster than people could stop and question it." A spec does not make the idea right. It gives people a place to question it before the agent builds it out.
Sources: Asana: Spec-driven development: The Good Parts
This also explains why Zaninotto's counterexample works. He built a 3D sculpting tool with Claude Code in about 10 hours without any spec, adding small features one by one and correcting the agent when it misunderstood him. Each change was small, visible on screen and cheap to undo: the top rows of the table. The same habit on a billing migration puts a wrong guess into production data. For where that style stops working, see agentic coding vs vibe coding.
Sources: Marmelab: Spec-Driven Development: The Waterfall Strikes Back
Where the critics are right
- Generated specs are often too long. If the spec for a date label is longer than the code, cut it or skip it.
- Code inside a spec doubles review. Describe behavior, constraints and checks, and review code once, as code.
- Drift is real. Treat a spec as a working document for the task; afterward keep the decisions and risks and archive the rest.
- A spec is not verification. An agent can tick every box and still skip the test. Only a check that runs, plus a reviewer who did not write the code, tells you the spec was met. An agent can also edit the test itself; see how to stop Claude Code changing tests to pass.
- Plan mode covers a lot. For many changes, a reviewed plan inside the session is all the spec you need.
For how three frameworks structure the spec step, see TLM Forge vs BMAD-METHOD vs GitHub Spec Kit.
Spec-driven development fails when applied the same way to every change, which is what waterfall did to every project.
Where TLM Forge fits
TLM Forge applies a coarser version of the same idea: three sizes instead of one heavy process for everything. It sizes each task as Light, Medium or Deep, and Light work gets no review agents. On Medium and Deep work it shows you a design for your OK before building, which is the short, reviewable spec from the middle of the table. On Pro, a hook makes subagent launches and code edits wait until you have seen that design and replied. Deep work also gets a spec audit of hidden risks. Three sizes are coarser than the six rows above, and none of this makes code secure or bug-free.
Frequently asked questions
01Is spec-driven development just waterfall?
Not when the spec covers one task, is written right before the work, and is checked against the code with runnable tests. It turns into waterfall when one large spec tries to settle a whole project up front and nobody revises it once implementation teaches them something.
02Is spec-driven development worth it?
For changes that touch data, money, auth, public contracts or several sessions, usually yes, because a wrong assumption is cheaper to catch in a paragraph than in a finished diff. For small, local changes you could describe in one sentence, a direct prompt is faster and the spec is overhead.
03What is the difference between spec-driven development and waterfall?
Scope and feedback time. A waterfall spec covers a whole project, is written weeks or months before the code and is frozen once coding starts. A useful task spec covers one change, is written minutes or hours before the code, ends in tests that pass or fail, and is revised when the code teaches you something.
04How do you stop a spec drifting from the code?
Keep the spec scoped to one task, put acceptance criteria in tests rather than prose, revise it when implementation changes the plan, and trim it after merge to the decisions and risks worth keeping. A spec nobody checks against the diff will drift.
05What did Royce's 1970 waterfall paper actually say?
Royce never used the word waterfall. He drew the sequential model, called it "risky" because testing came last, and proposed five fixes: program design first, document the design, do it twice, plan and monitor testing, and involve the customer. He favored more documentation, not less.