One Claude Code Tip a Day: Keep a Rollback Note Beside the Diff

Make Claude Code keep a rollback note next to the git diff: what changed, how to undo it, what proof is missing, and when to revert instead of piling on fixes.

Abstract code review workstation with git diff and rollback checklist

This post is part of the “One Claude Code Tip a Day” series — a daily guide to using Claude Code more effectively.

The real failure: a good patch with no way back

Claude Code is useful enough that the dangerous moment often arrives after the first patch looks reasonable. Imagine a production checkout bug: discounts are sometimes double-counted after a pricing refactor. You ask Claude to inspect the code, it finds a shared formatter, updates a helper, adjusts two tests, and the focused test passes. Then a reviewer notices that invoice PDFs may use the same helper. The code is not obviously wrong, but the session has lost something important: a clean way to back out or narrow the blast radius.

Today’s habit is to make Claude Code keep a rollback note beside the diff. This is not a ceremony for huge migrations. It is a small checkpoint for everyday risky edits: anything touching authentication, payments, migrations, shared UI, feature flags, deploy scripts, or data transformation. The rollback note turns “looks good” into “we know how to undo this safely if the evidence gets worse.”

Start with a reversible edit contract

Before Claude edits, give it two jobs: make the smallest change and preserve the exit route. A strong prompt sounds like this:

`We need to fix a possible double discount in checkout totals. Read the pricing path first. Before editing, name the smallest file boundary, the focused test to run, and a rollback note: which files would need to be reverted if the hypothesis is wrong. Do not edit until the rollback note is explicit.`

This changes the session. Claude Code has to state the hypothesis, the proof command, and the undo surface before it touches files. If it proposes changing a shared money formatter, you can ask why a route-level mapping or feature-flagged branch is not safer. If it says “revert the commit” without naming files, the rollback note is too vague.

Use git diff as the notebook, not the finish line

After the first edit, do not ask “is it fixed?” Ask Claude to bind the diff to evidence:

`Show git diff. For each changed file, add one line to the rollback note: why this file changed, what test or log proves it was needed, and what would break if we reverted only this file. Then run the focused checkout total test.`

A useful answer might say that `apps/web/src/routes/checkout.tsx` now maps `discountCents` once, `apps/web/src/lib/pricing.ts` is unchanged, and `checkout-total.spec.ts` proves the displayed total. That is reviewable. A weak answer says the diff “improves discount handling” and lists a passing test without connecting the test to the changed file.

A realistic second-pass correction

Suppose the focused test passes, but the browser check fails on mobile because the drawer uses a separate summary component. The wrong move is to say “fix mobile too” and let the session expand. The rollback-note move is narrower:

`The desktop checkout test passed, but mobile still shows the old total. Do not edit yet. Re-read the rollback note and the current diff. Explain whether the first patch is still necessary, which mobile file is outside the original boundary, and whether we should extend the patch or revert and choose a different seam.`

This prompt forces Claude Code to treat the failed verification as new evidence, not permission to sprawl. It may discover that the route-level mapping is still the right seam and the mobile drawer receives stale props from the same parent. Or it may discover that the first patch fixed only a desktop adapter and should be reverted before touching the shared pricing layer. Either way, the session stays inspectable.

What a good rollback note contains

Keep it short. Four bullets are enough. First, the hypothesis: “discount is applied twice because the checkout route maps API discount and the summary recalculates it.” Second, the changed files and why each one changed. Third, the proof already run: test names, command output, browser path, or log line. Fourth, the revert rule: “if invoice totals change, revert `checkout.tsx` and rerun the invoice fixture before trying a shared helper patch.”

You can ask Claude to maintain that note in the chat instead of committing it. For larger work, put it in the pull request description. The important part is not where the note lives. The important part is that the model must keep track of reversibility while it is still making decisions.

Failure modes

The first failure mode is writing a rollback note after everything is already tangled. By then it becomes a story, not a control. Ask for it before the first edit and update it after each verification step.

The second failure mode is confusing rollback with fear. Reversibility does not mean never touching shared code. It means shared code needs stronger proof: broader tests, fixtures from more consumers, and a clear reason the narrow seam is insufficient.

The third failure mode is letting Claude use the note as a substitute for `git diff`. Always inspect the actual diff. The note should explain the diff; it should not hide it.

Rule of thumb

Use a rollback note whenever a Claude Code edit could be correct locally and still risky globally. Make Claude name the undo surface before editing, connect every changed file to proof, and use failed verification to decide whether to extend, correct, or revert. The best sessions do not just move forward quickly; they keep a clean path back until the evidence earns the next step.