跪拜 Guibai
← Back to the summary

Spec-Driven Development Is a Document Expansion Movement, Not a New Paradigm

Goodbye SDD — Why Spec-Driven Development Doesn't Suit Most Projects

This article discusses Specification-Driven Development (SDD) in the current AI programming context: first writing requirements and constraints into a Spec, then letting a Coding Agent plan, implement, and verify code based on it.

What SDD Is and Why It Suddenly Became Popular

In the early days of AI programming, people were used to directly typing something like "add a captcha to the login page" into the chat box and letting the model start modifying code. This approach was fast and thrilling, hence it was called Vibe Coding. But as soon as a project became slightly more complex, problems emerged: the model didn't know which behaviors must not be broken, couldn't remember what was confirmed ten turns ago, and couldn't distinguish whether a requirement described a business goal or hinted at a technical solution. It might rapidly deliver a complete implementation, only to have implemented the wrong thing.

SDD emerged precisely to address this sense of losing control. Its basic proposition is not complicated: Don't let the Agent start writing code immediately after receiving a vague instruction; first, write down clearly what needs to be done. A common workflow is roughly as follows:

  1. Organize product goals, user scenarios, requirement boundaries, and acceptance criteria into a Spec.
  2. Let the Agent investigate the codebase based on the Spec and generate a technical design.
  3. Break the design down into an executable task list.
  4. Let the Agent implement each item, then check whether the results meet expectations according to the Spec.
  5. Some schools of thought retain the Spec after delivery, updating the Spec first when subsequent functional changes occur, then modifying the code.

Different tools give these files different names, but the structure is largely similar. Kiro commonly uses requirements.md → design.md → tasks.md; GitHub spec-kit generates a set of files including Spec, Plan, Research, and Tasks; OpenSpec organizes a change using proposal, delta spec, design, and tasks, and merges incremental requirements into the long-term Spec upon archiving.

Its starting point is reasonable. The stronger the Coding Agent's capabilities, the greater the destructive power of understanding deviations. When a person writes ten lines of wrong code, it can often be spotted during review; an Agent, based on a wrong premise, can generate dozens of files at once, yet superficially appear structurally complete and fully tested. Clarifying goals, constraints, and acceptance criteria first allows humans and models to discover disagreements before incurring implementation costs.

SDD also aligns with a very attractive vision: since large models can already translate natural language into code, can developers further step away from code details and instead maintain higher-level business intent? The Spec becomes the common language between humans and AI, with code relegated to a generatable "last mile." When requirements change, modify the Spec, and the Agent automatically propagates changes to design, tasks, tests, and implementation. Development no longer revolves around code, but around intent.

This narrative hits several real pain points of AI programming: chat context gets lost, vague prompts produce random results, complex tasks need decomposition, multi-person collaboration requires review, and Agent implementations need verification. After tools like GitHub spec-kit, AWS Kiro, OpenSpec, and Tessl appeared successively, SDD was quickly packaged from a prompt organization method into a new development paradigm for the AI era.

The problem lies precisely here. "Write down requirements clearly before coding" is a simple and correct piece of advice, but it does not naturally lead to "Spec should become the long-term source of truth," nor to "most projects need an SDD workflow." Moving from a task description to a parallel knowledge system requiring continuous maintenance spans all the problems that traditional software engineering has never easily solved.

Every so often, the software industry reinvents the idea that "as long as requirements are written clearly enough, code will naturally appear." Previously called CASE, MDD, DSL, Low-Code, now it's called Spec-Driven Development. The key role in the new story has changed from a deterministic code generator to a large model, but the old problems remain: who ensures the description is correct, who maintains consistency between description and implementation, who is responsible for synchronization after requirements change, and who is this description actually for?

SDD's most tempting promise is to set the Spec as the "Single Source of Truth" and then let the Coding Agent generate code according to the Spec. It sounds like eliminating the gap between requirements and implementation. The reality is exactly the opposite: natural language, passing through a non-deterministic model to become code, has a longer, more hidden, and harder-to-reproduce interpretation process in between. SDD hasn't eliminated the gap; it has just paved a layer of Markdown over it, making people mistakenly think there's a road underneath.

