How to review a pull request you did not ask for

Open any active repository and look at the pull request list. A growing share of what is there was not requested by anyone.
Dependency version bumps from an update bot. Security patches from a scanning tool. Lint and formatting corrections. Refactors an agent decided were an improvement while working on something adjacent. Suggested fixes from static analysis. They arrive daily, they are usually small, the build is usually green, and they get approved in a few seconds each.
The review habits everybody learned were built for a different situation, and they fail on these in a specific way that is worth naming.
The missing half of a review
Reviewing a human's change is a conversation with one side already written. The diff carries what was done. What is missing, reliably, is why: which approaches were tried and abandoned, what the author knew about the calling code, what they checked before deciding a case could not happen.
So reviewers ask. Why this approach. Did you consider the other thing. What happens when this is null. The question is a request for information that exists, in somebody's head, and can be retrieved.
On an unrequested pull request there is nothing to retrieve. The agent has no retained reasoning. Ask it anyway and you will get a fluent, confident, well-structured answer, reconstructed from the diff in front of it. That answer may be correct. It carries no evidence either way, and it is more dangerous than silence, because it satisfies the reviewer's instinct that a reason was given.
This is the adjustment: the review has to run on evidence inside the change rather than on intent behind it.
Three questions that work without an author
What did this change that I cannot see?
The diff is not the change. This is most obvious on a dependency bump, where the visible edit is one line in a lock file and the actual change is every difference between two versions of somebody else's code.
For a version bump, the artefact to read is the upstream changelog between the two versions, not the diff. You are looking for behavioural changes, deprecations, default value changes, and anything in the "breaking" section that the semantic version number did not warn you about, which happens more often than the convention promises.
For a generated refactor, the invisible part is whether behaviour changed at a boundary. Refactors are defined as behaviour-preserving and generated ones sometimes are not, particularly around null handling, ordering, and error paths that no test exercises.
What does this change claim about the world?
Generated changes constantly encode assumptions about data. This value is never null. This field is unused. This collection is small enough to load at once. This loop runs a handful of times.
Each is a claim about your production system, and your production system is not in the pull request. The reviewer's job on these is to notice the claim and then go and check it against something real: a query, a log, a metric. Not against intuition, because intuition about data distributions is unreliable in exactly the way that produces incidents.
This is the same failure described in why data changes are riskier than code changes, and it shows up wherever generated code meets data nobody measured.
What happens if this is wrong at 3am?
Two properties matter and neither is diff size: blast radius and reversibility.
A change that is small and reversible earns a fast approval, because being wrong costs a rollback. A change that is small and irreversible does not, regardless of how tidy it looks. Dropping a column, altering a permission default, changing a retry policy, modifying something that runs in a scheduled job: all of these can be eleven lines and none of them is cheaply undone.
The reason this question matters most is that approval speed in practice tracks diff size, and diff size is nearly unrelated to consequence. That correlation is the thing to break.
The queue problem
Behind the individual reviews is a volume problem that changes behaviour whether or not anyone decides it should.
A repository generating fifteen automated pull requests a week, each needing a genuine ten minutes of investigation, has created two and a half hours of weekly work that nobody was assigned and nobody scheduled. What happens next is predictable. The queue grows, somebody feels bad about it, and a habit forms of approving anything that looks routine. At that point the review step exists in the process diagram and nowhere else, which is worse than not having it, because it is being counted as a control.
Three things help.
Set a policy per category rather than deciding per pull request. Patch bumps to development-only dependencies behind a suite that would catch a regression: auto-merge is defensible. Anything touching authentication, payments, or data handling: always a human, always the changelog. Major versions: always a human. Write this down so it is a decision made once rather than fifteen times a week under time pressure.
Batch and schedule. Review these in one block on a fixed day rather than reactively as they arrive. Reactive review of low-urgency changes is how the fast-approval habit gets trained.
Name owners. Dependencies, security patches, and generated refactors each get a specific person. Unowned automated changes are reviewed by whoever has a spare moment, which describes no review at all.
What a green build is evidence of
Every one of these arrives with a passing build, and the temptation is to treat that as the answer.
A green build is evidence about exactly the cases the test suite covers, and nothing else. On a dependency bump it proves your tests still pass against the new version, which says nothing about the upstream behaviour your tests never touch. On a refactor it proves the covered paths still work, and refactors go wrong on uncovered paths.
The useful habit, and it takes an afternoon once rather than effort per review, is knowing what your suite actually protects. Break something a check is supposed to catch, on purpose, and confirm the build turns red. A check that cannot fail has been contributing false confidence to every review it appeared in. We made the longer argument in how many tests does AI-generated code need.
Where the actual risk sits
The dangerous unrequested pull request is never the large one. A 600-line generated refactor gets attention automatically, because its size triggers the instinct to slow down.
The one that gets merged is small, green, plausible, and appears among fourteen others exactly like it. It bumps a library that handles session tokens across a minor version where the default expiry changed. It removes a null check that a linter called redundant and that was covering a case the linter could not see. It adjusts a retry count in a job that only runs on the first of the month.
None of those are found by reading harder. They are found by asking what changed outside the diff, what the change assumes about real data, and what being wrong costs, on every change, including the boring ones. Especially the boring ones, since boring is the entire category now.
Sources
- Veracode spring 2026 GenAI code security testing: across more than 150 large language models, syntax correctness exceeded 95 percent while the security pass rate stayed near 55 percent and was roughly flat over two years.
- METR, early-2025 study of experienced open-source developers: 16 developers took 19 percent longer across 246 tasks when using AI tools, while afterwards believing they had been 20 percent faster.


