How do I update a specification halfway through AI-assisted development without losing track of what was agreed?

Noor walks with a phone pressed to her ear, frowning slightly at a printed document in her other hand as she listens to a change she has not agreed to yet.

TL;DR

Halfway through a build, new information arrives and the specification has to move. Editing it in place blurs which version was approved, and starting a fresh spec leaves two that disagree. Classify the change first: clarification, changed requirement or separate feature. Then trace each changed requirement to the tasks and tests built on it, publish a numbered revision that names what it supersedes and who approved it, and review the delivered diff against that revision. Anything that traces to neither is drift.

Edit in place, or start a new spec?

Halfway through a build, someone finds a gap in the specification. Before the next line of code, decide what happens to the document: change it where it stands, or write a new one. Each choice loses something. Editing in place keeps one current document, and version control still holds the old text, but nothing marks which version was approved or why it moved. Writing a new spec keeps history but leaves two documents that disagree, and nobody can say which one wins.

Both habits have defenders. In April 2026 a Spec Kit user asked in the project's GitHub discussions how to update a spec properly in the middle of development, having been advised to stop coding when something is missing, update the spec, then write the code. One reply said a step already started should not be altered, because the alteration becomes the next specification. A project collaborator answered that it depends on how you work, and that he prefers feeding forward into a new specification, because that keeps a trace of what was missed. In December 2025 someone asked on Hacker News the reverse: when implementation diverges, should the spec be updated to match, or is the code the source of truth? They expected the answer was to update the specs, but saw engineers at their company writing new specs so often that the specs sometimes conflicted.

The agent has its own version of the problem: a Codex user reported on the OpenAI developer forum that replaced requirements lingered as extra prohibitions, which in coding projects turned into validators and regression checks nobody had asked for. That is a single unconfirmed report, but it shows why a change has to say explicitly what it replaces.

The approach in the rest of this article keeps one current specification and changes it only through numbered revisions that state what they supersede, why, and who agreed.

Sort the change before you touch the document

Most mid-build news is one of three things, and each needs different handling. The test is what happens to the acceptance criteria: would a feature that passed them yesterday still pass them after the change?

Decision guide

  • Clarification. The wording gets sharper but every acceptance criterion would pass or fail exactly as before, for example replacing "large exports" with the row limit the acceptance criterion already states. Renaming a published field is not a clarification: it changes a contract. Amend the current revision, note it in the change log and carry on.
  • Changed requirement. At least one criterion would now pass where it failed, or fail where it passed: a limit moves, a rule gains an exception, a step disappears. This is a new revision. It needs the person who approved the spec, an impact check against finished work and approval before the agent builds against it.
  • Separate feature. The new need could ship on its own, and the work done so far is still correct without it. Give it its own specification and leave the current one as agreed. Kiro's guidance, for example, recommends a separate spec for each feature rather than one for the whole codebase.

The line between the second and third is a judgement call, often a scope negotiation. If folding the new need in would delay nearly finished work, that alone justifies its own spec. When in doubt, treat a change as the heavier kind: a clarification filed as a changed requirement costs a short review, while the reverse lets a real change through unreviewed.

Illustration inside an office lift of Noor holding the door with one hand and a folder against her chest, turning toward Mira, who has a coffee cup in one hand and a laptop bag on her shoulder and waves the other hand as she mentions a new request in passing.
The first question about mid-build news is what kind of change it is.

Find the work the change touches

A changed requirement is quick to edit and slow to trace, and tracing is only practical when requirements carry stable IDs. Spec Kit's commands work with numbered functional requirements and success criteria (FR-003, SC-002), and Kiro keeps requirements, design and tasks in separate files. Ask the agent to put the ID a task or test serves into the task line, the test name or a comment, so that a search for the ID finds everything built on it.

  1. Compare the old and new revisions requirement by requirement, and mark each ID as changed, added or removed.
  2. Search tasks, tests and decision records for every changed or removed ID. Reopen each completed task it finds until someone confirms it still holds; a ticked box records that work was done against the old wording, nothing more.
  3. For a removed requirement, delete or rewrite the tests that pinned it and take it out of the agent's instruction files. OpenAI support's reply to the report above suggested checking AGENTS.md and referenced documentation for outdated requirements.
  4. Give the agent the revision and the reopened list together, and ask it to restate what is now required and what no longer is before it edits anything. Correcting the restatement is cheaper than correcting the code.
  5. Run the whole test suite, not only the new tests, because a reopened task can pass while its neighbour breaks.

