pr-review

SKILL.md

PR Review Workflow

Systematic workflow for checking, responding to, and reporting on PR feedback from any source — human reviewers, review bots (CodeRabbit, Gemini, Codex, Snyk, etc.), or AI agents.

Requirements: GitHub repository with GitHub CLI (gh) installed and authenticated.

Key insight: PR feedback arrives through three different channels (conversation comments, inline threads, review submissions). Missing any channel means missing feedback. This skill ensures all channels are checked systematically.

Self-Contained Constraint

ALL operations MUST go through the provided scripts. Never run raw git, gh, date, or bash heredocs (cat > file << 'EOF') when a script or agent tool covers the same operation.

Instead of (prohibited) Use
git status, git branch, gh pr view, gh repo view get-context.sh
git add, git commit, git push commit-and-push.sh
git checkout -b, git switch -c open-branch.sh
gh pr create create-pr.sh
gh api repos/.../comments, gh pr view --json check-pr-feedback.sh
gh api ... -f body= (posting comments) post-fix-report.sh or reply-to-inline.sh
date -u +%Y-%m-%dT%H:%M:%SZ get-context.sh (outputs timestamp: field)
cat > file.md << 'EOF' (bash heredoc) Agent's native Write tool to .agents/scratch/, then pass file path to script
echo "..." | script.sh (piped stdin) Script's direct flag: -m, --body, or file-path argument

Entry point: Always start with get-context.sh to detect current state. Use its output to decide next steps via the Decision Tree below.

File creation: When a script accepts a file path (e.g., create-pr.sh --body, post-fix-report.sh), write the file to .agents/scratch/ using the agent's native Write tool, then pass the path to the script. Never use bash heredocs to create temp files.

  • Directory: .agents/scratch/ — inside the repo, avoids out-of-tree write permission prompts
  • Setup: Run mkdir -p .agents/scratch before the first write if it doesn't exist
  • Gitignore: Ensure .agents/ is in the project's .gitignore
  • Cleanup: Scripts auto-delete scratch files after reading them, so the file won't exist on subsequent runs (no overwrite prompts)

Acceptable raw commands: Project-specific test/build commands (npm test, npm run <script>, pytest, make build, etc.) are fine — these are not PR workflow operations. For creating test fixtures, use the agent's native Write tool (write to .agents/scratch/) instead of printf or echo redirects. Avoid echo ... | command — piped commands trigger permission prompts in sandboxed environments.

Entry Point Decision Tree

Run get-context.sh first. Based on its output, follow the matching path:

on_default has_changes pr_number Action sequence
true true empty open-branch.shcommit-and-push.shcreate-pr.sh --invoke --title "..."
true false empty Ask user what to do (no changes to work with)
false any has number check-pr-feedback.sh (existing PR — review cycle)
false true empty commit-and-push.shcreate-pr.sh --invoke --title "..."
false false empty create-pr.sh --invoke --title "..." (branch exists, already pushed)

For loop mode, see the Loop Mode section — the decision tree gets you started, then the loop takes over.

Quick Commands

Script path resolution: Before running any script, determine the correct base path. Check in this order:

  1. ~/.claude/skills/pr-review/scripts/ — global install for Claude Code
  2. Other global paths by preference of the agent

Use whichever path exists. Script paths below use the global form; substitute accordingly for your agent or install method.

Get Context (Entry Point)

~/.claude/skills/pr-review/scripts/get-context.sh

Outputs key-value pairs: branch, on_default, has_changes, change_summary, pr_number, pr_url, pr_state, timestamp, repo. Use timestamp for wait-for-reviews.sh --since. Gracefully handles missing gh (empty PR/repo fields). Exits 1 only on detached HEAD or not in a git repo.

Open Branch (Idempotent)

~/.claude/skills/pr-review/scripts/open-branch.sh [BRANCH_NAME]

If already on a non-main/master branch, prints branch name and exits. If on main/master, creates branch, switches, and pushes with -u. Default name: review-loop-YYYYMMDD-HHMMSS.

Check All Feedback (CRITICAL - Use First)

~/.claude/skills/pr-review/scripts/check-pr-feedback.sh [PR_NUMBER]

Checks all three channels: conversation comments, inline comments, reviews.

If no PR number provided, detects current PR from branch.

Reply to Inline Comment

~/.claude/skills/pr-review/scripts/reply-to-inline.sh <COMMENT_ID> "Your message"
~/.claude/skills/pr-review/scripts/reply-to-inline.sh <COMMENT_ID> .agents/scratch/reply.md

Replies in-thread to inline comments. Accepts message as inline text or a file path (auto-detects). Use file path when message contains ${...} or other shell-sensitive syntax to avoid permission prompts. Uses -F flag (not --raw-field) which properly handles numeric ID conversion in gh CLI.

Must be run from repository root with an active PR branch.

