Keeping Specs Alive
A committed spec that disagrees with the code is worse than no spec: every agent session will diligently implement the wrong world. Keeping specs alive is not documentation hygiene — it is preventing spec-code drift from becoming executable misinformation. See Specs over Prompts for why the spec layer exists; this page is the maintenance loop.
The feedback loop
Three honest outcomes when they disagree:
| Situation | Action | Anti-pattern |
|---|---|---|
| Spec right, code wrong | Fix code (or reject PR) | Patching code while leaving a lying acceptance criterion |
| Code right, spec stale | Amend spec in the same PR | "We'll update docs later" — later never comes; next agent reverts your fix |
| Neither matches product intent | Stop implementation; re-decide; rewrite spec first | Prompting the agent to "make it work" against a confused spec |
When to update the spec
Update in the same change that alters behavior — not in a follow-up chore.
| Trigger | Spec action |
|---|---|
| New acceptance criterion discovered mid-build | Add it before or with the implementation PR |
| Product owner changes scope | Amend non-goals / acceptance; re-plan remaining work |
| Bug fix reveals unspecified edge case | Add the case to acceptance + a test; don't leave it tribal |
| Deliberate behavior change | Rewrite the relevant section; mark superseded bullets |
| Implementation chose among allowed options | Record the choice under "Decisions" so the next agent doesn't re-pick |
| Feature abandoned or replaced | Mark spec Status: superseded by specs/0xx-... — don't delete history blindly |
Do not update for pure refactors that preserve behavior — unless the spec described a structure that no longer exists (paths, module names). Then fix paths only.
Lightweight ownership
| Role | Responsibility |
|---|---|
| Author of the behavior change | Spec diff in the same PR |
| Reviewer | Pass 1 of three-pass review includes spec sync |
| Agent | May draft spec amendments; must not silently diverge |
Put one line in CLAUDE.md:
If implementation changes user-visible or API behavior, update the relevant
file under specs/ in the same PR. If the spec is wrong, stop and propose an
amendment before coding further.PR checklist — spec sync
Copy into PR templates (Templates: Checklists):
## Spec sync
- [ ] Behavior change? → linked spec path(s) updated in this PR
- [ ] Acceptance criteria still match what QA/humans will verify
- [ ] Non-goals still true (no silent scope expansion)
- [ ] New edge cases from review added to spec + tests
- [ ] If no spec exists for this behavior: create one or justify why (chore/refactor only)
- [ ] Stale path/module references in spec fixedDetecting drift early
| Signal | Detection | Response |
|---|---|---|
| Agent "implements the spec" but product disagrees | Human acceptance fails | Spec was wrong or incomplete — amend, don't only patch code |
| Two specs describe the same feature differently | rg across specs/ for the feature name | Merge/supersede; leave one canonical |
| Tests assert behavior not in spec | Reviewing AI tests | Either under-specified feature or rogue test — reconcile |
| Spec cites files that don't exist | Link checker or review grep | Update paths after moves |
| Agent re-introduces removed behavior | Characterization + spec non-goals | Non-goal wasn't written; add it |
Agents will not notice drift on their own if both artifacts are in context and conflict — they often blend them. Your job is to keep one intended story.
Weak vs strong maintenance prompts
Weak:
Update the docs if needed.Strong:
Behavior changed in this PR: <one-sentence summary>.
1. Diff specs/<id>-<name>.md against the new behavior.
2. Propose a minimal spec patch (acceptance criteria, non-goals, decisions).
3. Stop for approval before editing code further.
4. After approval, apply spec + code/tests in one coherent change.
5. List any other specs that mention <feature> and whether they need edits.Cadence beyond PRs
| Cadence | Action |
|---|---|
| Per PR | Spec sync checklist above |
| End of epic | Skim all epic specs for Status, supersession, and orphan acceptance criteria |
| After incident | If production behavior was undefined, add it to spec + test before the next agent touches the area |
| Quarterly | Kill zombie specs (shipped-and-forgotten with wrong paths) |
Failure modes
| Symptom | Root cause | Fix |
|---|---|---|
| Every session rewrites billing rules differently | Spec missing or ignored | Write/repair spec; point prompts at it |
| Spec updated weeks after code | "Docs later" culture | Block merge on checklist; make author responsible |
| Spec is a novel; nobody reads it | Overwriting | Compress to acceptance + non-goals; move essays out |
| Agent implements deleted requirements | Superseded spec still linked from CLAUDE.md or PLAN | Fix pointers; mark superseded |
For writing quality on new specs, see Writing Effective Specs and Spec Examples.
Related
- Specs over Prompts — why the durable layer exists.
- Writing Effective Specs — structure that stays maintainable.
- Prompts vs Specs — escalation rule from chat to files.
- Reviewing AI PRs — pass 1 catches drift.
- Docs as Memory — same loop for architecture docs and ADRs.