One Claude Code Tip a Day: Name the Files You Will Not Touch

A field guide to making Claude Code declare the files it will not touch before editing, then verifying the diff against that boundary after the first patch.

Editorial illustration of an AI coding workflow with a highlighted safe edit boundary around a few files and surrounding files left untouched.

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

The failure: a small bug turns into a wide patch

A real Claude Code session can go wrong while still looking productive. You ask for a small fix: the settings drawer should keep the selected billing interval after a reload. Claude reads the React component, notices a shared preferences helper, and proposes a tidy cleanup while it is there. The patch passes a focused unit test. Then you open the diff and see three changed files that were never part of the bug: a route-level loader, a design token file, and a helper used by invoices.

That is not automatically bad code, but it is bad session control. The first patch now contains two stories: the reload bug and an opportunistic cleanup. Today's habit is simple: before Claude Code edits, make it name the files it will not touch. A no-touch boundary gives you something concrete to review after the patch lands. It turns scope from a vibe into a contract.

The workflow: define the edit boundary before the edit

Use this before the first patch, especially when the repo has shared helpers or styling layers that invite broad changes:

Prompt: `Before editing, inspect the relevant path and propose an edit boundary. List: files likely in scope, files explicitly out of scope, and the verification command. Do not edit until I approve the boundary.`

A good answer might say: in scope, `SettingsDrawer.tsx` and `billingPreferences.test.ts`; out of scope, `invoiceFormatter.ts`, `theme/tokens.ts`, and the route loader unless inspection proves persistence happens there. That answer is valuable because it names temptation. Claude Code is good at finding nearby abstractions, but nearby is not the same as necessary.

Make the no-touch list operational

The boundary should not be ceremonial. After Claude proposes it, tighten the rule:

Prompt: `Proceed with the smallest patch inside that boundary. If you discover the fix requires an out-of-scope file, stop and explain the evidence before editing it.`

This is the difference between collaboration and autopilot. Claude can still discover that the persistence bug lives in the route loader. But it must pause and show the evidence first: a read of the loader, a failing test path, or a runtime observation. You have converted surprise expansion into an explicit decision point.

For frontend bugs, I like adding one more line: `Do not change shared CSS, theme tokens, or unrelated responsive behavior unless the browser proof points there.` That line prevents a common second-order bug: the requested drawer fix accidentally changes a desktop sidebar or a mobile menu because the selector looked convenient.

Inspection: compare the diff to the boundary

After the patch, do not ask, `Is it fixed?` Ask Claude Code to audit the patch against the contract:

Prompt: `Review the current git diff against the approved boundary. Group changed lines by intent. Identify any file or hunk that violates the no-touch list, even if the code looks harmless.`

Then make it verify with evidence. For a UI bug, that might mean running the focused test and opening the affected route in the browser. For a backend bug, it might mean the failing request, a log line, and a targeted test. The important move is that diff review happens before celebration. If the diff touched `invoiceFormatter.ts` even though the bug was in settings, Claude must justify the connection or remove the change.

Failure modes and second-pass correction

The first failure mode is a boundary that is too broad: `components, hooks, and utils` is not a boundary. Ask for filenames and reasons. The second failure mode is treating the no-touch list as a cage when reality proves otherwise. If the error stack points directly into an out-of-scope helper, pause, update the boundary, and continue with a new proof. The rule is not `never touch shared code`; the rule is `never touch shared code silently.`

The best second pass sounds like this: `The patch changed one out-of-scope helper. Revert that hunk, rerun the focused test, and tell me whether the original bug still fails. If it still fails, produce the evidence that requires widening scope.` That prompt keeps Claude honest. Sometimes the cleanup was unnecessary and the test still passes after reverting it. Sometimes the cleanup was carrying the real fix, and now you have proof. Either outcome is better than accepting a pretty diff you cannot explain.

A practical example

Suppose Claude is fixing a stale filter badge in an admin dashboard. The approved boundary is `FilterBadge.tsx`, `useSavedFilters.ts`, and one test file. After the patch, the diff also changes `TableToolbar.tsx` because Claude wanted to simplify prop names. Your review prompt catches it. The second pass removes the toolbar rename, reruns the focused test, and performs a browser check: reload the dashboard, apply a saved filter, confirm the badge text, then inspect the diff again.

This is the TonBisa-style loop in miniature: prompt, inspect, find the gap, correct, verify. The no-touch list makes the gap visible. Without it, the toolbar rename might slide through as harmless cleanup. With it, the session has to earn every widened edit.

Rule of thumb

Before a Claude Code patch, ask for the files it will touch and the files it will not touch. After the patch, review the diff against that promise. If the fix needs more scope, widen deliberately with evidence. If it does not, make Claude remove the drift. Productive AI coding is not just faster editing; it is keeping each edit small enough that a human can still review the story.