Important: Always sign inline replies with your agent identity (e.g., —Claude Sonnet 4.5, —GPT-4, —Custom Agent) to distinguish agent responses from human responses in the GitHub UI.

Invoke Review Agents

~/.claude/skills/pr-review/scripts/invoke-review-agents.sh [--agents SLUG,...] [--format-only] [PR_NUMBER]

Posts trigger comments to start agent reviews. Without --agents, invokes all known agents (Codex, Gemini, CodeRabbit). Use --list to see available agents. Use --format-only to print trigger text to stdout without posting (for embedding in PR body).

Post Fix Report

~/.claude/skills/pr-review/scripts/post-fix-report.sh [PR_NUMBER] .agents/scratch/fix-report.md

Create PR (Idempotent)

~/.claude/skills/pr-review/scripts/create-pr.sh --title "PR title" --body .agents/scratch/pr-body.md [--invoke]

Or body as inline text:

~/.claude/skills/pr-review/scripts/create-pr.sh --title "PR title" --body "Short description"

--body auto-detects: if the value is a readable file, reads from it; otherwise treats as text. Idempotent: if a PR already exists, outputs its info. Refuses to run on main/master. Pushes branch if not yet pushed.

--invoke appends review agent trigger text to the PR body (via invoke-review-agents.sh --format-only), avoiding a separate trigger comment that causes double-invocations when auto-review is enabled.

Output prefixes (machine-parseable):

  • EXISTS: <url> — PR already existed for this branch
  • CREATED: <url> — new PR was created

Commit and Push

~/.claude/skills/pr-review/scripts/commit-and-push.sh -m "fix: address review feedback"

Stages all changes, commits, and pushes. Refuses to run on main/master. Never force-pushes. Outputs commit hash and branch.

Wait for Reviews

~/.claude/skills/pr-review/scripts/wait-for-reviews.sh [PR_NUMBER] --since TIMESTAMP [--timeout 600] [--interval 30]

Polls all three feedback channels for new comments posted after TIMESTAMP by non-self users. Exits 0 when new feedback detected, exits 1 on timeout. Default: 10 min timeout, 30s interval.

Check New Feedback (Differential)

~/.claude/skills/pr-review/scripts/check-new-feedback.sh [PR_NUMBER] --since TIMESTAMP

Like check-pr-feedback.sh but only shows feedback created after TIMESTAMP, excluding self-posted comments. Use in loop mode to distinguish new from already-addressed feedback. Ends with a summary line: Summary: N conversation, M inline, K reviews.

Commit Workflows

Always use commit-and-push.sh for committing. It stages all changes, commits, pushes, and enforces branch safety (refuses main/master, never force-pushes).

~/.claude/skills/pr-review/scripts/commit-and-push.sh -m "<type>: <outcome>"

Commit Type Conventions

Types: feat, fix, refactor, docs, chore, test

Self-Check Before Commit

Before committing, verify:

  1. Test changes — Run project-specific tests (npm test, pytest, etc.) if modifying working code
  2. Check latest feedback — Run check-pr-feedback.sh to catch any new comments
  3. User confirmation — If user is active in session, ask before committing
  4. Verify claims — If Fix Report says "verified:", actually verify

PR Creation

Set Up Template (Once)

Create .github/pull_request_template.md:

## Summary
-

## How to test
-

## Notes
- Review feedback may arrive in conversation comments, inline threads, or review submissions. Check all channels.

Or copy from assets/pr_template.md.

Create PR

Fill Summary, How to test, and Notes sections.

Code Review Coordination

Feedback Channels

Channel Reviewer Type Format
Conversation AI agents, humans Top-level comments
Inline Review bots (CodeRabbit, Gemini, Codex, Snyk, etc.), humans File/line threads
Reviews Humans, some bots Approve/Request Changes + optional body

Critical Rule: Check ALL Three Channels

~/.claude/skills/pr-review/scripts/check-pr-feedback.sh

Why: Different reviewers post in different channels. Missing any channel = missing feedback.

Three channels:

  1. Conversation comments — general discussion, agent reviews
  2. Inline comments — file/line-specific feedback from any reviewer
  3. Reviews — approval state + optional body

Critical Evaluation of Feedback

Never trust review feedback at face value. Before acting on any comment — whether from a human reviewer, review bot, or AI agent — critically evaluate it:

  1. Verify the claim — Read the actual code being referenced. Does the reviewer's description match reality? Reviewers (especially bots) may misread context, reference wrong lines, or describe code that doesn't exist.
  2. Check for hallucinations — Review bots may fabricate issues: non-existent variables, imagined type mismatches, phantom security vulnerabilities. Always confirm the issue exists before fixing it.
  3. Assess correctness — Even if the issue is real, the suggested fix may be wrong. Evaluate whether the suggestion would break existing behavior, introduce regressions, or conflict with project conventions.
  4. Test before committing — If a suggestion modifies working code, run tests before and after to confirm the change is actually an improvement.

