The Pull Request Checklist: Before You Open, and Before You Approve

Two checklists, not one — the author's and the reviewer's — plus a GitHub template you can paste in today. Including the item that predicts more about review time than the other nine combined, and the section every pre-2025 checklist is missing.

Coderbuds Team
Coderbuds Team
Author

A pull request checklist is a short, agreed list of things to confirm before a change moves — one list for the person opening it, a different one for the person approving it. Most teams write a single list, hand it to both, and wonder why it gets ticked without being read.

Here are both, in the form you can use today. The reasoning is underneath, and the section on AI-generated code is the part that did not need to exist three years ago.

#The author's checklist

Before you click Create pull request:

  • It does one thing. The title can be written without the word "and".
  • It is small enough to be read in one sitting. See below — this is the item that matters most.
  • The description says why, not what. The diff already says what.
  • I have read my own diff, top to bottom, in the pull request view rather than the editor.
  • Debug code, commented-out blocks and stray console.logs are gone.
  • Tests cover the behaviour I changed, and I have watched them fail without the change.
  • The checks pass. Nobody should review a red pull request.
  • Anything I generated, I can explain. Line by line, if asked.
  • The risky part is flagged in a comment on the diff, so the reviewer's attention lands there first.
  • I know who should review this, and it is not just whoever is least busy.

#The reviewer's checklist

Before you click Approve:

  • I understand what problem this solves. If not, that is a comment, not an approval.
  • It does what the description claims — and nothing the description does not mention.
  • The edge cases are handled: empty, null, zero, very large, concurrent, and the failure path.
  • Errors are handled rather than swallowed.
  • Nothing here is a security problem: untrusted input, authorisation checks, secrets, injection.
  • The tests would fail if the code were wrong. A test that passes against a broken implementation is worse than no test.
  • I could maintain this in six months, or I have said which part I could not.
  • My comments distinguish blocking from optional. Prefix the ones that are not: nit:.
  • I have not rewritten it in my head and asked for my version. Different is not worse.

Two lists, because the jobs are different. The author is protecting the reviewer's attention. The reviewer is protecting everyone who comes after.

#The one item that predicts the rest

If you keep a single line from the author's list, keep the size one.

Here is what pull request size looked like on our own repository, across 431 pull requests merged in a recent 90-day window:

Size Median time to merge
Tiny 8.6 hours
Small 9.4 hours
Medium 18.1 hours
Large 87.6 hours

Median size across all of them was 241 lines.

The shape of that table is the finding, not the exact hours. Tiny and small are indistinguishable — a reviewer picks up either one in the same sitting. Medium roughly doubles. Then large is not a further doubling but a tenfold jump: one working day against three and a half.

That jump is not reading time. A 900-line diff does not take ten times longer to read than a 90-line one. It is queueing. A reviewer with twenty minutes free will pick up the small change and leave the large one for later, and later competes with tomorrow's work, and tomorrow's work wins.

The practical consequence for your checklist: shaving lines off an already-small pull request buys almost nothing. Keeping one change out of the large bucket buys days. Which is why the item is "small enough to read in one sitting" and not "under 400 lines" — the threshold that matters is attention, not arithmetic.

More on how to measure it in the pull request size glossary entry.

#The section every older checklist is missing

Search for a pull request checklist and most of what you will find was written before a meaningful share of the diff was generated rather than typed. Those lists still work, but they assume something that is no longer safe to assume: that the author read every line before the reviewer did.

Three items worth adding.

"I can explain this" is now a real check, not a platitude. The failure mode with generated code is not that it is wrong in obvious ways — it usually compiles, usually passes the tests it was asked to write, and usually reads well. It is that it is plausible. It handles the case the prompt mentioned and silently does something reasonable-looking with the case nobody thought of. Reading your own diff before opening catches this, and it is exactly the step that feels most skippable when the code arrived in seconds.

Generated tests need checking against a broken implementation. A generated test suite frequently tests that the code does what the code does. Break the function on purpose and watch the test fail. If it passes, you have coverage without verification, which will read as safety on a dashboard and provide none.

Say what wrote it. Not as an admission — as context for the reviewer. "Most of the parser here is generated, the reconciliation logic is mine" tells a reviewer where to spend their attention, and it is more useful than either pretending otherwise or apologising for it. The second-order benefit is that it is the only honest input to any measurement of how AI is actually affecting your delivery; inferring it later from the shape of a diff is guesswork.

If your team is trying to measure this properly, tracking AI coding tools through pull requests covers the approach, and your code review stopped being a quality signal covers why the review step in particular stopped catching what it used to.

