Code review checklist

A practical Pragmatic Programmer checklist

Updated 23 October 2026 · 7 minute read

Twenty questions that focus a review on the cost of the next change. This is an independent, practical checklist inspired by the principles in The Pragmatic Programmer; it is not the book’s checklist and reproduces no book text.

Use it in order. Start with the boundaries and the tests. Style disagreements can wait until the behavior and the design are understood.

The 20 checks

CheckQuestion to askCommon false positive
PP-DRYDoes each piece of knowledge have one authoritative home?Similar code that represents different policies
PP-CONFIGAre secrets, hosts, paths, and policy outside the code?A local constant that clarifies a comparison
PP-MAGICIs every numeric threshold named and explained?A protocol value fixed by an external contract
PP-ORTHOCan one concern change without forcing edits in another?Two modules that genuinely share a domain concept
PP-GLOBALSIs mutable state owned by the smallest possible scope?A process-wide client with a documented lifecycle
PP-TRAINWRECKAvoid call chains that reach through three or more objects.A fluent API or builder that returns its own type
PP-INHERITWould composition express this relationship better?Framework base classes and exception hierarchies
PP-CONTRACTSDoes every public boundary validate inputs and fail loudly?A boundary that intentionally returns a typed result
PP-RESOURCESIs every file, lock, transaction, and connection closed on every path?A resource transferred to a documented owner
PP-COINCIDENCEDoes the code rely on reliable behavior rather than an accident?Float comparison with an explicit tolerance
PP-COMPLEXITYIs each function small enough to hold in your head?A parser or dispatcher with inherent branching
PP-NAMINGDo names use the domain vocabulary and state intent?Short names with strong local convention, such as i in a loop
PP-COMMENTSDo comments explain why, and is dead code deleted?A comment that documents an external constraint
PP-BROKEN-WINDOWSIs every skip, suppression, and TODO bounded and visible?A skip that links to a tracked issue with an owner
PP-TESTSDo tests pin down the behavior you intend to keep?Generated tests that assert an observable contract
PP-TEST-HYGIENEAre tests deterministic and independent of the network and clock?An integration test with a local, controlled fixture
PP-AUTOMATIONAre tests, linting, and release steps scripted and repeatable?A documented manual step that cannot be automated yet
PP-VCSIs everything in version control, with secrets and large files ignored?A generated lockfile or vendored dependency
PP-E2EIs there one thin path that exercises the real architecture?A library with no service boundary to exercise
PP-DOCSDoes the README explain purpose, setup, usage, and tests?A repository whose docs live in a separate site

How to run the checklist in a pull request

  1. Read the change description. Write down what behavior should be different when the change lands.
  2. Find the boundary. Identify the smallest public surface that crosses into the change.
  3. Check the failure path. Follow an invalid input and an infrastructure error. Do they fail loudly with context?
  4. Check ownership. Follow every acquired resource to a guaranteed release.
  5. Check the tests. Remove one behavior and confirm a test fails for the right reason.
  6. Check duplication. Ask which representation is authoritative before suggesting an extraction.
  7. Record dissent. If a finding is a false positive, write the reason next to the suppression.

Automate the repeatable part

A checklist works better when the mechanical questions are answered before the review starts. The pragmatic-audit CLI checks 20 of these concerns, reports file and line locations, and produces a review packet for a coding agent.

pip install pragmatic-audit
pragmatic-audit .
pragmatic-audit . --agent-packet

The scan is a hypothesis generator, not a grade. Less than a perfect signal is not proof of poor design, and a clean signal is not proof of correctness.

Where the checklist stops

No static tool can decide whether a boundary is in the right place, whether a domain concept is named well, or whether an abstraction has earned its keep. Those remain human decisions. The checklist is there to make them explicit, not to automate them away.

Run the audit