If a review comment is incorrect, respond with a clear explanation of why rather than applying a bad fix. Use WONTFIX status with reasoning in the Fix Report.

Responding to Inline Comments

  1. Critically evaluate the feedback (see above), then address it in code if valid
  2. Reply inline to each comment (sign with agent identity):
# Short messages — inline text:
~/.claude/skills/pr-review/scripts/reply-to-inline.sh <COMMENT_ID> "Fixed @ abc123. [details] —[Your Agent Name]"
# Messages with ${...} or shell-sensitive syntax — write to file first, pass path:
~/.claude/skills/pr-review/scripts/reply-to-inline.sh <COMMENT_ID> .agents/scratch/reply.md
  1. Include in Fix Report (conversation comment) — the Fix Report summarizes all changes, but inline replies ensure each comment gets a direct acknowledgment

Invoking Review Agents

Run invoke-review-agents.sh when check-pr-feedback.sh returns empty output from all three channels — no feedback means no agents have reviewed yet.

# No feedback on the PR? Invoke all agents:
~/.claude/skills/pr-review/scripts/invoke-review-agents.sh

# User mentioned specific agents (e.g., "ask Gemini and Codex to review"):
~/.claude/skills/pr-review/scripts/invoke-review-agents.sh --agents gemini,codex

Agent selection from prompt: If the user's prompt names specific agents (e.g., "have Codex review this"), use --agents with the matching slug(s). Otherwise invoke all.

Embedding in PR body: When creating a new PR with create-pr.sh --invoke, trigger text is appended to the PR body automatically (via --format-only). This avoids a separate trigger comment that would cause double-invocations when auto-review is enabled. Only use invoke-review-agents.sh directly when the PR already exists.

After invoking: Inform the user that trigger comments were posted and suggest running check-pr-feedback.sh again once agents have had time to respond (typically a few minutes).

See references/review-agents.md for the full agent registry and instructions for adding new agents.

Fix Reporting

After addressing feedback, always post ONE conversation comment (Fix Report). This is separate from requesting re-review — the Fix Report documents what was done, even if no re-review is needed.

Write the report with the agent's Write tool (e.g., to .agents/scratch/fix-report.md), then post it:

~/.claude/skills/pr-review/scripts/post-fix-report.sh .agents/scratch/fix-report.md

Fix Report format:

### Fix Report

- [file.ext:L10 Symbol]: FIXED @ abc123 — verified: `npm test` passes
- [file.ext:L42 fn]: WONTFIX — reason: intentional per AGENTS.md
- [file.ext:L100 class]: DEFERRED — tracking: #123
- [file.ext:L200 method]: QUESTION — Should this handle X?

Optionally, if re-review is needed, add @reviewer-username please re-review. at the end of the body.

Fix Statuses

Status Required Info
FIXED Commit hash + verification command/result
WONTFIX Reason (cite docs if applicable)
DEFERRED Issue/ticket link
QUESTION Specific question to unblock

See references/fix-report-examples.md for real-world examples.

Use assets/fix-report-template.md as starting point.

Review Format (For Agent-Reviewers)

Agent-reviewers MUST post ONE top-level conversation comment:

### Review - Actionable Findings

**Blocking**
- path/file.ext:L10-L15 (Symbol): Issue → Fix → Verify: `command`

**Optional**
- path/file.ext:L100 (class): Improvement → Fix

Rules:

  • Blocking MUST include verification (runnable command or objective check)
  • Use file:line + symbol anchor
  • Actionable, not prose
  • Group by severity

Do NOT:

  • Create inline file/line comments
  • Submit GitHub review submissions
  • Post multiple separate comments

Why: Inline comments harder to retrieve. Conversation comments deterministic.

Re-Review Loop

After Fix Report:

  1. Request re-review: @reviewer please re-review. See Fix Report.
  2. Tag ALL reviewers who provided feedback
  3. If QUESTION items: Wait for clarification
  4. If blocking feedback was only provided inline: Mention it was addressed, optionally ask to mirror to conversation for future determinism

Loop Mode

Activate when the user's prompt requests a review loop, review cycle, or similar — in any words — meaning: run the full review-fix-review cycle autonomously until no new feedback remains.

Default max rounds: 5. Override with user instruction if needed.

