Back to blog
Workflow
OpenSpec
Claude Code

How to Describe Code Changes Without Rewriting the Spec Every Time

Thang Doan
Thang Doan

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

Enjoyed this article?

Subscribe for new articles. No spam. Unsubscribe anytime.

By subscribing you agree to receive the newsletter. See the Privacy page.