{"slug": "why-you-should-not-commit-your-specs", "title": "Why You Should Not Commit Your Specs", "summary": "A developer argues that AI-assisted Spec Driven Development spec files should not be committed to a codebase once the code is implemented, since the code itself becomes the unambiguous source of truth. The post surveys popular SDD frameworks and groups them by spec lifecycle: deleted after implementation, kept but stale, or kept and continuously updated. The developer contends that committing specs duplicates information, creates competing sources of truth, and adds maintenance burden, and that intent is better captured in README and other markdown files.", "body_md": "**Disclaimer**\n\nWhen I say \"specs\" in this article I mean specs as understood in AI assisted Spec Driven Development: markdown files that describe a change before an LLM implements it.\n\nI am NOT talking about OpenAPI, AsyncAPI or similar formats, and I am not talking about README-style documentation that describes what a system does today.\n\nSoftware development today is in constant change. It feels like every month there is a \"new\" development method or idea.\n\nSome of these ideas are gone within a month or two, others stick around for longer.\n\nSpec Driven Development (SDD) is one of the ideas that has gotten some traction and is making its way into the mainstream. The idea is not new, but it has been redefined, and when I talk about SDD I only mean its current incarnation:\n\nBefore writing any code, write a specification. Then use the spec as an input for an LLM and let it produce the code.\n\nThe spec is usually one or more markdown files with a detailed description of what should be done, created by the developer together with an LLM.\n\nIn this post I will look at how popular SDD frameworks implement this idea, with a focus on one thing: what happens to the spec files after the code is written.\n\nBefore SDD had a name, we called this a \"plan\": write the change down, refine it with the LLM until you both agree, let it implement, review the result.\n\nEvery SDD framework I have tried follows that same pattern. Where they differ is one question:\n\n**What happens to the spec once the code is written?**\n\nIf we focus just on the lifecycle of the spec file itself, we can group them into three different groups, with different approaches:\n\n**Deleted** — not committed, or removed after implementation.\n\n**Kept and stale** — committed, but frozen in time. It describes what was true on the day it was written. Moving it into an `archive/` folder is a slightly cleaner version of this, but it is the same category.\n\n**Kept and updated** — committed and kept in sync with the code. The specs always describe the system as it is today.\n\nSome frameworks also use a hybrid approach where some high level specs are always updated and some — usually the 'feature branch' specs — are discarded or archived.\n\nAll of this is nuance about *which* specs to keep. It assumes we have already agreed that some specs should be kept at all.\n\nTo me this feels like we jumped two steps ahead, instead of answering a simple question first:\n\n**Should we commit these specs? Or should we throw them away once the code is implemented?**\n\nIf you have read the title of this article then you probably already guessed my take on this.\n\nEnglish, like every natural language, is ambiguous by nature.\n\nFor example, what does \"bi-weekly\" mean? Does it mean twice a week? Or every two weeks?\n\nThe answer is: **yes**.\n\nBefore the code exists, that ambiguity is unavoidable. But once the code is written, we have an unambiguous description of the feature: **the code**.\n\nProgramming languages can be read by humans and machines alike, and they are by nature much more precise than English, since they have to follow a strict syntax to be valid.\n\nCommitting the spec next to the code means keeping an ambiguous description of *what* something does, next to a precise one.\n\nPeople will say that specs capture the intent behind a change better than the code does, and I agree. Sometimes it is hard to tell from the code alone why it exists.\n\nBut that is not a reason to commit the spec. We already have plenty of places for intent that live close to the code:\n\n`README.md` and other markdown files that give humans and LLMs the required context\nOnce the spec is implemented, most of it repeats what is already obvious from the code.\n\nWhy maintain something that becomes a burden the moment it is implemented? Why keep the same information twice inside the codebase?\n\nDuplication also means competing sources of truth. If the code says one thing and the spec says another, who decides what is correct?\n\nI recently tried out 3 popular SDD frameworks ([Spec Kit](https://github.com/github/spec-kit), [OpenSpec](https://github.com/Fission-AI/OpenSpec), [BMad Method](https://github.com/bmad-code-org/BMAD-METHOD)), gave them the same starting prompt to add a feature and followed their suggested workflow.\n\nHere are the lines of markdown each one created for that single feature, not counting the one-time project setup files:\n\n| Framework | Lines of markdown | \n|---|---|\n| Spec Kit | 841 | \n| OpenSpec | 540 | \n| BMad Method | 1,773 | \n\nAre we still pretending to read all these files?\n\nTo me a spec has one purpose: to make sure the LLM and the developer share an understanding of what needs to be built.\n\nOnce the LLM has 'translated' this shared understanding into code, and the developer has verified its output, the spec loses its value.\n\nCommitting the spec also means committing it to the pull request. 1,773 lines of markdown on top of the actual change leaves the reviewer with two options: skip it, or invest their time actually reading it.\n\nIf every feature that gets implemented leaves behind some type of artifact, these artifacts will start to be outdated quickly.\n\nThis will also lead to problems with LLMs: they will inevitably grep one of these files and then get confused as to why the spec is different from the code.\n\nMost models are trained to be careful, so they will burn tokens trying to figure out whether the spec is stale or the code is wrong.\n\nTo prevent this from happening some SDD frameworks keep a high level 'living spec' besides these outdated 'frozen in time' specs. The user is then [advised to keep these 'living specs' in sync](https://github.com/bmad-code-org/BMAD-METHOD/discussions/1838).\n\nBut keeping the living spec in sync requires its own set of tools and effort (aka tokens).\n\nThere is also an underlying notion that suggests that the spec is the source of truth and that the code is just the disposable output.\n\nThe specification becomes the primary artifact engineers maintain, and code becomes a derived, regenerable output that AI agents produce from that spec on demand.\n\nThe idea is that if you were to delete the whole code of your software system, you could simply regenerate it from your specs.\n\nThat notion led Elon Musk to the stupidest take of the year:\n\nThings will move, maybe even by the end of this year, to where you don't even bother doing coding. The AI just creates the binary directly. And the AI can create a much more efficient binary than can be done by any compiler.\n\n— Elon Musk, xAI all-hands, February 10, 2026 ([video at 11:30](https://www.youtube.com/watch?v=HD_SiJDWPcQ&t=690s), [original post by xAI](https://x.com/xai/status/2021667200885829667))\n\nGreat idea. Why generate something both machines and humans understand, when you could generate something only machines understand?\n\nBack to regenerating source code from specs. My main question is simply: **Why?**\n\nWhy would anyone want to regenerate their entire codebase from specs? To switch stacks or languages? Why not use the code and tests you already have? That is exactly [what the Bun team did earlier this year when they ported Bun from Zig to Rust](https://bun.com/blog/bun-in-rust).\n\nI truly don't get it, but maybe I am missing the point.\n\nI am NOT a fan of committing specs (as SDD understands them) into the codebase.\n\nI am fine with committing the spec while working on the feature, as long as it is deleted before the PR is created. That way it stays in the git history without ending up in the codebase.\n\nInstead of committing your specs, here is what I would do:\n\n**Throw the spec away** once the code is merged, or keep it in git history only.\n\n**Make the intent obvious from the code.** If that is not possible, add documentation via concise, information-dense markdown files that explain why, not what.\n\n**Make sure your repositories need no external context.** A new dev should be able to start working on your project without the help of another dev.\n\n**Don't cram everything into a central `README.md`.** For example, have a separate markdown file for testing or deployment. High-level markdown files that describe non-obvious features are fine too.", "url": "https://wpnews.pro/news/why-you-should-not-commit-your-specs", "canonical_source": "https://dev.to/carstenbehrens/why-you-should-not-commit-your-specs-440g", "published_at": "2026-09-18 18:57:21+00:00", "updated_at": "2026-09-18 19:22:59.472090+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "ai-tools", "large-language-models"], "entities": [], "alternates": {"html": "https://wpnews.pro/news/why-you-should-not-commit-your-specs", "markdown": "https://wpnews.pro/news/why-you-should-not-commit-your-specs.md", "text": "https://wpnews.pro/news/why-you-should-not-commit-your-specs.txt", "jsonld": "https://wpnews.pro/news/why-you-should-not-commit-your-specs.jsonld"}}