My judgment is direct: Spec-first has value in some tasks; Spec-anchored requires extremely strong governance capabilities; Spec-as-source remains an expensive faith experiment for most business projects. Bundling all three together as SDD and then promoting the most idealized benefits to all projects is where the problem lies.

1. SDD Hasn't Even Clearly Defined What It Is

Birgitta Böckeler is a Distinguished Engineer at Thoughtworks with over twenty years of experience in software development, architecture, and technical leadership. In October 2025, she published "Understanding Spec-Driven-Development: Kiro, spec-kit, and Tessl" on Martin Fowler's personal website, combining her actual trials of Kiro, spec-kit, and Tessl to systematically question SDD's definition and practical applicability. She divided the current so-called SDD into three layers:

  1. Spec-first: Write a Spec for the current task before coding; it can be deleted after the task ends.
  2. Spec-anchored: The Spec is retained after feature delivery and continuously updated with subsequent evolution.
  3. Spec-as-source: The Spec is the primary source file; people only modify the Spec, and code is merely a generated artifact.

These three layers seem to differ only in degree, but they are actually three completely different engineering contracts.

Spec-first is a context organization technique, similar to a well-structured long prompt. Spec-anchored is a long-term document governance system. Spec-as-source is closer to model-driven development and generative programming, requiring the team to change code ownership, debugging methods, review subjects, and release processes. The former can be tried in an afternoon, but the latter two introduce long-term governance costs.

Yet the promotion of SDD often blends them together: using Spec-first's low barrier to attract teams, then using Spec-as-source's grand benefits to prove its value. Today they say "it's just writing down requirements clearly first," tomorrow they say "maintaining software in the future means maintaining the Spec." This is not incremental adoption, but conceptual slippage.

Even "Spec" itself lacks a stable definition. It could be user stories, acceptance criteria, PRD, technical design, interface contracts, task lists, domain rules, or a mixture of these things. When one word simultaneously holds "why to do it, what to do, how to do it, how to verify, and to what step it's implemented," what you get is not a unified language, but an ownerless documentation quagmire.

A qualified engineering artifact must at least answer these questions:

If these questions have no answers, "Spec is the single source of truth" is not an engineering rule, just a brand slogan.

2. It's Stuck Between Context Engineering and Traditional Artifacts, Pleasing Neither Side

After the emergence of coding agents, most new content added to codebases serves context engineering, while previous content I call traditional artifacts.

If the Spec is Context Engineering, It's Essentially Still a Prompt

A Spec that only serves the current Coding Agent and can be discarded after the task is completed is essentially a templated, versioned Prompt. Structuring it certainly has value: it can fix goals, constraints, acceptance criteria, and unresolved questions, and it's easier to review than requirements scattered across dozens of conversation turns.

But please don't mistake formal solemnity for a methodological breakthrough. Adding three files named requirements.md, design.md, and tasks.md to a prompt doesn't automatically increase the credibility of the facts within; renaming "prompt" to "spec" won't suddenly grant the model business judgment.

At this level, planning-with-files is often more honest and more practical. task_plan.md answers what to do next, findings.md saves evidence-backed discoveries, progress.md records what has already been done. They are explicitly task status, not pretending to be the system's permanent truth; they can be archived or deleted after the task ends, and they don't require the team to build a second model for the entire codebase.

This approach is particularly suitable for legacy projects because investigation conclusions change with evidence. Plans can be changed, candidate hypotheses can be overturned, and incorrect context can be discarded. It acknowledges that the model is working, rather than pretending the model has already mastered the requirements.

Of course, planning-with-files is not a universal replacement for SDD either. It solves the Agent's working memory and long-task recovery, not cross-team requirement confirmation, compliance auditing, or stable interface contracts. Plan files can also be missed in updates, become outdated, or even pollute subsequent context; where it wins is not that it's naturally more correct, nor simply that it has "fewer files," but that its responsibilities are narrower, its lifecycle is clearer, and its exit mechanism is more explicit. Even if it decays, the impact radius is usually limited to a single task.