Loop workflow:

  1. Branchopen-branch.sh (idempotent — creates branch if on main/master)
  2. PRcreate-pr.sh --invoke --title "..." --body <path> — write body with agent Write tool, pass path. Capture output prefix (CREATED: / EXISTS:)
  3. Invoke — Round 1: if step 1 output CREATED:, skip (triggers in PR body). If EXISTS:, run invoke-review-agents.sh. Rounds 2+: agents triggered by @-mentions in previous Fix Report footer (no separate invoke step)
  4. Waitwait-for-reviews.sh --since <timestamp> — use timestamp from get-context.sh (run after last commit, or after step 1 for round 1). Polls until new feedback or timeout
  5. Checkcheck-pr-feedback.sh (ALL feedback, all channels)
  6. Process — compare all feedback against previous Fix Reports. Address only: (a) items not covered in any Fix Report, (b) items with new follow-up comments after the last Fix Report. Critically evaluate each item before fixing
  7. Fix code, commitcommit-and-push.sh -m "fix: address review feedback round N"
  8. Get timestampget-context.sh (capture timestamp for next wait step)
  9. Reply inlinereply-to-inline.sh for each addressed inline comment; sign with agent identity; tag the reviewer's @github-user
  10. Fix Report — write report with agent Write tool, then post-fix-report.sh <PR> <path>
    • Before max: footer has @-mentions + @coderabbitai review on its own line
    • At max: footer has max-reached message (see below)
  11. Loop — if ROUND < MAX_ROUNDS, go to step 3

Why full check instead of differential: Using check-new-feedback.sh --since in the check step risks missing feedback that arrives during the fix phase (e.g., Gemini posts while agent is fixing Codex's comments). The full check + Fix Report comparison approach is gap-free.

Termination conditions (any):

  • Step 5 finds nothing new to process (all feedback already addressed in Fix Reports)
  • wait-for-reviews.sh times out (no new feedback after invocation)
  • A reviewer posts an Approve review
  • User explicitly stops the loop
  • Max rounds reached

Final round Fix Report footer:

Max review rounds (N) reached. Remaining items addressed above. Manual re-review recommended.

Inline reply tagging: When replying to a bot/agent inline comment, include the reviewer's GitHub username in the reply (e.g., —Claude Sonnet 4.6 | addressed @gemini-code-assist feedback).

See references/fix-report-examples.md Examples 7–8 for loop-mode Fix Reports.

Multi-Reviewer Patterns

Duplicate Feedback

If multiple reviewers flag the same issue:

- [file.php:L42 (ALL flagged)]: FIXED @ abc123 — verified: `npm test` passes
  - Gemini: "use const"
  - Codex: "prefer immutable"
  - Claude: "const prevents reassignment"

Conflicting Suggestions

- [file.php:L100]: QUESTION — Gemini suggests pattern A, Codex suggests pattern B. Which aligns with project conventions? See AGENTS.md.

Finding Comments by Reviewer

Use check-pr-feedback.sh — its output already includes [user.login] for every comment across all three channels. Filter the output for the reviewer you need:

~/.claude/skills/pr-review/scripts/check-pr-feedback.sh | grep "coderabbitai"

Troubleshooting

"Can't find review comments" → Check all three channels. Use ~/.claude/skills/pr-review/scripts/check-pr-feedback.sh, not just gh pr view.

"Reviewer posted inline, should I reply inline?" → Yes, always. Reply inline with a brief ack so the comment can be resolved in GitHub UI. Also include in Fix Report.

"Multiple reviewers flagged same issue" → Fix once, report once (note all sources), tag all reviewers.

"Conflicting suggestions" → Mark QUESTION, check project docs, cite specific suggestions.

"Script can't detect PR" → Run from repository root. Must be on branch with open PR.

"Reply script fails with HTTP 422" → Use -F in_reply_to=ID not --raw-field. The -F flag works correctly with gh CLI for numeric IDs.

"Review suggestion broke working code" → Never trust suggestions blindly. Verify the issue exists, evaluate the fix, and test before committing. Review bots frequently hallucinate problems or suggest incorrect fixes.

"No feedback on PR — all three channels empty" → Agents haven't reviewed yet. Run ~/.claude/skills/pr-review/scripts/invoke-review-agents.sh to trigger them, then wait and re-check.

"Committed before checking latest feedback" → Run feedback check script immediately before declaring PR "ready" or "complete."

Summary

Key principles:

  1. Always check all three channels (conversation + inline + reviews)
  2. Critically evaluate every comment — reviewers can be wrong, misread context, or hallucinate issues
  3. Any reviewer (human, bot, agent) can post in any channel
  4. One Fix Report per round
  5. Tag all reviewers explicitly
  6. If no feedback exists, invoke agents first — never declare a PR complete without at least one review round

Most common mistakes: ❌ Only checking conversation or gh pr view ✅ Always run ~/.claude/skills/pr-review/scripts/check-pr-feedback.sh

❌ Blindly applying review suggestions without verifying the issue exists ✅ Read the actual code, confirm the problem, test the fix

Weekly Installs
14
First Seen
Feb 27, 2026
Installed on
opencode14
gemini-cli14
github-copilot14
amp14
cline14
codex14