Review PR
Review a GitHub pull request, then either approve it cleanly or post structured,
severity-classified feedback. A correct PR is approved with no comments attached; a PR
with findings gets those findings and no approval.
When to use
"Review PR 412" / a pasted https://github.com/<org>/<repo>/pull/<n> URL.
"Is this PR safe to merge?" (answering "yes, nothing blocking" is a valid outcome)
"Look over these changes and tell me what's wrong."
"Approve this PR if it's fine."
Do not use this when the user wants to answer review comments already left on their own
PR; this skill produces feedback, it does not reply to it. Also skip this when the change
is not on GitHub yet (review the working tree directly) or the user only wants a PR
description.
Prerequisites
gh auth status # must be logged in
If gh is missing or unauthenticated, stop and tell the user; do not guess at PR content.
Command economy is a hard requirement. Every script here batches into a single API
call. Never poll, never loop a command per file, and never dump raw JSON into context. See
references/gh-commands.md for the anti-patterns to avoid.
Workflow
Load the PR in one call. Metadata, file churn, CI status, existing reviews, and
open threads all come back from a single request:
bash scripts/pr_context.sh <owner/repo> <n>
Then fetch the diff once and reuse it:
gh pr diff <n> --repo <owner/repo> > /tmp/pr-<n>.diff
Do not also run gh pr view, gh pr checks, or a per-file loop. pr_context.sh
already returned all of it.
Gate on CI before reviewing anything. Read the ## Checks section from step 1
first. If any context is listed FAIL, stop immediately: do not read the diff, do not
run the checklist, do not classify findings. Go straight to
references/outcome-ci-failing.md. A red build makes a line-by-line review
premature, since the fix will change the diff.
PENDING contexts are not failures; review normally and note anything still running.
Load the existing threads before auditing. Read ## Unresolved threads and
## Resolved threads from step 1 and keep both lists in mind for the whole review.
An unresolved thread is feedback already visible to the author, so re-posting it adds
noise and splits the discussion. A thread that someone resolved is fair game
again: if the underlying problem is still in the code, raise it, because resolving a
thread does not fix anything. See
references/existing-threads.md for how to match a finding to a thread and what to do
with a suppressed one.
Understand intent before judging code. Read the PR description and linked
issues. State in one line what the PR claims to do. If the description does not
explain the change, that is the first review comment.
Read the diff in context, not in isolation. For every non-trivial hunk, open the
full file. Reviewing only diff lines produces false positives. When several files need
full context, run gh pr checkout <n> once and read locally rather than making an API
call per file.
Check tests. CI is already green by step 2, so what remains is coverage: a
behavior change with no test change is a finding.
Apply the checklist. Work through references/review-checklist.md: correctness,
security, error handling, tests, API/back-compat, performance, readability. Skip
categories that genuinely do not apply.
Classify every finding with a severity prefix so the author can triage:
[Blocker] correctness, security, data loss, breaking change. Must be fixed.
[Suggestion] should be fixed before merge, but not dangerous.
[Nitpick] style or taste. Non-blocking, the author may decline.
An open question counts as a blocker or a suggestion depending on what it gates: use
[Blocker] when you cannot judge correctness without the answer.
Pick the outcome from the Outcomes table, read that one file, and follow it. It
carries the placement tiers, the comment shape, and the exact API call.
Never merge or close a PR. Approve only under Outcome A, request changes under
Outcome B or C.
Outcomes
Exactly one applies. Read its file and follow it; do not read the other two.
| Condition |
Outcome |
Read |
| Any CI check failing |
C |
references/outcome-ci-failing.md |
| CI green, nothing to change |
A |
references/outcome-approve.md |
| CI green, any finding at all |
B |
references/outcome-request-changes.md |
Outcome C overrides the others: a failing check ends the review whatever the diff looks
like. Between A and B, a single nitpick is enough to make it B.
Rules
These hold for every review; the outcome-specific rules live in that outcome's file.
- One API call per job. Use
pr_context.sh; never loop a command per file, and never
re-fetch data it already returned.
- Failing CI ends the review before it starts, with no counts line and no code comments.
- Approve only when there is nothing to change, and approve with no comments attached.
Any finding, down to one nitpick, is a request for changes.
- Never merge or close a PR.
- Never approve to be agreeable. If any category is unverified or any doubt remains, that
is Outcome B, not an approval.
- A clean PR gets a clean review. Finding nothing is a valid, complete result; never
invent findings to fill the template.
- Be direct about severity in both directions: do not soften a blocker into a nitpick, and
do not inflate a nitpick to justify a longer review.
- Every finding names a concrete fix. "This feels wrong" is not a review comment.
- The counts in the review body must equal the findings actually posted, so a finding
suppressed as a duplicate of an open thread is not counted.
- Never re-post a finding that an unresolved thread already covers. A thread that was
resolved without the code changing may be raised again.
- Judge the diff against the repo's existing conventions, not your own defaults, and do
not rewrite the author's style preferences as blockers.
- No vendor or AI attribution in review bodies.
References
Load these on demand, not up front.
references/review-checklist.md — the per-category checklist. Read at step 7, when
actually reviewing the diff.
references/writing-comments.md — placement tiers, the five-bullet comment structure,
and committable suggestions. Read under Outcome B, before posting findings.
references/existing-threads.md — how to suppress a finding another reviewer already
has open, and when a resolved thread may be re-raised. Read at step 3.
references/gh-commands.md — the review JSON payload, batched gh/GraphQL recipes,
and the costly anti-patterns. Read when posting, or when a command needs changing.
One outcome file, chosen by the verdict. Never more than one:
references/outcome-ci-failing.md — Outcome C, any check failing.
references/outcome-approve.md — Outcome A, nothing to change.
references/outcome-request-changes.md — Outcome B, any finding at all.
Scripts
| Script |
Calls |
Purpose |
scripts/pr_context.sh |
1 |
Whole review context: meta, files, checks, reviews, open and resolved threads |
1---2name: review-pr3description: When the user wants to review someone's GitHub pull request, approve it, or leave feedback on it. Also use when the user mentions "review this PR", "code review", "look at this pull request", "what do you think of this PR", "approve this PR", "request changes", or pastes a GitHub pull request URL asking for an opinion.4---5# Review PR67Review a GitHub pull request, then either approve it cleanly or post structured,8severity-classified feedback. A correct PR is approved with no comments attached; a PR9with findings gets those findings and no approval.1011## When to use1213- "Review PR 412" / a pasted `https://github.com/<org>/<repo>/pull/<n>` URL.14- "Is this PR safe to merge?" (answering "yes, nothing blocking" is a valid outcome)15- "Look over these changes and tell me what's wrong."16- "Approve this PR if it's fine."1718 Do not use this when the user wants to **answer** review comments already left on their own19 PR; this skill produces feedback, it does not reply to it. Also skip this when the change20 is not on GitHub yet (review the working tree directly) or the user only wants a PR21 description.2223## Prerequisites2425```bash26gh auth status # must be logged in27```2829If `gh` is missing or unauthenticated, stop and tell the user; do not guess at PR content.3031**Command economy is a hard requirement.** Every script here batches into a single API32call. Never poll, never loop a command per file, and never dump raw JSON into context. See33`references/gh-commands.md` for the anti-patterns to avoid.3435## Workflow36371. **Load the PR in one call.** Metadata, file churn, CI status, existing reviews, and38 open threads all come back from a single request:3940 ```bash41 bash scripts/pr_context.sh <owner/repo> <n>42 ```4344 Then fetch the diff once and reuse it:4546 ```bash47 gh pr diff <n> --repo <owner/repo> > /tmp/pr-<n>.diff48 ```4950 Do not also run `gh pr view`, `gh pr checks`, or a per-file loop. `pr_context.sh`51 already returned all of it.522. **Gate on CI before reviewing anything.** Read the `## Checks` section from step 153 first. If any context is listed `FAIL`, stop immediately: do not read the diff, do not54 run the checklist, do not classify findings. Go straight to55 `references/outcome-ci-failing.md`. A red build makes a line-by-line review56 premature, since the fix will change the diff.57 `PENDING` contexts are not failures; review normally and note anything still running.583. **Load the existing threads before auditing.** Read `## Unresolved threads` and59 `## Resolved threads` from step 1 and keep both lists in mind for the whole review.60 An unresolved thread is feedback already visible to the author, so re-posting it adds61 noise and splits the discussion. A thread that someone **resolved** is fair game62 again: if the underlying problem is still in the code, raise it, because resolving a63 thread does not fix anything. See64 `references/existing-threads.md` for how to match a finding to a thread and what to do65 with a suppressed one.664. **Understand intent before judging code.** Read the PR description and linked67 issues. State in one line what the PR claims to do. If the description does not68 explain the change, that is the first review comment.695. **Read the diff in context, not in isolation.** For every non-trivial hunk, open the70 full file. Reviewing only diff lines produces false positives. When several files need71 full context, run `gh pr checkout <n>` once and read locally rather than making an API72 call per file.736. **Check tests.** CI is already green by step 2, so what remains is coverage: a74 behavior change with no test change is a finding.757. **Apply the checklist.** Work through `references/review-checklist.md`: correctness,76 security, error handling, tests, API/back-compat, performance, readability. Skip77 categories that genuinely do not apply.788. **Classify every finding** with a severity prefix so the author can triage:7980 - `[Blocker]` correctness, security, data loss, breaking change. Must be fixed.81 - `[Suggestion]` should be fixed before merge, but not dangerous.82 - `[Nitpick]` style or taste. Non-blocking, the author may decline.8384 An open question counts as a blocker or a suggestion depending on what it gates: use85 `[Blocker]` when you cannot judge correctness without the answer.869. **Pick the outcome** from the Outcomes table, read that one file, and follow it. It87 carries the placement tiers, the comment shape, and the exact API call.8810. **Never merge or close a PR.** Approve only under Outcome A, request changes under89 Outcome B or C.9091## Outcomes9293Exactly one applies. Read its file and follow it; do not read the other two.9495| Condition | Outcome | Read |96| --- | --- | --- |97| Any CI check failing | **C** | `references/outcome-ci-failing.md` |98| CI green, nothing to change | **A** | `references/outcome-approve.md` |99| CI green, any finding at all | **B** | `references/outcome-request-changes.md` |100101Outcome C overrides the others: a failing check ends the review whatever the diff looks102like. Between A and B, a single nitpick is enough to make it B.103104## Rules105106These hold for every review; the outcome-specific rules live in that outcome's file.107108- One API call per job. Use `pr_context.sh`; never loop a command per file, and never109 re-fetch data it already returned.110- Failing CI ends the review before it starts, with no counts line and no code comments.111- Approve only when there is nothing to change, and approve with no comments attached.112 Any finding, down to one nitpick, is a request for changes.113- Never merge or close a PR.114- Never approve to be agreeable. If any category is unverified or any doubt remains, that115 is Outcome B, not an approval.116- A clean PR gets a clean review. Finding nothing is a valid, complete result; never117 invent findings to fill the template.118- Be direct about severity in both directions: do not soften a blocker into a nitpick, and119 do not inflate a nitpick to justify a longer review.120- Every finding names a concrete fix. "This feels wrong" is not a review comment.121- The counts in the review body must equal the findings actually posted, so a finding122 suppressed as a duplicate of an open thread is not counted.123- Never re-post a finding that an unresolved thread already covers. A thread that was124 resolved without the code changing may be raised again.125- Judge the diff against the repo's existing conventions, not your own defaults, and do126 not rewrite the author's style preferences as blockers.127- No vendor or AI attribution in review bodies.128129## References130131Load these on demand, not up front.132133- `references/review-checklist.md` — the per-category checklist. Read at step 7, when134 actually reviewing the diff.135- `references/writing-comments.md` — placement tiers, the five-bullet comment structure,136 and committable suggestions. Read under Outcome B, before posting findings.137- `references/existing-threads.md` — how to suppress a finding another reviewer already138 has open, and when a resolved thread may be re-raised. Read at step 3.139- `references/gh-commands.md` — the review JSON payload, batched `gh`/GraphQL recipes,140 and the costly anti-patterns. Read when posting, or when a command needs changing.141142One outcome file, chosen by the verdict. Never more than one:143144- `references/outcome-ci-failing.md` — Outcome C, any check failing.145- `references/outcome-approve.md` — Outcome A, nothing to change.146- `references/outcome-request-changes.md` — Outcome B, any finding at all.147148## Scripts149150| Script | Calls | Purpose |151| ----------------------- | ----- | ------------------------------------------------------------------- |152| `scripts/pr_context.sh` | 1 | Whole review context: meta, files, checks, reviews, open and resolved threads |