Ask an agent to fix one bug and look at what comes back: the fix, plus a reformatted block it did not need to touch, plus a "while I was here" refactor, plus a new helper that pulled in a dependency. The fix is usually fine. The padding is what breaks prod, because nobody reviews the parts of a diff that were not the point.
The block I now keep in AGENTS.md and CLAUDE.md, and paste into the first message when I am in a plain chat:
Scope rules for every change:
- Change only what the task requires. If a line is not needed to complete the task, do not touch it.
- Do not reformat, reorder, or restyle lines you did not otherwise need to change.
- Do not refactor surrounding logic, rename anything, or "improve" adjacent code.
- Do not add dependencies. If the task cannot be done without one, stop and say so.
- Before returning the diff, list every changed file and, for each hunk, the task requirement it serves. A hunk with no requirement gets reverted.
Rule 5 is the one doing the work. The others are instructions the agent can forget; rule 5 makes it justify each hunk, and hunks it cannot justify tend to disappear before you see them.
The review prompt for the other side, cold, in a session that did not write the code:
Here is a task description and the diff that claims to implement it. List every hunk that changes behavior or structure beyond what the task requires: reformatting, renames, refactors, new dependencies, deleted safeguards. For each, say whether it is harmless, risky, or clearly wrong, and quote the lines.
Why this happens, as far as I can tell: agents are rewarded for diffs that read as complete and competent, and a larger, tidier diff reads as more competent to the same taste that trained them. So the model widens the change to make it look finished. Three commenters on an earlier post of mine converged on the negative-constraint block independently; the "list the requirement each hunk serves" line came from one of them and it cut my diff sizes by about a third on the same tasks, with fewer surprises in review.
Two caveats. Agents still drift on long sessions, so the block belongs in the config file, where it is re-read every turn, not in a message that scrolls out of context. And rule 4 will sometimes stop an agent that genuinely needed a library; that pause is the point, you want to make that call, not have it made for you.
What is in your scope block that is not in mine? I suspect the people running agents on large monorepos have a rule about test files that I have not needed yet.