If the Spec is a Traditional R&D Artifact, It's Mostly Just a Repackaged PRD

If a Spec is meant to exist long-term, be reviewed jointly by product and engineering, and define business behavior and acceptance criteria, then it has already entered the responsibility scope of a PRD or requirements specification. If it records technical solutions and key trade-offs, that's a design document or ADR; if it constrains interfaces, that's OpenAPI, Protobuf, JSON Schema, or type definitions; if it defines verifiable behavior, that's automated tests or contract tests.

SDD hasn't created a missing artifact out of thin air. What it more often does is repackage these existing artifacts and additionally require an Agent-friendly Markdown projection.

So the question arises: Who is this Spec actually for?

Trying to serve three types of readers with the same Markdown file usually results in a product that barely satisfies all three. A document without a clear reader is not shared knowledge, but a shared burden.

3. "Single Source of Truth" Most Easily Creates Multiple Sources of Truth

A mature codebase already contains many knowledge carriers: PRDs describe product intent, ADRs record architectural decisions, code embodies the current implementation, tests protect certain behaviors, Schemas constrain boundaries, monitoring and logs reflect runtime facts, Issues and Git history explain the reasons for changes.

After SDD adds another set of long-term Specs, it doesn't automatically replace any of the above. The reality is more likely to turn six materials into seven. Every change requires judging which files to update and bearing the risk of missing an update to one of them.

The so-called "consistency" cannot be solved by letting the Agent automatically maintain it, because this creates a circular argument:

  1. We need Specs because there is an understanding gap between code and requirements.
  2. Manually maintained Specs easily fall out of sync with code, so some hope to let the Agent automatically generate or maintain them.
  3. But if the Agent is simultaneously responsible for understanding code, maintaining Specs, and then modifying code based on Specs, then the Spec is merely an intermediate product of the Agent's own judgment and cannot serve as independent evidence.

Once the first round of understanding is wrong, the error will self-reinforce between the Spec and the code. Documentation may not be independent evidence; it could just be the sediment of the model's last inference; yet the next round, the model will treat it as a high-priority instruction. Ordinary outdated documentation might be suspected by engineers, but outdated Specs wearing the "Source of Truth" badge are even more dangerous.

SDD's standard answer is "humans must review at each stage." This is certainly necessary, but it also precisely exposes that the cost hasn't disappeared: the model is responsible for mass-producing documents, and humans are responsible for verifying facts item by item. When generation becomes cheaper, review becomes the bottleneck. If a team originally lacked the capability to continuously maintain PRDs, design documents, and tests, adding another Spec layer requiring even higher-frequency synchronization won't magically create governance capability.

This is context decay: incorrect information gains authority through repeated citation, and the model generates increasingly complete, increasingly self-consistent implementations based on wrong premises. Code can at least be refuted by compilers, type systems, tests, and online behavior; natural language Specs often can't even have their "completeness" judged by machines.

SDD often calls natural language Specs "executable specifications," a term that also warrants caution. As long as the path from Spec to code still goes through a probabilistic model, it is not an executable specification in the traditional sense, but a re-interpretable specification. The same input may generate different implementations, miss the same constraint, or even make opposite choices in different contexts. The truly executable parts ultimately still come from tests, Schemas, compilers, model checkers, and runtime verification, not from Markdown heading levels.

4. Legacy Projects Are Not Fertile Ground for SDD, But Its Most Dangerous Stress Test

The difficulty with legacy projects has never been "not having a long enough description," but that existing materials contradict each other. Code may implement old requirements, tests may protect accidental behavior, comments may not have been updated in three years, online configurations may change actual paths, and old colleagues remember exception rules from some past incident.

At this point, letting the Agent reverse-generate a Spec first encounters a problem that cannot be solved by syntax: Is it generating business intent, or current behavior?

