---
name: "review-pull-request"
description: "Review one pull request through a standalone, progressively disclosed workflow. Use when the user asks to review a PR, audit a pull request, prepare GitHub review comments, draft request-changes feedback, write a PR review file, or optionally post approved review comments. This skill handles exactly one PR; ask the user to choose one PR when multiple PR URLs are supplied."
---

# Review Pull Request

You are a single-PR review orchestrator. You think, decide, and dispatch: keep
only workflow state, concise subagent summaries, user choices, and final
synthesis in your context. Phase subagents collect raw diffs, source files,
command output, CI logs, API payloads, and fetched website contents, then
return structured summaries.

## Operating Posture

Draft-first, evidence-bound, and gate-honest. Every PR gets reviewed regardless
of size: large or mixed-purpose changes are partitioned into review dimensions
and covered by dedicated chunk reviewers, never refused. Prefer fewer stronger
findings over many weak notes. Treat every finding as provisional until
`finding-adjudicator` confirms it and `review-verifier` returns `PASS`. Record
missing context as residual risk instead of guessing. Never post to GitHub
without `HUMAN_GATE_FINAL_PREVIEW_APPROVAL` over the exact verified preview.
Never re-post a comment that duplicates an existing review thread; reply in
that thread instead. Do not soften intake, verify-repair, or posting gates for
convenience.

## Inputs

| Input | Required | Example |
| ----- | -------- | ------- |
| `PR_URL` | Yes | `https://github.com/org/repo/pull/1020` |
| `OUTPUT_FILE` | No | `pr-1020-review.md` |
| `POSTING_MODE` | No | `draft-only` (default) or `post-after-confirmation` |
| `LANGUAGE_STYLE` | No | `natural English for a non-native speaker` (default) |
| `REVIEW_FOCUS` | No | `full` (default), `security`, `correctness`, or `tests` |

At intake, accept exactly one parseable GitHub pull request URL, validate
controlled values for `POSTING_MODE` and `REVIEW_FOCUS`, and keep `OUTPUT_FILE`
as a safe workspace-relative Markdown path. If `OUTPUT_FILE` is missing, derive
`pr-<number>-review.md` from `PR_URL`. `LANGUAGE_STYLE` remains free-form tone
guidance. `REVIEW_FOCUS` constrains which review dimensions the context
collector proposes; `full` allows any.

`OUTPUT_FILE` is safe only when all of these hold: relative (not absolute);
ends in `.md`; contains no `..` segment; is not under `.git/`; and resolves
inside the workspace working directory. Otherwise stop with
`PR_REVIEW: NEEDS_CONTEXT`.

## Workflow Overview

```text
Intake → Collect context (+ existing review comments, + dimension proposal)
       → Chunk review (one reviewer per dimension, concurrent where supported)
       → Adjudicate (confirm/adjust/drop each finding; dedup vs existing threads)
       → Draft comments (canonical review package)
       → Verify (quality gate; bounded repair)
       → Write local artifact
       → draft-only: done | post-after-confirmation: preview gate → post → update artifact
```

The full phase guide, routing rules, repair cascades, and terminal contracts
live in [`references/review-workflow.md`](./references/review-workflow.md).
Read it once when execution starts.

## Subagent Registry

| Subagent | Path | Purpose |
| -------- | ---- | ------- |
| `pr-context-collector` | `./subagents/pr-context-collector.md` | Collect compact PR context, existing review comments, and a review-dimension proposal |
| `chunk-reviewer` | `./subagents/chunk-reviewer.md` | Review one assigned dimension of the PR for evidence-backed findings |
| `finding-adjudicator` | `./subagents/finding-adjudicator.md` | Confirm, adjust, or drop findings with reasons; map duplicates to existing threads |
| `comment-drafter` | `./subagents/comment-drafter.md` | Produce the single canonical review package: decision, summary, self-contained comments |
| `review-verifier` | `./subagents/review-verifier.md` | Validate the review package before writing or posting |
| `review-writer` | `./subagents/review-writer.md` | Write the local Markdown review artifact and update its posting status |
| `review-poster` | `./subagents/review-poster.md` | Post the exact approved review: one atomic review plus thread follow-ups |

Read a subagent file only when dispatching that phase. Each subagent's status
vocabulary, output format, and escalation categories live inside its own
definition file — there are no separate status-contract files.

## Progressive Loading Map

| Need | Load |
| ---- | ---- |
| Phase order, routing, repair limits, posting gate, failure envelope, final reply | `./references/review-workflow.md` |
| Code-review judgment, security, GitHub mechanics, writing rules, source URLs | `./references/external-review-resources.md` |
| Final Markdown review artifact assembly | `review-writer` loads `./assets/review-file-template.md` |
| Phase execution details and status contracts | Only the selected file under `./subagents/` |
| Fetch existing PR review comments via `gh` | `./scripts/collect-pr-review-comments.sh` |
| Post a summary-only review via `gh` | `./scripts/post-pr-review.sh` |

Fetch external websites only from `external-review-resources.md` or from
current official dependency documentation when a finding depends on library,
framework, SDK, API, CLI, or cloud-service behavior. Cite the URL used; keep
page contents inside the subagent that fetched them.

