← The ADLC library
Live debates · 36

Against uniform review

One review policy applied to every change is why review is collapsing. You already have tiers, set by whichever diff happened to look boring on a Thursday afternoon. The only real question is whether you chose them.

Almost every engineering organisation runs the same review policy on every change: one approval, any approver, before merge. A dependency bump and a rewrite of the session handling code pass through the identical gate.

That was defensible when a team produced a handful of changes a day and the gate was cheap. It is now the single biggest reason review is failing, and my position is blunt: uniform review policy is not fairness, it is an abdication. It hands the tiering decision to fatigue.

You are already tiering

Watch what actually happens in a queue of forty pull requests on a Thursday.

The reviewer scans for the ones that look manageable. Small diffs, familiar areas, changes from people whose work they trust. Those get read. The 900-line change to the billing reconciliation path gets opened, scrolled, and approved, because reading it properly is an hour and there are nineteen more waiting.

So the deepest review went to the change that needed it least, and the thinnest went to the one that needed it most. That is a tiering system. Nobody designed it, and it runs on the inverse of risk, because attention flows towards what is easy to give attention to.

LinearB’s 2026 benchmarks put the numbers on the pressure driving this. Agentic pull requests show 5.3 times longer pickup time, median review duration up 441.5 percent, and merges with zero review up 31.3 percent. Read those together and the picture is not that reviewers stopped caring. It is that a uniform policy under that load has exactly two failure modes, waiting or waving through, and teams are doing some of each.

Tiering by fatigue

  • Small diffs get read closely
  • Large diffs get scrolled
  • Familiar areas get scrutiny, unfamiliar ones get trust
  • Friday changes get less than Tuesday changes
  • Nobody can state the policy, because there is not one

Tiering by risk

  • A short, named list of change classes gets deep review
  • Everything else gets automated gates and sampling
  • Deep review has protected time attached
  • The class of a change is determined before the queue, not in it
  • Anyone can state the policy in one sentence
Both columns spend the same total reviewer hours. Only one of them spends them on the changes where being wrong is expensive.

What a risk class actually looks like

The mistake most teams make when they try this is to define tiers by size, or by author, or by some composite score. Size is a proxy for effort, not for consequence. Author is a proxy that stops working the moment most changes are agent-initiated.

Define classes by what it costs to be wrong. That produces a short list, and short is the point.

Trust boundaries

Authentication, authorisation, session handling, anything that decides who may see what. Wrong here is unbounded and often silent.

Money and irreversible state

Billing, payments, deletion, migrations that drop or transform data. Wrong here cannot be fixed by rolling back the deploy.

Shared contracts

Public APIs, event schemas, anything another team consumes. Wrong here is discovered by someone else, later, at a bad moment.

Everything else

The large majority. Automated gates, criteria checked against the diff, and a sampled read. Full speed, and honestly so.

If your first three classes cover much more than a fifth of your changes, they are not classes, they are a wish for more reviewers.

The fourth box is where the argument gets uncomfortable, and I want to be direct about it. Saying “everything else gets sampled, not read” sounds like lowering the bar. It is describing what is already happening, with the difference that you have chosen where the reading goes and can say so out loud.

Deep review needs to actually be deep

Tiering only pays if the top tier is meaningfully different, and in most attempts it is not. It becomes “two approvals instead of one”, which is the same shallow read performed twice, with the added problem that each signer assumes the other looked properly.

A top-tier review that earns its cost has different mechanics: protected time on the reviewer’s calendar rather than a slot between meetings, a reviewer who knows that subsystem rather than whoever is free, a stated set of criteria to check the change against, and an output that is more than an approval. A question, a named behaviour, a test added, a scenario the change does not handle. If a top-tier review produces nothing but a green tick, you have not built a top tier, you have built a delay.

The corollary is that you cannot have many of these. A team can sustain a small number of deep reviews per week. That constraint is the reason the class list has to stay short, and any attempt to add a fifth and sixth class is really an attempt to avoid choosing.

Where this breaks down

Risk classification is exactly where context blindness lives. The changes that hurt most are often the ones nobody would have classified as risky: a cache TTL, a retry policy, a default value in a config. A tiering system routes attention by expectations, and the expensive failures are by definition the ones that violated expectations. This is the strongest argument against my position and I do not have a full answer to it. The partial answer is to add classes from your own incident history rather than from first principles, which at least corrects for the surprises you have already had.

Uniform policy has one genuine virtue: it is unarguable. The moment there are tiers, there is a negotiation about which tier a change falls into, and that negotiation happens under deadline pressure with the author arguing for the fast lane. Uniform policy is worse on average and much harder to erode.

Sampling only works if somebody acts on what it finds. A sampled read that finds a problem in an untiered change is a signal about the whole population. In practice it usually results in fixing that one change and moving on, which converts a statistical control into an expensive one-off.

Junior engineers lose something real here. Reviewing ordinary changes is how people learn a codebase. Route all the deep reading to the people who already know the risky subsystems and you have optimised this quarter’s risk while shutting the door on next year’s reviewers. That is a genuine cost of my position and it lands on the people with the least say.

And the classes will rot. A list written today reflects today’s architecture. Subsystems move, new trust boundaries appear, and nothing about a tiering policy makes it notice. It needs a scheduled revisit, which is exactly the kind of maintenance that quietly stops after two quarters.

The takeaway

Review is not failing because reviewers are careless. It is failing because a uniform policy under high volume degrades into tiering by convenience, and convenience is anti-correlated with risk.

Choose the tiers. Keep the deep list short, define it by the cost of being wrong rather than by diff size, give the top tier protected time and a real output, and be honest in public that the rest is gated and sampled rather than read.

If you take one thing into next week: take last month’s merged changes, mark the ones that touched a trust boundary, money, or a shared contract, and find out how long the review on each of those actually took. If those are not your longest reviews, your policy is being set by fatigue.