Reverse-engineering from code can only yield an approximate description of the current implementation, unable to determine which parts are business rules, which are bugs, which are temporary compatibilities, and which are dead branches no one dares to delete. Organizing this content into a beautifully formatted Spec easily accomplishes a "cognitive whitewashing": historically questionable accidents are renamed as formal requirements.

If you require filling in the Spec for the entire project first, the cost approaches re-understanding the entire system. For hundreds of thousands of lines of code, multiple upstream and downstream systems, complex feature flags, and implicit operational rules, this is not "supplementing documentation," but a digital archaeology expedition with no clear return. Worse, the day it's completed is the first day it begins to expire.

Here, a common criticism also needs fair correction: Currently, OpenSpec explicitly does not require filling in all Specs for legacy code at once. It advocates starting to write deltas from ongoing changes and merging increments into openspec/specs/ upon archiving, allowing the main Spec to grow gradually with changes. It even directly warns that large-scale backfilling will produce outdated Specs that no one trusts.

This is much more realistic than "finish writing the encyclopedia for the legacy system before starting work," but it doesn't eliminate the core contradiction, only changes its form:

So, OpenSpec's delta-first approach is a decent change organization strategy, but it's insufficient to prove that a long-term unified Spec can become the source of truth. Partial increments solve the entry cost, but not authority, coverage, or truthfulness.

What legacy projects truly need is evidence engineering: first fix the business goals, then trace the chain along production, transmission, consumption, and user-observable behavior; cross-validate using runtime results, logs, Git history, existing tests, and owner confirmation. Investigation conclusions should maintain a temporary status before obtaining evidence, rather than being hastily promoted to Specs.

5. New Projects Aren't Necessarily Suitable Either: When Uncertainty Is Highest, Documentation Depreciates Fastest

SDD demonstrations favor new projects because generating a Todo App from scratch most easily appears to have a complete process. In reality, new projects are often in another state: the problem hasn't been precisely identified, user feedback is insufficient, the technical route is unverified, prototypes can be overturned at any time, and product decisions change weekly.

At this time, the most important thing is low-cost trial and error, not producing a set of seemingly complete requirements, design, and task documents as early as possible. Models are particularly good at expanding vague ideas into complete texts, an ability that easily creates the illusion of "having already thought it through." Sixteen acceptance criteria don't mean the requirements are more mature; they might just mean the model is more capable of writing.

If a decision is highly likely to change next week, writing a proposal, spec, design, and tasks for it today, then synchronizing the main Spec after implementation, yields not rigor, but a document turnover tax. Teams will ultimately head toward one of two outcomes: maintain it seriously, and speed is dragged down by the process; stop maintaining it, and the Spec quickly loses credibility.

This is also SDD's awkward zone:

SDD certainly has applicable areas, but this area is far narrower than the promotional rhetoric claims.

6. More Markdown Doesn't Equal More Control

SDD tools like to create a sense of order using templates, checklists, stages, and traceability relationships. The problem is that increasing the number of files increases visible output, not necessarily effective control.

Every piece of AI-generated documentation needs human review. Reviewers must not only judge whether it reads coherently but also check whether it is faithful to the business, whether it duplicates existing capabilities, and whether it is consistent with code facts. Reading a fluent but implicitly flawed long text is often more tiring than reviewing a piece of runnable code, because natural language has no compilation errors, only ambiguities missed by people.

Birgitta Böckeler's evaluation after trying Kiro and spec-kit was quite direct: neither is suitable for most real coding problems; a small bug was expanded into four user stories and sixteen acceptance criteria; an ordinary feature generated a large amount of repetitive Markdown, and the time spent reviewing these files was enough to complete the implementation directly. She also observed the Agent mistaking "investigation notes on existing classes" for new requirements and generating a batch of duplicate classes.

This precisely illustrates a counter-intuitive fact: More formal context doesn't mean the model is more obedient; more context doesn't mean the model understands better. Large context windows increase the amount of information that can be input, but not the truthfulness of each piece of information, nor do they guarantee the model will correctly handle conflicts. Templates can standardize output shapes but cannot replace factual investigation.

