AI Rewrote a Critical Section You Did Not Want Touched

You asked for an edit to one part — and AI quietly rewrote logic elsewhere.

You asked the model to rename a parameter in one function. It did. It also “cleaned up” a retry loop two functions below, swapped a forEach for a map, and silently changed a default timeout from 30s to 10s. None of that was in the prompt. None of it appears in the model’s summary of changes (“renamed parameter as requested”). Worse: the tests still pass because the retry path is exercised only in production. You will discover the change in a 3am incident, not in code review. AI agents over-edit because most chat-style instructions are interpreted as a license to “leave the code better than you found it” — a habit modeled on senior engineers in training data who do exactly that.

This page walks through how to scope an AI edit to a surgical change with a real diff you can audit.

Common causes

1. Verb is open-ended

“Refactor”, “improve”, “clean up”, “modernize” all give the model permission to touch anything that smells suboptimal — which, by training-set standards, is most pre-existing code.

How to spot it: your prompt verb has no object. “Refactor” alone means “improve everything you can”.

2. Whole file pasted, no edit zone marked

When the model receives the whole file and is told to “make a change”, regenerating the whole file is the path of least resistance. Anything regenerated drifts.

How to spot it: you pasted 400 lines and asked for one rename, and got 400 lines back.

3. Agent has wide write permission

In Cursor Composer, Claude Code with auto-edit, or Codex with broad scope, the model can touch any file. Without explicit scoping, “scope” becomes “everything the agent can read”.

How to spot it: changes appear in files you never named.

4. No diff format requested

If the output format is “the new file”, the model has to produce every line, and every line is a chance to drift. If the output format is “unified diff”, the model is forced to emit only changed hunks.

How to spot it: you got a full new file back, not a diff.

5. Model summary says “renamed” but does more

Models sometimes claim to do less than they did in their summary. The summary is a self-report; you cannot trust it for an audit. Audit the diff itself.

How to spot it: model summary mentions one change; diff shows many.

Before you change anything

  • Commit the current state before re-prompting (so you can git diff cleanly).
  • Identify exactly which lines/functions should change and which must not.
  • Save the over-edited output so you can compare with the surgical version.
  • For agent runs, narrow the scope (e.g., open only the target file in Cursor; restrict Claude Code’s working directory).
  • Decide: do you want a diff, an Edit tool call (exact old-string match), or a constrained full file?

Information to collect

  • The file(s) pasted and the prompt used.
  • The model’s claimed summary of changes.
  • The actual diff (git diff).
  • The model, agent, and tool permissions in effect.
  • A list of lines that were changed but should not have been.

Shortest path to fix

Step 1: Replace open verbs with surgical operations

Bad:  "Refactor this module for readability."
Good: "In function `handlePayment`, rename parameter `amt` to `amountCents`.
       Update all references inside `handlePayment` only.
       Do not modify any other function. Do not touch imports.
       Do not reformat unchanged lines."

Step 2: Declare a “do not modify” list

Constraints:
- Do not modify any function other than `handlePayment`.
- Do not touch imports, exports, or comments.
- Do not change constants `MAX_RETRIES` or `TIMEOUT_MS`.
- Do not change formatting of unchanged lines.
- If you would normally "clean up" something, list it in a separate
  "Suggested follow-ups" section instead of doing it.

Step 3: Demand a unified diff, not a file

Return output in this format:

DIFF:
\`\`\`diff
--- path/to/file.ts
+++ path/to/file.ts
@@ ... @@
- old line
+ new line
\`\`\`

SUGGESTED FOLLOW-UPS:
- <things you noticed but did not change>

Diff output forces minimal change because regenerating untouched code is wasted work.

Step 4: Use exact-match Edit tools when available

In Cursor / Claude Code / Codex, prefer the Edit tool that requires an exact old_string to match. The model literally cannot edit unmarked regions because the match fails. This is the strongest mechanical guarantee.

Step 5: Audit the diff, not the summary

Never accept the model’s prose summary as truth. Always:

git diff HEAD

Scroll every hunk. If a hunk surprises you, revert that hunk individually with git checkout -p or your IDE’s per-hunk revert.

Step 6: Split multi-region edits into multiple prompts

If you really need to change 3 functions, do 3 prompts. Combined prompts blur scope and the model averages constraints across regions.

How to confirm the fix

  • git diff shows changes only in the files and functions you named.
  • No imports, exports, or constants moved.
  • Existing tests still pass with no test changes from the model.
  • The model’s “follow-ups” list is non-empty if it noticed other issues — meaning it respected the scope.
  • A second AI run with the same prompt produces a similar diff (stable, scoped behavior).

If it still fails

  1. Restrict tool permissions: read-only on directories you do not want touched.
  2. Switch to Edit-tool-only mode (no full file rewrites).
  3. Use a smaller / cheaper model — many follow constraints more strictly than flagship models.
  4. For high-stakes code, never let an agent commit directly — always review the diff first.

When this is not on you

If your prompt literally said “refactor”, “polish”, or “modernize”, the model obeyed the prompt. The fix is to change the verb, not to blame the model.

Prevention

  • Default prompt verb: edit, rename, replace — never refactor, improve, or polish without scoping.
  • Always require diff output for code edits over 20 lines.
  • Bracket the edit zone with comments: // AI-EDIT-START / // AI-EDIT-END and tell the model to only modify inside.
  • Use Edit-tool exact-match mode for surgical edits.
  • Commit before every AI run so you can git diff and git restore cleanly.
  • Review the diff every time. Do not trust the model’s self-summary.

Tags: #Troubleshooting #Prompt #Prompt quality #Unwanted rewrite