A pull request is not a spelling test. It is a proposal to change software that other people—and often future versions of you—will need to trust and maintain.
The best reviews protect correctness without turning into a performance of superiority. They focus on the risks that matter, explain concerns clearly, and help the author improve the change.
This guide works whether the code was written by a person, an AI assistant, or a mixture of both.
Start with the story, not the diff
Before reading line by line, answer four questions:
- What user or engineering problem does this change solve?
- What behaviour should change?
- What must remain unchanged?
- What evidence would convince me that the change works?
Read the ticket, description, screenshots, design notes, and tests. If the pull request does not explain its purpose, ask for that context before guessing.
Then inspect the overall diff. Notice which files changed, whether the scope matches the task, and whether any unrelated formatting, generated files, dependency changes, or configuration edits appeared.
Review in layers
Layer 1: Correctness and contracts
Look for the actual behaviour, not just whether the code looks plausible.
- Are inputs validated at the right boundary?
- Are assumptions about data shape or ordering justified?
- Are return values and error states handled consistently?
- Does the code preserve existing API and data contracts?
- Could concurrent operations, retries, or partial failures violate an invariant?
Read surrounding code when a change depends on a function’s contract. A line can look correct in isolation and still violate how its caller expects it to behave.
Layer 2: Failure paths and edge cases
Happy paths are necessary and rarely sufficient. Consider empty values, missing permissions, network timeouts, duplicate requests, malformed input, stale state, and partial success where relevant.
Do not mechanically demand every possible edge case. Choose cases that follow from the requirements, the data model, and the failure modes of the system.
Layer 3: Tests and evidence
Check whether the tests exercise the behaviour that changed. A test that only confirms a helper returns a hard-coded value may not prove the feature works end to end.
Ask:
- Does a regression test fail on the old behaviour?
- Are assertions checking the right outcome?
- Are important error paths covered?
- Did CI actually run, and did it run the relevant checks?
- Are there manual verification steps that should be recorded?
A green CI run is useful evidence. It is not a substitute for understanding the change.
Layer 4: Security and data handling
Pay special attention to authorization, input handling, secrets, sensitive data in logs, unsafe file operations, untrusted content, and new external dependencies. Think about where trust changes: browser to server, user to administrator, service to database, or retrieved content to an AI agent.
If you find a security concern, describe the concrete risk and a safer alternative. Do not paste live secrets or private user data into review comments or AI tools.
Layer 5: Maintainability and operations
Finally, consider whether the change is understandable and operable:
- Is the design consistent with local conventions?
- Is the abstraction simpler than the problem it solves?
- Will errors be diagnosable in production?
- Does the change require a migration, feature flag, configuration, or rollback plan?
- Does it add cost, latency, or a new operational dependency?
A tiny change can have a large operational footprint. Review the consequence, not just the number of lines.
Make comments people can act on
Weak comment:
This is bad. Fix it.
Better comment:
If this request is retried after a timeout, this path can create a second order because the write is not idempotent. Could we enforce the invariant at the service or database boundary and add a retry regression test?
Useful review feedback names the condition, explains the consequence, and offers a path forward. Distinguish blockers from suggestions. Ask questions when you are uncertain about the intent.
Avoid turning subjective preferences into correctness requirements. If a naming or formatting issue is already handled by automated tooling, let the tool handle it.
Reviewing AI-generated changes
AI-generated diffs deserve the same review as any other code, often with extra attention to consistency and scope. Look for:
- Unused or invented APIs.
- Broad changes unrelated to the task.
- Tests that simply mirror the implementation’s assumptions.
- Error handling that catches and hides failures.
- Secrets, unsafe input handling, or weakened permissions.
- Duplicate logic that should use an existing project abstraction.
- Documentation that describes behaviour the code does not implement.
Do not assume AI code is bad or good by origin. Review the evidence and the change itself.
The reviewer’s decision
A review should make its outcome legible. Depending on the platform and team norms, the outcome may be approval, a request for changes, or a discussion that needs resolution.
Before approving, you should be able to explain what changed, why it is correct enough to merge, what checks support that judgment, and what risks remain. You do not need to guarantee perfection. You do need to make a responsible decision with the evidence available.
A pull-request review checklist
- I understand the ticket and intended behaviour.
- The diff is limited to the necessary scope.
- The implementation preserves relevant contracts and invariants.
- Important failure paths and edge cases are considered.
- Tests cover the changed behaviour and meaningful regressions.
- Security and sensitive-data boundaries remain intact.
- CI and relevant manual checks have been examined.
- Deployment, migration, and rollback implications are clear.
- My comments are specific, respectful, and actionable.
Try it: be the reviewer
Open a small pull request in a reputable open-source project. Read its description first. Before reading comments from other reviewers, write down three things: the intended behaviour, the highest-risk failure mode, and the evidence you would want before approving.
Then compare your analysis with the actual discussion. You will learn not just how to spot defects, but how experienced engineers explain why a change is safe.