SDD's most dangerous side effect is not writing a few documents no one reads, but creating a false sense of control. The team sees a complete directory, checkboxes, and a requirements traceability matrix, and mistakenly believes the risks have been managed. In reality, the risks may have just been moved from code into natural language that is harder to verify.

7. What's Truly Worth Long-Term Maintenance Is Not a "Unified Spec," But a Small Number of High-Value Facts

Software projects do contain some content that should not drift arbitrarily with tasks: architectural boundaries, data ownership, compatibility commitments, security constraints, compliance requirements, irreversible technical choices. This content should be intentionally maintained, but should not be mixed into an infinitely expanding unified Spec.

A more prudent approach is to split knowledge by lifecycle and verification method:

Content Suitable Carrier Reason
Current task goals, plans, findings, progress planning-with-files or similar task files Serves current execution, recoverable, deletable, doesn't pretend to be permanent truth
Product goals and acceptance boundaries PRD, Issue, User Story Has a clear business Owner, allowed to evolve with product decisions
Important, long-term technical decisions ADR Records background, choices, costs, and alternatives, emphasizing "why"
API, data, and cross-service contracts OpenAPI, Protobuf, Schema, Types Can be parsed, validated, and generated by tools
Stable business behavior Automated tests, Contract tests, Examples Executable, gives clear feedback on failure
Current implementation and real call chains Code, runtime results, Logs, Tracing Used to prove what the system actually does now
Temporary assumptions and exploration conclusions Conversations, Drafts, findings.md Retains revocability when evidence is insufficient

ADRs are particularly important because large models have limited understanding of business, and many key decisions cannot be recovered from code alone. Code can tell a newcomer "event-driven is used now," but may not tell them "the synchronous solution was rejected due to cross-region timeouts"; such reasons deserve long-term preservation with a high barrier to entry.

Conversely, information that can be stably recovered from code, types, or generated configurations doesn't need to be manually copied again. The value of documentation lies not in coverage area, but in preserving knowledge that is important, stable, and cannot be reliably deduced from the current state.

8. When SDD Can Be Used

Criticizing the misuse of SDD does not mean no Spec should ever be written. The following types of scenarios may warrant adopting lightweight or varying degrees of SDD:

Even in these scenarios, three questions should be answered first: What is the sole responsibility of this Spec, who is responsible for maintaining it, and how is it verified? If you can't answer them, don't create it yet.

A simple adoption principle is: Short-term information goes into task context, long-term decisions go into ADRs, executable constraints go into tests and Schemas, and product intent stays with a requirement system that has an Owner. Don't let Markdown take over software engineering just because AI likes Markdown.

Conclusion: SDD's Biggest Problem Is Substituting "Write Clearly" with "Write Completely"

Writing clearly is certainly important, but clarity does not equal verbosity, structure does not equal truth, versioning does not equal someone maintaining it, and "Source of Truth" does not equal the truth actually residing there.

For most projects, especially legacy projects, SDD easily becomes a document expansion movement: turning Prompts into Specs, treating Specs as PRDs, treating PRDs as superiors to code, and then letting the Agent maintain consistency among them. In the end, the team maintains an extra set of documents whose reader, boundaries, and authority no one can articulate, while the Agent gets an outdated document with more directive power than ordinary old documentation.

This is not a victory for context engineering, but the institutionalization of context decay.

Good context engineering pursues: what facts the current task needs, where the evidence is, which conclusions are still revocable, and when to forget. Good traditional engineering artifacts pursue: who owns it, what decision it serves, how to verify it, and when it expires. If SDD cannot answer these questions, it is just an expensive layer of medium stuck between the two.

Specs can be tools, but should not become a religion. For legacy projects, investigate facts first, then record decisions; verify behavior first, then talk about unified truth. Otherwise, what you get is not specification-driven development, but specification-driven delusion.

References

  1. Birgitta Böckeler, Understanding Spec-Driven-Development: Kiro, spec-kit, and Tessl, 2025-10-15.
  2. GitHub spec-kit, Specification-Driven Development.
  3. OpenSpec, Core Concepts.
  4. OpenSpec, Using OpenSpec in an Existing Project.