Max Narditdata & ai systems
← Articles
8 mindev

Spec-driven development with AI agents: Spec Kit's own repository ignores its specs

Keeping a spec after the session is the cheap part. A spec earns its keep at delivery, as the one artifact a person read and corrected before any code existed. After the merge it is a document nothing runs on its own, and the honest choices are to mark it as history, to keep a check pointed at it, or to move what must last into the constitution and the tests, which is the choice Spec Kit's documentation describes for its own repository.

Contents

GitHub’s announcement of Spec Kit put the promise of spec-driven development in one line: “We’re moving from ‘code is the source of truth’ to ‘intent is the source of truth.’” Write the spec first, let the coding agent plan and build from it, and keep the spec as the thing everyone checks the code against. The spec, in that telling, is the part of an agent session that survives the session.

Then look at what Spec Kit keeps in its own repository. Its .gitignore lists specs/, the directory where every feature spec, plan and task list lands, and the project’s documentation says this is deliberate:

Spec Kit's own repository illustrates this choice: it tracks
`.specify/memory/constitution.md`, while `specs/` is gitignored and
feature artifacts are not tracked.

The constitution, the project-wide rules, stays in version control. The feature specs stay out of it. The same page is careful to add that excluding them “does not establish whether they are deleted or archived”, and I’ll take it at its word: they may well sit in a pull request or on someone’s disk. What they are not is part of the repository the next contributor clones.

The documentation calls this choice “constitution-only” and offers it as one of four ways to treat a spec after delivery, none of them the default. I think it tells you more about spec-driven development than the announcement does. A spec does outlive the session that wrote it, and that turns out to be the cheap part. A spec is worth the most at delivery, as the one artifact a person read and corrected before the code existed. After the merge it is a document nothing runs on its own, and such a document goes stale like any other.

Spec-driven development in Spec Kit, Kiro and Tessl: how long a spec matters

Birgitta Böckeler’s comparison of Kiro, Spec Kit and Tessl on Martin Fowler’s site, a year old now, is still the clearest map. It sorts spec-driven development by how long the spec matters:

Spec-first: A well thought-out spec is written first, and then used in
the AI-assisted development workflow for the task at hand.
Spec-anchored: The spec is kept even after the task is complete, to
continue using it for evolution and maintenance of the respective feature.
Spec-as-source: The spec is the main source file over time, and only the
spec is edited by the human, the human never touches the code.

Her finding was that the tools did spec-first and had little story past it. Kiro was “mostly spec-first”. Tessl was the only one that “explicitly aspires to a spec-anchored approach”. Spec Kit created a branch per spec, which made the spec live “for the lifetime of a change request, not the lifetime of a feature.”

Some of that has moved. In today’s Spec Kit the spec directory and the git branch are independent: specs land in numbered directories under specs/, and creating a branch is an optional hook. The persistence guide on the main branch cites her article and answers it with four models, from flow-forward, where each feature directory is an immutable record and a change gets a new one, to living spec, where you edit spec.md first and regenerate the rest. Kiro’s best-practices page, as of November 8, 2026, describes specs as “designed for continuous refinement”: you edit requirements.md or design.md, choose Sync Files on tasks.md to create tasks for the change, and can ask Kiro whether the implementation meets a task’s acceptance criteria.

So both tools now support keeping a spec and changing it. What neither does by default is notice, on its own, that an older spec and the code have drifted apart. Every check in both toolkits runs when someone starts it, usually while building the feature the spec was written for. Whether a spec outlives its session is still a team habit, and Tessl’s spec-anchored ambition was, as of Böckeler’s review, an ambition.

Spec Kit’s /speckit-converge checks the code against the spec at delivery

Where Spec Kit does give you a check is the end of a feature. Since June it ships /speckit-converge, and the minimal flow ends with it: implement, converge, repeat until convergence reports Converged. The command template says plainly what kind of check this is. It reads spec.md, plan.md and tasks.md as “the sole source of intent”, assesses the current code against them, and appends each gap as a new task. It never edits the spec. And it refuses to trust the task list’s own checkboxes:

Include every existing task in the intent inventory, regardless of
checkbox state or Convergence phase: completion claims are not evidence.

That’s the line I’d keep from the whole toolkit. A task marked done is a claim, and the code is the evidence. It’s the same instinct as watching a test fail before you trust it: a green status from the thing that did the work proves little.

