← All posts Engineering

AI Coding Agent Over-Editing and Diff Size Limits

AI coding agent over-editing is a reviewability failure, not a style annoyance. The agent touches more files than the task needs, bundles behavior with cleanup, changes tests to fit the implementation, regenerates noisy artifacts, and hands reviewers a diff they cannot approve with confidence.

The bottleneck moved. Agents make broad diffs cheap to create. They do not make broad diffs cheap to understand.

For staff engineers and engineering managers, the answer is not "ask the model to be careful." Set diff budgets, scope budgets, path-risk rules, generated-file handling, and restart criteria before the work reaches a pull request.

Platform limits are not review limits

GitHub and GitLab publish real diff ceilings because review tooling has limits. GitHub PR diffs cannot exceed 20,000 loadable lines or 1 MB of raw diff data. A single diff is limited to 300 files, and only 25 renderable files are supported. GitLab self-managed defaults include 1,000 files and 50,000 lines, with oversized diffs marked too large.

Those numbers are product ceilings. They are not acceptable targets for human review.

A PR can sit far below GitHub's 20,000-line limit and still be irresponsible. The classic SmartBear/Cisco guidance points reviewers toward roughly 100 to 300 lines at a time and warns against review sizes above 400 lines, though later critique rightly says the public evidence should not be treated as a hard scientific law. Use the numbers as a sanity check, not a religion.

The practical rule is simpler: if a reviewer cannot inspect the change carefully in a normal review block, the agent produced too much work for one PR.

Measure AI coding agent over-editing by size and scope

Lines changed are easy to count and easy to misuse. A 60-line auth change may deserve more scrutiny than a 900-line generated snapshot. A one-line dependency bump can be riskier than a small helper refactor.

A useful agent diff budget combines four dimensions:

Budget What to count Why it matters
Line budget Non-generated added and deleted lines Approximates reviewer reading cost
File budget Number of changed files and directories Shows blast radius and context switching
Scope budget Subsystems, packages, owners, and behavior changes Prevents one task from becoming a redesign
Risk budget Auth, payments, migrations, public APIs, dependencies, infra Applies stricter rules where mistakes cost more

Start with local defaults. For many product teams, a warning above 200 to 400 non-generated LOC, an ask gate above 10 changed files, and a block or split requirement above 25 changed files is a reasonable first policy. Then adjust from your own review data.

Do not pretend one number covers every repo. A codegen PR and a permissions PR need different review paths.

Give agents a scope contract before editing

Most over-editing starts before the first file changes. The assignment is vague, so the agent expands the task. "Fix the bug" becomes "fix the bug, clean nearby code, update tests, rename a helper, adjust mocks, and touch config because it looked related."

Before edit mode, require the agent to state:

  • the exact behavior it is changing
  • the files or directories it expects to touch
  • the files it must not touch
  • the tests it will add or run
  • the risk paths that need approval before editing
  • the point where it should stop and ask

Put that in AGENTS.md, task templates, or tool-specific instructions. Then back it with permissions where possible. For Claude Code, deny or ask rules can protect migrations, generated directories, package manifests, deployment config, and test assets. Instructions shape behavior. Permissions make the boundary real.

CI should label reviewability, not only correctness

CI usually answers "does it pass?" Add a check that answers "is this reviewable?"

The check can compute:

  • changed files
  • non-generated LOC
  • generated LOC
  • deleted files
  • test modifications versus test additions
  • dependency manifest and lockfile changes
  • high-risk path touches
  • number of CODEOWNER groups requested

The output should be visible in the PR. Label it reviewable, needs-split, agent-scope-exceeded, or generated-churn. A reviewer should not have to discover on their own that the agent touched auth, regenerated snapshots, and changed a package lockfile.

Watch GitHub Actions path filters for huge diffs. GitHub documents that if a generated diff has more than 3,000 files, filters only see the first 3,000 returned files. That can skip intended workflows. Large agent diffs are not only hard to review. They can make automation behave in ways the team did not expect.

Generated files should not hide semantic work

Generated artifacts create a common review trap. The PR shows thousands of lines changed, but the actual decision is in two source files. Or worse, the generated churn hides an unrequested behavior change.

Use linguist-generated for files that should be hidden by default in GitHub diffs and excluded from language stats. Keep generated-file changes separate from semantic changes when possible. Include the exact generation command and the source-of-truth input.

A good generated-file section in an agent PR says:

  • which files are generated
  • which command regenerated them
  • which source files caused the generation
  • whether reviewers should inspect them directly or sample them
  • whether CI verified regeneration from source

Generated files can be large. They should not make the behavioral review obscure.

Reject or restart when the scope is gone

Teams lose time when they try to review their way out of an unreviewable agent diff. Some PRs should go back to draft. Some should be thrown away and restarted with a smaller prompt.

Use these restart criteria:

  • The agent touched an unrequested subsystem.
  • The diff combines behavior change with style cleanup.
  • Existing tests were changed to match the implementation.
  • Public APIs, auth, migrations, or dependency manifests changed without approval.
  • The PR exceeds the file or LOC budget and is not an approved migration or codegen task.
  • The human owner cannot explain why each file changed.
  • The review path is unclear.

This is not punishment. It is capacity management. Reviewer attention is a production resource.

Make large necessary changes reviewable

Some changes are large because the system requires it: migrations, generated clients, package moves, API-wide renames, framework upgrades. The answer is not to pretend they are small. The answer is to split the decision surface.

Use stacked PRs where possible. Separate mechanical renames from behavior changes. Put generated artifacts in their own commit or PR. Route sensitive paths through CODEOWNERS. Include a file-by-file table that says why each area changed. For migrations, include rollback and compatibility notes. For public APIs, include consumer impact.

For unavoidable large PRs, pair a design review with code review. The reviewer should first approve the plan and boundaries, then review implementation slices. Asking one person to infer architecture from a 10,000-line diff is not review. It is a gamble.

A practical default policy

Start with this policy and tune it with your data:

  • Agent work starts with a plan for any task likely to touch more than five files.
  • Warn above 200 to 400 non-generated LOC.
  • Ask for human approval above 10 changed files.
  • Require split or explicit approval above 25 changed files.
  • Block unapproved edits to tests, migrations, auth, deployment config, dependency manifests, and public APIs.
  • Separate generated files from semantic changes.
  • Reject agent PRs where the human owner cannot explain the diff.

AI velocity is useful only when review capacity keeps up. Diff budgets give agents room to work inside a bounded space and give humans the right to say, "this is too much to approve responsibly."

Get started

Deploy your fleet.

Put a fleet of sandboxed agents to work on your own infrastructure, provisioned in seconds and watched live from one console.

Get started

Admin-provisioned · Self-host in one command · Your data never leaves your VM