oh-review
Review a PR, check it against the linked issue's requirements, and post structured feedback as a GitHub review. Read-only except for the review comment itself — no code changes, no commits.
Invocation
/oh-review <pr-number>
<pr-number> - the pull request number to review
Prerequisites
- Repo context: Run from the repo root where the PR exists
- GitHub CLI:
gh must be authenticated
Flow
Load project background from AGENTS.md and relevant .oh/ artifacts. Use RNA repo_map and search first for repository exploration. If RNA is empty or incomplete, broaden queries and remove filters; before any Read/Grep/Bash fallback, document the reason and record a friction event in the repository session context.
Fetch PR metadata:
gh pr view <pr-number> --json title,body,headRefName,baseRefName,additions,deletions,changedFiles,state,mergeable
Abort if PR is not open.
Read the linked issue (CRITICAL) — the issue is the source of truth for requirements:
- Parse "Closes #N" / "Fixes #N" / "Resolves #N" from PR body
- Fetch the full issue:
gh issue view <N> --json title,body
- Extract acceptance criteria, goal, context, constraints
- If no linked issue found, note "No linked issue — cannot verify requirements" and review code quality only
Fetch the PR diff:
gh pr diff <pr-number>
Review the diff against:
- The linked issue requirements first — are acceptance criteria met? Does the implementation match the goal? Are constraints respected?
- Code quality (bugs, missing error handling, edge cases)
- Consistency with existing patterns in the repo
- Missing tests or documentation
Write a structured review to a temp file:
## Review: PR #<number> — <title>
### Requirements Check (from #<issue>)
- [ ] <acceptance criterion 1> — met/not met/partially met
- [ ] <acceptance criterion 2> — met/not met/partially met
### Blockers (P0-P1)
- <issue with explanation and suggested fix>
### Improvements (P2-P3)
- <issue with explanation>
### Clean
- <what looks good>
### Follow-up Work
- <concrete items that should be separate issues/PRs>
Post the review on the PR:
If blockers found or requirements not met:
gh pr review <pr-number> --request-changes --body-file /tmp/review-<pr-number>.md
If no blockers and requirements met:
gh pr review <pr-number> --approve --body-file /tmp/review-<pr-number>.md
Signal completion:
- Success with blockers:
signal_completion(status: "blocked", blocker: "PR has N blockers — see review comment")
- Success clean:
signal_completion(status: "success", message: "Approved — N improvements noted")
- Error:
signal_completion(status: "error", error: "<reason>")
Review Principles
- The issue is the spec. The review must check the PR against the issue requirements, not just review code in isolation. A PR that passes code review but misses requirements is a failure.
- Be opinionated but structured — blockers vs improvements vs nits
- Read the full diff, not just file names — actually understand the changes
- Follow-up items should be concrete enough to become issues (not vague "consider refactoring")
- Do NOT auto-create follow-up issues — just post them as review comments. The human decides what to act on.
- Keep the skill read-only except for the review comment itself — no code changes, no commits
Exit Conditions
- Success: Review posted, PR approved (no blockers)
- Blocked: Review posted with request-changes (has blockers)
- Error: Could not fetch PR, diff, or post review
Completion Signaling (MANDATORY)
CRITICAL: You MUST signal completion when done. Call the signal_completion tool as your FINAL action.
Signal based on outcome:
| Outcome |
Call |
| Review posted, PR approved |
signal_completion(status: "success", message: "Approved — N improvements noted") |
| Review posted, changes requested |
signal_completion(status: "blocked", blocker: "PR has N blockers — see review comment") |
| Unrecoverable failure |
signal_completion(status: "error", error: "<reason>") |
If you do not signal, the orchestrator will not know you are done and the session becomes orphaned.
Fallback: If the signal_completion tool is not available, output your completion status as your final message in the format: COMPLETION: status=<status> message=<msg> or COMPLETION: status=<status> error=<reason>.
Example
$ /oh-review 99
Fetching PR #99...
PR: "Fix validation bug in auth module"
State: open, +147 -23, 4 files changed
Parsing linked issue...
Found: Closes #42
Fetching issue #42...
Issue: "Fix validation bug in auth module"
Acceptance criteria:
1. Empty string validation returns error
2. Tests cover edge cases
3. No changes to public API
Fetching PR diff...
Reviewing diff against requirements...
Posting review...
gh pr review 99 --approve --body-file /tmp/review.md
Review posted:
Requirements: 3/3 met
Blockers: 0
Improvements: 2
Follow-ups: 1
signal_completion(status: "success", message: "Approved — 2 improvements noted")
Done.
ARGUMENTS:
1---2name: oh-review3description: Review a PR against its linked issue requirements, post structured feedback4---56# oh-review78Review a PR, check it against the linked issue's requirements, and post structured feedback as a GitHub review. Read-only except for the review comment itself — no code changes, no commits.910## Invocation1112`/oh-review <pr-number>`1314- `<pr-number>` - the pull request number to review1516## Prerequisites1718- **Repo context**: Run from the repo root where the PR exists19- **GitHub CLI**: `gh` must be authenticated2021## Flow22231. Load project background from `AGENTS.md` and relevant `.oh/` artifacts. Use RNA `repo_map` and `search` first for repository exploration. If RNA is empty or incomplete, broaden queries and remove filters; before any Read/Grep/Bash fallback, document the reason and record a friction event in the repository session context.24252. Fetch PR metadata:2627 ```bash28 gh pr view <pr-number> --json title,body,headRefName,baseRefName,additions,deletions,changedFiles,state,mergeable29 ```3031 Abort if PR is not open.32333. **Read the linked issue (CRITICAL)** — the issue is the source of truth for requirements:34 - Parse "Closes #N" / "Fixes #N" / "Resolves #N" from PR body35 - Fetch the full issue: `gh issue view <N> --json title,body`36 - Extract acceptance criteria, goal, context, constraints37 - If no linked issue found, note "No linked issue — cannot verify requirements" and review code quality only38394. Fetch the PR diff:4041 ```bash42 gh pr diff <pr-number>43 ```44455. Review the diff against:46 - **The linked issue requirements first** — are acceptance criteria met? Does the implementation match the goal? Are constraints respected?47 - Code quality (bugs, missing error handling, edge cases)48 - Consistency with existing patterns in the repo49 - Missing tests or documentation50516. Write a structured review to a temp file:5253 ```markdown54 ## Review: PR #<number> — <title>5556 ### Requirements Check (from #<issue>)57 - [ ] <acceptance criterion 1> — met/not met/partially met58 - [ ] <acceptance criterion 2> — met/not met/partially met5960 ### Blockers (P0-P1)61 - <issue with explanation and suggested fix>6263 ### Improvements (P2-P3)64 - <issue with explanation>6566 ### Clean67 - <what looks good>6869 ### Follow-up Work70 - <concrete items that should be separate issues/PRs>71 ```72737. Post the review on the PR:74 - If blockers found or requirements not met:7576 ```bash77 gh pr review <pr-number> --request-changes --body-file /tmp/review-<pr-number>.md78 ```7980 - If no blockers and requirements met:8182 ```bash83 gh pr review <pr-number> --approve --body-file /tmp/review-<pr-number>.md84 ```85868. Signal completion:87 - Success with blockers: `signal_completion(status: "blocked", blocker: "PR has N blockers — see review comment")`88 - Success clean: `signal_completion(status: "success", message: "Approved — N improvements noted")`89 - Error: `signal_completion(status: "error", error: "<reason>")`9091## Review Principles9293- **The issue is the spec.** The review must check the PR against the issue requirements, not just review code in isolation. A PR that passes code review but misses requirements is a failure.94- Be opinionated but structured — blockers vs improvements vs nits95- Read the full diff, not just file names — actually understand the changes96- Follow-up items should be concrete enough to become issues (not vague "consider refactoring")97- Do NOT auto-create follow-up issues — just post them as review comments. The human decides what to act on.98- Keep the skill read-only except for the review comment itself — no code changes, no commits99100## Exit Conditions101102- **Success**: Review posted, PR approved (no blockers)103- **Blocked**: Review posted with request-changes (has blockers)104- **Error**: Could not fetch PR, diff, or post review105106## Completion Signaling (MANDATORY)107108**CRITICAL: You MUST signal completion when done.** Call the `signal_completion` tool as your FINAL action.109110**Signal based on outcome:**111112| Outcome | Call |113| --------- | ------ |114| Review posted, PR approved | `signal_completion(status: "success", message: "Approved — N improvements noted")` |115| Review posted, changes requested | `signal_completion(status: "blocked", blocker: "PR has N blockers — see review comment")` |116| Unrecoverable failure | `signal_completion(status: "error", error: "<reason>")` |117118**If you do not signal, the orchestrator will not know you are done and the session becomes orphaned.**119120**Fallback:** If the `signal_completion` tool is not available, output your completion status as your final message in the format: `COMPLETION: status=<status> message=<msg>` or `COMPLETION: status=<status> error=<reason>`.121122## Example123124```text125$ /oh-review 99126127Fetching PR #99...128PR: "Fix validation bug in auth module"129State: open, +147 -23, 4 files changed130131Parsing linked issue...132Found: Closes #42133134Fetching issue #42...135Issue: "Fix validation bug in auth module"136Acceptance criteria:137 1. Empty string validation returns error138 2. Tests cover edge cases139 3. No changes to public API140141Fetching PR diff...142Reviewing diff against requirements...143144Posting review...145gh pr review 99 --approve --body-file /tmp/review.md146147Review posted:148 Requirements: 3/3 met149 Blockers: 0150 Improvements: 2151 Follow-ups: 1152153signal_completion(status: "success", message: "Approved — 2 improvements noted")154Done.155```156157ARGUMENTS: