Dev.to AI 🤖 Ai 👁 0 📖 3 min read

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 o

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 agents blow past “small”

Models don’t feel review pain. Given a feature ask, they’ll happily:

  • Touch every file that might be related
  • Rewrite tests “for clarity” while fixing the bug
  • Drive-by format / rename / import-sort half the package
  • Open shared UI primitives because “the Button was almost right”

You said small. They optimized for complete. Completeness without a budget looks like a megadiff.

The three budgets I actually use

I put all three in the prompt. Soft limits get ignored; hard stops get obeyed more often.

  1. Lines — max changed lines (insertions + deletions), e.g. ≤ 200 for a bugfix, ≤ 400 for a feature slice
  2. Files — max paths touched, e.g. ≤ 8 (tests count)
  3. Blast radius — allowed directories / globs, e.g. only src/features/checkout/** + colocated tests

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.

Paste this into the prompt

## 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.

That STOP clause matters. Without it, agents treat the budget as a suggestion and keep going.

How I pick the numbers

Rough defaults I reuse on frontend work:

Kind of change Files Lines Typical fence
Bug fix / copy / a11y 1–4 ≤ 120 One component + test/story
Small feature slice 3–8 ≤ 250 Feature folder only
Refactor (rename/extract) 2–6 ≤ 200 One intent, no behavior change
Migration / codegen separate rules — Often file-count heavy; budget by intent, not vanity lines

If the real work can’t fit, I split the ask before prompting — not after reviewing a monster.

Measure, don’t vibe

After the agent stops, I run:

git diff --stat
git diff --name-only | wc -l

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.

Blast radius beats line count

Line budgets alone miss the scary cases:

  • One-line changes in auth, payments, and i18n config
  • Touching design-system primitives for a page-level tweak
  • Editing both app code and generated GraphQL types “while here”

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.

Pair budgets with one intent

A diff budget without one intent still fails. “Fix checkout + clean hooks + update Storybook” will thrash inside the numbers by doing three half-jobs.

Prompt shape I like:

  1. One sentence intent
  2. Diff budget block
  3. Acceptance checks (tests / story / manual path)
  4. Explicit non-goals

Example non-goals: no renames, no dependency bumps, no “improve types” outside touched signatures.

What I do when overrun is legitimate

Sometimes 12 files is correct (rename across the feature). Then I:

  • Raise the file budget and freeze line budget for behavior
  • Or require one commit per concern inside the PR
  • Or stack two PRs: mechanical rename first, behavior second

I still write the new budget into the prompt. “Unlimited because rename” is how you get rename + rewrite.

Tiny checklist before I hit send

  • [ ] Intent is one sentence
  • [ ] File max + line max + path fence are numbers/globs, not adjectives
  • [ ] Forbidden paths listed
  • [ ] STOP-and-report rule present
  • [ ] How I’ll measure (git diff --stat) stated up front

What I stopped doing

  • Saying “keep it reviewable” with no numbers
  • Accepting “I had to touch Button” without a separate PR
  • Reviewing over-budget diffs hoping the important hunks would jump out
  • Letting test rewrites eat half the line budget on a one-line product fix

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.

📰 Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.