It also points at the weak spot. Converge is a model reading code against a document, and the check is only as independent as the document. /speckit-specify takes a sentence, in the README’s example “Build a photo organizer with albums grouped by date and a tile preview of each album.”, and writes the spec from it. If you skim what comes back and move on, converge later compares the agent’s code with the agent’s own reading of your sentence, and when that reading is wrong the two agree. What you get is a longer, more confident restatement of what the agent already believed, and then a check that agrees with it.

What makes the spec a reference is that a person read it and accepted or corrected it, line by line, before the plan existed. That is where Böckeler’s objection lands:

To be honest, I’d rather review code than all these markdown files.

For a lot of work she’s right. My read is that the answer depends on what each artifact can show. Code shows what the system does. It can’t show what the system was supposed to refuse, or which edge cases someone decided not to handle. Those are the parts of a spec worth a reviewer’s time, so a review that only checks whether the spec “sounds right” is the same skim, only slower. Two tests decide whether a spec earns review at all: it states something the code can’t, and it is shorter than the code it governs. A spec that restates the implementation in prose fails the first; a spec for a change small enough that the diff is shorter fails the second, and in both cases reviewing the code is the better use of the hour. A spec that passes both is the cheapest place in the whole loop to catch a misread requirement, because nothing has been built on the misreading yet.

A spec-driven development spec after the merge is a document nothing runs

After delivery nothing in Spec Kit reads a spec again unless someone points a command at it. Converge works on one feature directory, and its template says it is “not a diff tool”: no git, no branch comparison, no history. Feature 003’s spec gets checked while feature 003 is built. When feature 007 changes the same code six weeks later, nothing compares that change with 003’s spec unless someone thinks to.

I have a small version of this in my own repository, outside any spec tool. This site’s multilingual design document was committed on May 2, 2026 with a status line at the top:

**Status:** Design validated, not yet implemented

The implementation landed in commits the same day. The document has had no commit since, so for six months it has stated, in a confident header, something that stopped being true within hours. It’s a plain design doc, not a spec any tool would check, and that’s the point: retained and readable is not the same as current, which is the trouble with a memory file nobody checks too.

Any agent told to treat that document as the current plan would plan against a state that no longer exists. Spec Kit has a sharper version of the same risk. If someone pointed converge at an old feature directory as if it were current intent, later work that departed from it could come back as contradicts or unrequested findings, with tasks appended to fix them. The template gives unrequested work a softer path, a task to review or justify it, and it never deletes code itself, so nothing reverts automatically. But the next implement pass would work from those tasks unless someone read them first. The Spec Kit guides see this. Flow-back’s “main risk is silent divergence”, and the evolution guide asks you not to leave a change in code “contradicting a spec that is meant to remain trustworthy”. The weight sits on “meant to”. Trustworthy is a property you keep up per spec, and the tool leaves that work to you.

Spec-driven development after delivery: mark the spec, check it, or promote it

What matters after the merge is what each spec becomes. I see three honest answers.

The first keeps the spec as history and marks it so: what was intended on this date, superseded by whatever came later. That’s Spec Kit’s flow-forward model and the older discipline of architecture decision records, which are dated, carry a status, get marked superseded and are never edited into the present. The rule that makes it safe is that no agent reads a record as present intent.

The second keeps the spec current, with something that checks it on every change that touches its feature, not only the change that wrote it. Böckeler’s definition of spec-anchored asks only that the spec be kept and used for maintenance, and a team that maintains specs by hand meets it. My stronger requirement is a check that runs without anyone remembering to run it, because a living spec kept current by good intentions decays the way the status line in my design document did.

The third retires the spec after delivery and moves what must last somewhere read every time. That’s the choice Spec Kit’s docs describe for its own repository: the constitution stays, the feature specs leave version control, and enduring knowledge lives, in the docs’ words, “in design documents, documentation, tests, and contributor guidance.” One caution about the destination. A constitution is a rules file an agent reads at the start of work, the same kind of object as a CLAUDE.md, and a rule a model only reads is weighed, not enforced. Conventions and taste belong there. Anything that must hold belongs in a test.

What happens if you decide nothing is worse than any of the three: the spec stays in the repository with no status anyone maintains, readable by every future session as if it were still the plan.

For a developer about to run specify init or open a first Kiro spec, then: decide the persistence model before the first feature and write it into the constitution, as Spec Kit’s own guide suggests. Spend the review time on spec.md before the plan exists, on the refusals and the skipped edge cases rather than the parts the code will show anyway, because that is the earliest and cheapest point where your correction reaches the agent. My design document had its moment on May 2. Everything it has said since is a status line nobody updated.

01 / Discussion

No comment section here — all discussions happen on X.

Max Nardit@mnardit

02 / More articles