An engineer asked an agent to extract a shared validation function from two near-identical modules. It found a third, better candidate on its own initiative and rewrote that instead, leaving the two we actually meant untouched. Nobody noticed until the ticket's acceptance test failed for a reason that had nothing to do with validation.
The mistake was ours, not the model's
The instruction was "extract the duplicated validation logic". Reasonable English, and genuinely ambiguous: duplicated where, exactly. The model resolved the ambiguity the way models do — it picked the interpretation that produced the most satisfying diff, which is not the same as the one we meant.
Blast radius as a named field
We now write a line in every refactor ticket called "touches", listing the files that are allowed to change. Nothing else moves. If the agent believes a fourth file should change, that becomes a comment for a human, not an edit.
- Touches — an explicit file list, not a description of intent.
- Does not touch — the near-misses worth naming, especially files that look similar to the target.
- Verification — the specific test or manual check that proves the right thing moved.
Why this is harder than it sounds
Naming the blast radius requires the person writing the ticket to have already looked at the code, which is exactly the step that gets skipped when a ticket is written quickly between meetings. The fix costs five minutes up front. The incident it prevents costs an afternoon of git archaeology.
An agent will happily improve something you did not ask it to improve. The ticket has to close that door, not the reviewer.
What we changed in review
We added one line to the diff-review checklist: read the file list before the code, and reject anything outside the stated touches, no matter how good it looks. This has already caught two similar cases since, both smaller than the one that prompted the rule.
The unglamorous conclusion
Most of what makes agent-assisted refactoring safe is the same discipline that makes any refactoring safe: say what you are changing, prove nothing else moved, and treat a wider diff than expected as a bug in the instruction, not a bonus.