#Putting it in GitHub automatically

Create .github/pull_request_template.md in the repository root. GitHub pre-fills the description box with it on every new pull request — no app, no configuration, no permissions.

 1## What and why
 2
 3<!-- What problem does this solve? The diff shows what changed; use this for why. -->
 4
 5## How to check it
 6
 7<!-- What should the reviewer run, click, or look at first? -->
 8
 9## Where I want attention
10
11<!-- The risky part. Be specific — "the retry logic in Client::send" beats "the new service". -->
12
13## Author checklist
14
15- [ ] Does one thing
16- [ ] Small enough to read in one sitting
17- [ ] I have read my own diff
18- [ ] Tests cover the change, and I have watched them fail without it
19- [ ] Checks pass
20- [ ] I can explain every line, including anything generated
21
22## AI assistance
23
24<!-- Which parts were generated, and with what. Helps the reviewer aim. -->

Three things worth knowing about templates:

Keep it shorter than you want to. The template is a prompt, not a form. Every item you add costs attention from every item already there.

Use <!-- comments --> for instructions. They are visible while writing and invisible in the rendered description, so the merged pull request reads as prose rather than as a filled-in form.

You can have more than one. Put multiple files in .github/PULL_REQUEST_TEMPLATE/ and append ?template=hotfix.md to the new-PR URL. In practice most teams do not need this, and a single good template beats four that nobody can choose between.

For the reviewer half, a template does not help — reviewers do not get a form. Put that list where reviews happen: a pinned message, a CODEOWNERS convention, or your team's definition of done.

#Why most checklists quietly stop working

Every team that adopts one goes through the same arc, and it is worth naming so you can skip a step.

They grow. Each incident adds an item, nothing ever removes one, and eighteen months later there are thirty boxes. A thirty-item checklist does not get followed thirty times more carefully — it gets ticked in one pass without being read, which is strictly worse than no checklist, because now the ticks look like evidence.

The fix is a budget. Ten items, and adding an eleventh means removing one. Argue about which to remove. That argument is the useful part.

They drift towards the mechanical. Formatting, import order, trailing whitespace, naming conventions — all real, all easy to check, and all things a linter should be doing. Anything a machine can verify should not be on a human's list. Every mechanical item you remove buys attention for a judgement item, and judgement is the only thing review is actually for.

They ask for the unverifiable. "Code is well-documented." "Follows best practices." "Is performant." Nobody can tick those honestly, so everyone ticks them dishonestly, and the habit of ticking without checking spreads to the items that mattered.

They turn into a compliance ritual. Once a checklist is enforced rather than used, the goal becomes a green tick rather than a good change. You can tell this has happened when pull requests are approved within ninety seconds of being opened, or when the same reviewer approves everything. Both are measurable, and both are worth looking at before you conclude your review process is healthy.

They never get reviewed. Put the checklist itself on a retrospective agenda twice a year. Which items caught something? Which have never once been the reason a change was sent back? Delete the second group without ceremony.

#Where the checklist should actually run

Here is the uncomfortable thing about the author's list: every item on it is checked at the last possible moment.

By the time you are looking at the Create pull request screen, the change is written. "It does one thing" and "small enough to read in one sitting" are not really checks at that point — they are verdicts. If the answer is no, the options are to open it anyway, or to spend an afternoon unpicking a change that is already finished. Most people open it anyway, and the checklist records a decision it did not influence.

That is not a discipline problem. It is a timing problem. A checklist at the end of the work can only catch what is still cheap to change, and by then very little is.

Which is why the interesting version of this is the same list, applied earlier. Your team's standards — how big a change should get before it is split, what needs a test, what needs a second reviewer — are now readable by the coding agent doing the work, over MCP, at the point the change is being written rather than after. The check that asks "should this be two pull requests?" is worth something when there is one file open and worth nothing when there are forty.

That is what Coderbuds does with the standards your team already has: carries them into Claude Code, Cursor and Copilot so the guidance arrives before the code, and then measures whether it made any difference to how long things actually took. The checklists above work perfectly well on their own — they are the same items either way. The only question is whether they run while there is still time to act on them.

#Related reading

Coderbuds Team
Written by

Coderbuds Team

The Coderbuds team writes about DORA metrics, engineering velocity, and software delivery performance to help development teams improve their processes.

View all posts

You're subscribed!

Check your email for a confirmation link. You'll start receiving weekly engineering insights soon.

Want more insights like this?

Join 500+ engineering leaders getting weekly insights on DORA metrics, AI coding tools, and team performance.

We respect your privacy. Unsubscribe anytime.