One Claude Code Tip a Day: Review Code Like a Maintainer
Use Claude Code as a maintainer-style reviewer: make it read the diff, test the behavior, challenge edge cases, and request a second-pass patch before merging.
This post is part of the “One Claude Code Tip a Day” series — a daily guide to using Claude Code more effectively.
The most dangerous Claude Code session is the one that looks finished. The patch compiles, the assistant says the task is done, and the diff is short enough that you want to approve it quickly. That is exactly when I like to switch Claude from builder mode into maintainer mode.
Today’s habit: after Claude Code implements something, do not ask “is this good?” Ask it to review the change as if it owns the repository for the next year. That wording matters. A maintainer is not only checking syntax. A maintainer asks whether the behavior is observable, whether the tests prove the right thing, whether the change fits the existing patterns, and whether the failure path will be understandable six months later.
The real task
Imagine a small frontend bug. A settings page has a “Save preferences” button that sometimes stays disabled after the user edits a field. You ask Claude Code to fix it. It reads the component, notices that the dirty-state comparison ignores a nested notification setting, patches the comparison, and adds one unit test. The first pass is plausible.
This is where many developers stop. The better move is to force a review loop before you accept the edit.
The review prompt
Run the tests if you have not already, then give Claude a reviewer-shaped instruction:
Prompt: Review your last changes as a strict maintainer. Start from git diff. Do not edit yet. Explain the behavioral change, the files touched, the tests that prove it, and the risks that are still untested. Look for over-broad changes, naming drift, missing loading/error states, and places where the UI could still lie to the user.
If the patch touched more than one subsystem, make the scope explicit:
Prompt: Limit the review to the preferences save flow. Ignore unrelated formatting. For each concern, quote the exact file and line range from the diff and say whether it is blocking, follow-up, or acceptable.
The important part is “Do not edit yet.” You want analysis before another patch. Otherwise Claude may hide the review inside a new round of changes, and you lose the chance to see whether it understands the risk.
What to inspect
A good maintainer review from Claude Code should include four artifacts. First, a diff summary in plain English: not “updated preferences logic,” but “the dirty-state check now compares notifications.email and notifications.push before enabling Save.” Second, a behavior claim: what a user can now do that they could not do before. Third, verification: the exact tests, lint commands, browser checks, or logs used as evidence. Fourth, remaining risk: the cases not covered by the patch.
For the settings example, I want Claude to say something like: “The new unit test covers editing the nested notification preference from false to true, but it does not cover reverting the value back to the initial state, so the Save button might remain enabled after an undo.” That is useful. It turns a vague code review into a concrete second-pass target.
Make the second pass small
Once Claude identifies a real gap, do not let it rewrite the whole component. Give a narrow correction prompt:
Prompt: Good catch on the revert case. Make the smallest patch that proves Save disables again when the user changes notifications.email and then changes it back. Prefer adding a failing test first. Do not refactor unrelated state logic.
This keeps the loop honest. The second pass should usually be one test plus a tiny implementation adjustment, not a new architecture. If Claude proposes a large rewrite during review, treat that as a smell. Ask it to separate “blocking correctness issue” from “nice cleanup.”
Use shell checks as the referee
Reviewer mode is not a substitute for evidence. Pair the review prompt with concrete checks inside Claude Code. For example: !git diff --stat, !git diff -- src/settings/PreferencesForm.tsx, !npm test -- PreferencesForm, and, for UI work, a browser reproduction or screenshot if your workflow supports it. Then ask Claude to reconcile its claims with the outputs.
A useful follow-up is: “Which claim in your review is directly proven by the test output, and which claim is still an inference?” That question catches a common AI failure mode: confident statements about UI behavior based only on reading code. Maintainers do not merge vibes. They merge evidence.
Failure modes
Claude Code can over-review. It may invent theoretical issues that are not worth fixing, especially in small patches. That is why I ask it to label each concern as blocking, follow-up, or acceptable. It can also under-review by repeating the implementation summary without challenging it. If the response has no risks, no untested cases, and no command output, ask again with a sharper prompt: “Assume this patch has one subtle bug. Where would you look first?”
Another failure mode is review drift. Claude may start commenting on unrelated formatting or old code. Anchor it to the diff. The review unit is not the whole repo; it is the behavior changed by this patch.
Rule of thumb
Use Claude Code to write code, but make it earn the merge as a reviewer. After every non-trivial patch, run a maintainer review pass: diff summary, behavior claim, evidence, untested risk, then one small correction. If the review cannot name what changed and how it was proven, the session is not done yet.