How to Describe Code Changes Without Rewriting the Spec Every Time
Specs go stale because updating them is painful. You change a behavior. The spec for that behavior lives in a long markdown file. You would have to rewrite half of it to reflect the change. You skip the update. Six months later, the spec contradicts the code. The next developer trusts the spec. They ship a bug.
The fix is not more discipline. The fix is a spec format that lets you describe changes without rewriting.
What a delta is
A delta is a document that describes changes to your system using three sections.
ADDED. New behavior that does not exist yet. When the delta archives, these get appended to the main spec.
MODIFIED. Existing behavior that is changing. When the delta archives, these replace the existing version.
REMOVED. Behavior being deprecated. When the delta archives, these get deleted from the main spec.
You never rewrite the main spec during a change. You write the delta. The archive step applies the delta to the main spec mechanically.
A concrete example
You are adding two-factor authentication to an existing login system.
Under ADDED, you specify: "The system MUST support TOTP-based two-factor authentication." With scenarios for enrollment (user enables 2FA, gets a QR code) and login (user submits credentials, gets an OTP challenge).
Under MODIFIED, you change the session timeout. "The system MUST expire sessions after fifteen minutes of inactivity." With a note that it was previously thirty minutes. This replaces the old requirement.
Under REMOVED, you note: "Remember Me feature deprecated in favor of 2FA. Users should re-authenticate each session."
The main spec is untouched during the change. The delta captures exactly what is moving. When you archive, the main spec absorbs the changes. Three lines added. One line modified. One line removed. The main spec is now current.
Why deltas beat full rewrites
Four reasons.
Clarity. A delta shows exactly what is changing. Reading a full spec, you have to mentally diff it against the current version to spot the differences. With a delta, the diff is the document.
Conflict avoidance. Two changes can touch the same spec file without conflicting, as long as they modify different requirements. The changes live in separate delta folders. They archive independently. Parallel work becomes possible.
Review efficiency. Reviewers see only the change, not unchanged context. A spec change that adds three lines reviews in minutes. A full-spec rewrite of the same change reviews in an hour because the reviewer has to find the three lines.
Brownfield fit. Most development modifies existing behavior. Deltas make modification a first-class concept. The spec layer works for new code and for changes to old code, without a format difference.
What happens at archive
The archive step is mechanical.
ADDED requirements append to the main spec.
MODIFIED requirements replace the existing version.
REMOVED requirements delete.
The change folder moves to archive with a date prefix. The full context of the change (proposal, design, tasks, delta) is preserved.
This creates a virtuous cycle. Specs describe current behavior. Changes propose modifications as deltas. Implementation makes them real. Archive merges them back. Each cycle builds on the last. The spec directory grows organically, always reflecting what the system actually does today.
Specs describe behavior, not implementation
A common mistake is putting implementation details in specs.
Good spec content: inputs, outputs, error conditions, external constraints. Things you can observe from outside the system.
Bad spec content: internal class names, library choices, step-by-step implementation plans. Those belong in the design document.
The quick test: if the implementation can change without changing externally visible behavior, the change probably does not belong in the spec. React Context versus Redux is an implementation choice. "The system SHALL allow theme switching" is behavior. The behavior goes in the spec. The choice goes in design.
When you get this separation right, deltas work cleanly. Implementation churns. Specs stay stable. Deltas reflect behavior changes only. The main spec evolves slowly, in the right direction.
The pattern that earns its keep
Most teams adopting deltas make the same mistake. They try to delta everything, including brand-new features. New features do not need deltas. They need new specs.
Deltas are for modifications to existing behavior. A brand-new subsystem is just a new spec file. Write it once. Move on.
The discipline is recognizing which kind of work you are doing. New behavior. Write a new spec. Modified behavior. Write a delta. Removed behavior. Write a removal delta.
Mixing these up produces confused artifacts. A new spec written as a delta is awkward because there is nothing to modify. A modification written as a new spec duplicates the existing spec and creates ambiguity about which is authoritative.
When deltas are overkill
For a project with one developer and no plans to grow, deltas are overhead. The developer knows what changed. The spec is for them. They update it directly.
For experimental code that will be thrown away, deltas are overhead. The spec will not survive the experiment.
For code where the behavior is trivially observable from the code itself (a one-function utility, a config file), deltas are overhead. Just read the code.
Deltas earn their keep on code that lives long enough for the spec to drift from the code, and complex enough that reading the code is harder than reading the spec. Most production code is in this category. Most prototypes are not.
The smallest test
Take the next change you are about to make. Write it as a delta. Three sections: ADDED, MODIFIED, REMOVED. Even if some sections are empty.
If the delta captures the change clearly, the format works for you. If you find yourself wanting to write a full new spec, the change is bigger than a delta should be, and the spec format is telling you something.
Recommended for you
- WorkflowSuperpowersClaude Code
Why Your Agent Starts Coding Before You Finish Talking
You give the agent a one-sentence task. It immediately writes code. The code is plausible. It is also not what you wanted. The discipline teams skip first: brainstorm before code, no exceptions.
- WorkflowSuperpowersClaude Code
Why Your Agent Forgets Step 5 by Step 12
A ten-task plan drifts by task four. The model is not forgetful. The plan is too coarse. Tasks that look discrete to you blur together in execution. Smaller tasks with sharper edges fix it.
- WorkflowSuperpowersClaude Code
The Discipline Stack That Makes Agent Output Trustworthy
The reliability problem is not the model. It is the missing disciplines around the model. Brainstorm before code. Plan before implement. Test before pass. Verify before claim. Review before merge.
- WorkflowSuperpowersClaude Code
Why Your Multi-Agent Workflow Keeps Colliding
Two agents in two threads share the filesystem but not context. They make decisions based on stale state. The fix is one fresh agent per task with isolated context.
Enjoyed this article?
Subscribe for new articles. No spam. Unsubscribe anytime.
By subscribing you agree to receive the newsletter. See the Privacy page.