Diff budgets for AI PRs: lines, files, and blast radius
I stopped arguing with agents about “keep the PR small.” Small is mushy. What works is a diff budget — hard numbers for lines, files, and blast radius — written into the prompt before the model starts typing. Green CI on a 1,200-line agent PR is not a win. It’s a review hostage situation. Why agent

I stopped arguing with agents about “keep the PR small.” Small is mushy. What works is a diff budget — hard numbers for lines, files, and blast radius — written into the prompt before the model starts typing.
Green CI on a 1,200-line agent PR is not a win. It’s a review hostage situation.
Models don’t feel review pain. Given a feature ask, they’ll happily:
You said small. They optimized for complete. Completeness without a budget looks like a megadiff.
I put all three in the prompt. Soft limits get ignored; hard stops get obeyed more often.
Miss any one and reviewers lose the thread. A 150-line change across 25 files is still painful. A 300-line change inside one feature folder is often fine.
## Diff budget (HARD — stop if you would exceed) - Max files: 8 (including tests / stories) - Max lines: 250 (git diff --stat total) - Blast radius: ONLY src/features/checkout/ ** and ** /checkout *.test.* - Do NOT edit: src/components/ui/ **, shared hooks, CI, package.json, lockfiles If the task needs more: STOP. List what you’d need and why. Do not “almost finish” outside the fence. Prefer a follow-up PR over expanding scope. Enter fullscreen mode Exit fullscreen mode That STOP clause matters. Without it, agents treat the budget as a suggestion and keep going.
Rough defaults I reuse on frontend work:
If the real work can’t fit, I split the ask before prompting — not after reviewing a monster.
git diff --stat git diff --name-only | wc -l Enter fullscreen mode Exit fullscreen mode If --stat or the file count is over budget, I don’t deep-review. I send it back:
Over budget: 14 files / 480 lines. Fence was checkout/**, max 8 / 250. Split into (1) UI state (2) API wiring — or justify the overrun in one paragraph.
Agents respond well to concrete overruns. “Too big” does nothing. Numbers do.
Line budgets alone miss the scary cases:
So I always name allowed globs and forbidden areas. When the agent needs a shared Button change, I want a stop + a note — maybe that becomes PR #2 with its own reviewers.
A diff budget without one intent still fails. “Fix checkout + clean hooks + update Storybook” will thrash inside the numbers by doing three half-jobs.
Example non-goals: no renames, no dependency bumps, no “improve types” outside touched signatures.
Sometimes 12 files is correct (rename across the feature). Then I:
I still write the new budget into the prompt. “Unlimited because rename” is how you get rename + rewrite.
Diff budgets turn “please be careful” into something the agent can fail against. Lines, files, blast radius — pick all three, put them in the prompt, and send the PR back when the meter trips. Review time stays scarce; the model’s typing speed doesn’t get a blank check.