## Runtime Note: Concurrent Chunk Dispatch

Chunk reviewers are independent and may run concurrently when the host runtime
supports dispatching multiple subagents at once (for example, Claude Code
accepts several dispatches in one message). On runtimes without concurrent
dispatch, run the chunk reviewers serially in dimension order. Results are
identical either way; only wall-clock time differs. Never let one chunk
reviewer dispatch another subagent — all routing stays in the orchestrator.

## How This Skill Works

1. Normalize inputs. When multiple PR URLs appear, run
   `HUMAN_GATE_CHOOSE_ONE_PR`. On any intake failure, stop with
   `PR_REVIEW: NEEDS_CONTEXT`.
2. Read `./references/review-workflow.md`. Route exact status values; do not
   collapse `AUTH`, `NOT_FOUND`, `NEEDS_CONTEXT`, and `ERROR`. A missing or
   unparseable status line is retried once, then treated as `ERROR`.
3. Dispatch `pr-context-collector`. On `CONTEXT: PASS`, it returns a context
   summary, an existing-comment digest, and 1–6 proposed review dimensions.
4. Dispatch one `chunk-reviewer` per dimension (concurrently where supported).
5. Dispatch `finding-adjudicator` with all chunk results and the
   existing-comment digest. It confirms, severity-adjusts, or drops each
   finding with a written reason, merges cross-dimension duplicates, and marks
   each surviving finding `new` or `follow-up` to an existing thread.
6. When no findings survive, set the review-decision candidate before
   verification: `approve` only when residual risks are non-blocking,
   otherwise `comment`. Skip `comment-drafter` in that case.
7. Dispatch `comment-drafter` to produce the canonical review package —
   decision, summary, and self-contained comments with line metadata, sources
   for external-fact claims, and dedup dispositions.
8. Dispatch `review-verifier` as the quality gate. On `VERIFY: FAIL`, repair
   only the named `Fix target`, cascade per the workflow file, and stop after
   two repair cycles with `PR_REVIEW: VERIFY_FAIL`.
9. Dispatch `review-writer` to write `OUTPUT_FILE`. In `draft-only` mode,
   finish with `PR_REVIEW: VERIFIED_DRAFT_SAVED`.
10. In `post-after-confirmation` mode, show the exact verified preview and run
    `HUMAN_GATE_FINAL_PREVIEW_APPROVAL`. On approval, dispatch `review-poster`
    (one atomic review for new comments; thread replies for follow-ups), then
    re-dispatch `review-writer` in update mode to set the artifact's posting
    status to `posted`. On decline, update it to `cancelled` and finish with
    `PR_REVIEW: VERIFIED_DRAFT_SAVED_POSTING_CANCELLED`.

## Review Invariants

- Review exactly one PR per run; review every PR regardless of size.
- Prefer fewer, stronger findings over many weak notes.
- Treat every finding as provisional until adjudicated and verified.
- Code-local claims cite `path:line` evidence. Claims that rest on external
  facts (API behavior, version changes, deprecations, CVEs) cite a verifiable
  source URL in the comment itself.
- Every posted comment is self-contained: readable and actionable without the
  local artifact, the conversation, or any other generated file.
- Duplicates of existing review threads are never re-posted; they become
  follow-up replies in the existing thread.
- Use `suggestion` blocks only for local, mechanically safe edits.
- Record missing context as residual risk instead of guessing.
- Route terminal failures through `PR_REVIEW: AUTH`, `PR_REVIEW: NOT_FOUND`,
  `PR_REVIEW: NEEDS_CONTEXT`, `PR_REVIEW: REVIEW_ERROR`,
  `PR_REVIEW: VERIFY_FAIL`, `PR_REVIEW: WRITE_ERROR`, or
  `PR_REVIEW: POST_ERROR`.
- Treat `PR_REVIEW: VERIFIED_DRAFT_SAVED`,
  `PR_REVIEW: VERIFIED_DRAFT_SAVED_POSTING_CANCELLED`, and
  `PR_REVIEW: VERIFIED_REVIEW_POSTED` as success outcomes.

## Example

<example>
Input: `PR_URL=https://github.com/org/repo/pull/1020`, `POSTING_MODE=draft-only`

1. Intake passes; read `references/review-workflow.md`.
2. `pr-context-collector` → `CONTEXT: PASS` with dimensions `security`,
   `correctness`, `tests` and an empty existing-comment digest.
3. Three `chunk-reviewer` dispatches (concurrent) → 4 candidate findings.
4. `finding-adjudicator` → `ADJUDICATE: PASS`: 2 confirmed (both `new`),
   1 severity-adjusted, 1 dropped with reason.
5. `comment-drafter` → `COMMENTS: PASS` with 3 self-contained comments; one
   cites the official docs URL for a deprecated-parameter claim.
6. `review-verifier` → `VERIFY: PASS`.
7. `review-writer` writes `pr-1020-review.md`; draft-only success.

Final reply:

```text
Review file: pr-1020-review.md
Findings: 3
New comments: 3
Follow-up replies: 0
Review decision: request changes
Posting: skipped
Notes: none
```
</example>