The tools cover parts of this. Kiro's spec best practices say to update requirements.md, ask Kiro to update design.md, then choose Sync Files on tasks.md, which creates new tasks mapped to the new requirements; the page does not say what happens to tasks already completed against the old wording. Spec Kit's converge command, run after implementation, compares the code with the current spec, plan and tasks, treats completion claims as no evidence, flags code that contradicts or falls outside the stated intent, and appends the remaining work as new tasks. Its own definition says it is not a diff tool and keeps no history, so what changed in the spec and who agreed to it stay your record.

Write the revision so it shows what it replaced

A revision a reviewer can trust answers four questions without the chat: what changed, why, who agreed and which work it reopened. A short block at the top of the spec, or a revisions file committed beside it, is enough. The example below is an illustrative format with invented values, not output from any tool:

The hash lets anyone detect that revision 2's text changed after this revision was written. It does not stop a rewrite, because whoever can edit the file can edit the hash, so bind it to an approval record the agent cannot write, such as the approving review on the pull request that merged revision 2. Keep superseded text in version control rather than deleting its meaning: a reader who sees AC-4 at 20,000 rows should be able to find out that it was once 5,000 and why it moved. If your team approves specs in a pull request, the revision and its approval belong in the same pull request as the code that implements it. The article on keeping an AI coding agent in planning until the plan is approved lists the changes that should void an earlier approval; a changed requirement is one of them.

Illustration of Noor beside an office printer holding a marked-up page and a clean page side by side, while Ivo leans on the printer lid to see which line moved.
A revision is only useful if a reader can see what it replaced.

Check the delivery against the agreement

At review the question is narrower than whether the code is good: does every behaviour change in the diff trace to a requirement in the current revision? Each change lands in one of three places.

  • Traced to the current revision. An agreed change. Check that its test was updated to the new criterion, not just added beside the old one.
  • Traced to a superseded or removed requirement. Leftover work from an earlier agreement, like the lingering prohibitions in the Codex report. Remove it, or record a decision to keep it.
  • Traced to nothing. Drift, however sensible it looks. Either it becomes a revision with its own approval or it comes out.

A spec revision with no approval line is drift too, only in the document instead of the code. And if the work continues in a new session, give that session the current revision and its record rather than the old conversation; the article on handing unfinished work to another coding agent covers what such a handoff needs.

Paqad builds part of this into its workflow on Claude Code and Codex CLI. On its graduated and full lanes the specification is frozen before code, with a recorded sign-off. Before a covered edit, a deterministic check compares the frozen spec with the hash stored at the freeze; if the spec has moved, Paqad opens a "spec changed" decision pause that names the changed sections and blocks further edits until you update and refreeze or hold to the agreed version. The stored hash detects a change; it is not a trusted approval record, and the sign-off name is recorded rather than authenticated. The fast lane has no frozen spec, shell writes and other tools are not intercepted, and a pause says the spec moved, not which finished tasks it affects. Paqad's spec pipeline and freeze documentation describes the freeze and the pause that follows a change.

Frequently Asked Questions

Keep one current spec and change it only through numbered revisions that name what they supersede and who approved them. While a revision is being agreed, pause new work in the affected area: an agent that keeps building during the renegotiation produces code for a version nobody signed.

Apply the acceptance-criteria test from the decision block. If the person asking for the change cannot say whether a criterion moves, that is a finding in itself: the criterion is too vague, and sharpening it is the first revision.

Everything that references a changed or removed requirement ID, plus decisions that relied on it, such as a storage choice made because of a row limit. Decisions are the easiest to miss because they rarely carry an ID, so note the requirement a decision depends on at the time you make it.

Review the difference between revisions rather than the whole document, ideally with the person who approved the original. Link the revision to the reopened tasks and to the pull request that implements it, so that the chain from request to approval to code survives after the conversation is gone.

Ask the agent to add a trace table to the pull request: each behaviour change, with the requirement ID and revision it serves. Then spot-check the table against the diff. A table the agent wrote is a claim to verify, and the rows that do not match are where the review time should go.