How to merge AI code safely on a busy team

By Rogier Muller08.15.26
How to merge AI code safely on a busy team

Triage the diff before you read it

To merge AI code safely, sort the change into three buckets and give each a different level of attention. Mechanical edits, renames, import reordering, formatting, get a skim and a green pipeline. Logic changes inside existing functions get a careful read. Anything touching auth, money, permissions, data deletion, or an external boundary gets read line by line, out loud if it is late in the day.

Doing this consciously beats the default, which is reading the first thirty lines carefully and the remaining four hundred with rapidly declining attention.

The bugs that get through

Review these failure modes in generated code as well as hand-written changes:

  • Plausible but wrong constants. A timeout of 30 seconds where your infrastructure uses 5, a retry count copied from a generic example.
  • Silently swallowed errors. A try block wrapping more than it should, with a log line and no rethrow.
  • Duplicated helpers. A new utility that already exists two directories away under a different name.
  • Tests that assert the implementation rather than the behaviour, so they pass and protect nothing.
  • New dependencies added to solve something your standard library already does.

The fourth one is the most expensive because it looks like diligence. When a diff arrives with generous test coverage, check that at least one test would fail if you deleted a line of the new logic. If none would, the coverage is decorative.

Automate the checks humans are bad at

Use human review for intent and tradeoffs, supported by automated checks for repeatable properties. Run a secret scanner in pre-commit. Print the lockfile diff into the pull request body so a new package cannot arrive unnoticed. Enforce a coverage floor rather than a target. Require an explanation for new lint suppressions and check that they do not conceal the defect being fixed.

Then add the cheapest control of all: a size cap. Split a large PR when it contains independently reviewable changes. Generated files, migrations and mechanical renames may need different treatment; assess the reasoning burden rather than using a universal line limit.

Ask the author to explain one thing

Our favourite review practice needs no tooling. Pick one non-obvious block in the diff and ask the author why it is written that way. An accurate explanation is useful evidence of understanding, but does not prove they inspected every line. If they cannot, you have learned something more useful than any static check could tell you, and the fix is a conversation rather than a policy.

This works because it is not adversarial. Nobody is being accused of anything. It simply makes reading the code the path of least resistance, which is the entire goal.

Apply the review to one change

Choose a small recent PR. Label its mechanical, logic and sensitive changes, then identify the test that protects its main behavior. On a disposable branch, introduce a deliberate regression in that behavior and confirm the test fails. Restore the implementation, rerun the check, and attach both results to the review. If the test stays green, improve the assertion before relying on its coverage.

Where does your team stand?

Each team member completes the proficiency matrix individually. You receive a PDF with the team baseline and a recommended next step.

Assess your team