Resolve PR Comments in Parallel (v3)
DEFAULT WORKFLOW for resolving PR comments with parallel execution.
MANDATORY: Background Execution
The ENTIRE workflow (Phases 0-7) MUST run as a background agent. This prevents the workflow from being sidetracked by user questions, CI failures, or context switches.
Foreground steps (do these FIRST, before launching the agent):
- Detect PR number from args, current branch, or ask user
- Resolve the PR branch name — run
gh pr view $PR_NUM --json headRefName -q.headRefNameto get the exact branch. Store as$PR_BRANCH. - Print: "Launching PR resolution for #$PR_NUM (branch: $PR_BRANCH) in background. You'll be notified when it completes."
- Launch background agent with the full workflow, passing the branch name:
Agent(
run_in_background: true,
prompt: "You are resolving PR comments for PR #$PR_NUM.
Branch: $PR_BRANCH
Read the pr-resolution skill at ~/.claude/skills/pr-resolution/SKILL.md and execute Phases 0-7.
IMPORTANT:
- FIRST: checkout the PR branch with `git checkout $PR_BRANCH && git pull origin $PR_BRANCH`
- Verify you are on the correct branch before making ANY changes
- For questions classified as [question] that need human input, skip them and note them in your final output
- For CI failures, fix them as part of the workflow — do NOT stop or ask for help
- Complete ALL phases including the CI gate (Phase 6) and shepherd launch (Phase 7)
- Your final output should summarize: comments resolved, comments skipped (with reasons), CI status"
)That's it for the foreground. Everything below is executed by the background agent.
Quick Reference
| Action | Command |
|---|---|
| Get comments | ~/.claude/skills/pr-resolution/bin/get-pr-comments PR_NUM |
| Parse CodeRabbit | ~/.claude/skills/pr-resolution/bin/parse-coderabbit-review PR_NUM |
| Check CI | gh pr checks |
| Resolve thread | ~/.claude/skills/pr-resolution/bin/resolve-pr-thread NODE_ID |
| Resolve all threads | ~/.claude/skills/pr-resolution/bin/resolve-all-threads PR_NUM |
Workflow Overview
Phase 0: Pre-Flight → GoodToGo status check (if installed, otherwise skip)
Phase 1: Discovery → Gather comments, parse bot formats, enumerate
Phase 2: Classification → Categorize by priority, group by file
Phase 3: Resolution → Launch parallel agents by file group
Phase 4: Verification → Local checks + GoodToGo gate (if installed)
Phase 5: Completion → Commit, push, resolve threads
Phase 6: CI Gate → Monitor CI, fix actionable failures, re-push
Phase 7: Shepherd → Background agent monitors for new bot comments + CIPhase 0: Pre-Flight
Branch checkout (MANDATORY — do this FIRST)
The background agent inherits whatever branch the user was on. You MUST switch to the PR branch before doing anything else:
# Get PR branch from the prompt context (passed as $PR_BRANCH)
# If not provided, resolve it:
PR_BRANCH=$(gh pr view $PR_NUM --json headRefName -q '.headRefName')
# Checkout and pull latest
git checkout "$PR_BRANCH"
git pull origin "$PR_BRANCH"
# Verify — abort if wrong branch
CURRENT=$(git branch --show-current)
if [ "$CURRENT" != "$PR_BRANCH" ]; then
echo "FATAL: Expected branch $PR_BRANCH but on $CURRENT"
exit 1
fiIf checkout fails (e.g. uncommitted changes on current branch): run git stash first, then checkout. Do NOT proceed on the wrong branch.
GoodToGo check (optional)
If gtg is installed, run the GoodToGo pre-flight check (see references/goodtogo.md):
if command -v gtg &> /dev/null; then
# gtg auto-detects repo from git remote
GTG_RESULT=$(gtg $PR_NUM --format json 2>/dev/null)
GTG_STATUS=$(echo "$GTG_RESULT" | jq -r '.status')
fiRoute based on status (or skip straight to Phase 1 if gtg is not installed):
READY→ Quick verify and commit (fast path — skip Phases 1-3)CI_FAILING→ Fix CI firstACTION_REQUIRED→ Continue with full workflowUNRESOLVED_THREADS→ Continue with full workflow
Phase 1: Discovery
- Gather comments using scripts from
references/discovery.md - Parse bot formats using rules from
references/bot-formats.md - Print enumeration - counts MUST match before proceeding
Zero comments found? Bots (CodeRabbit, Gemini, Cubic, CodeScene) take 1-5 minutes to post reviews. If discovery finds zero comments, skip Phases 2-5 and jump directly to Phase 6 (CI Gate), then Phase 7 (Shepherd). The shepherd will catch late-arriving bot comments. Do NOT exit early — the shepherd is the whole point when there are no initial comments.
Phase 2: Classification & Grouping
- Classify each comment using
references/classification.md - CodeScene handling: CodeScene comments flag measurable code health regressions (complexity, duplication, nesting). These are ALWAYS addressed with code changes — extract helper functions, reduce cyclomatic complexity, remove duplication. Never resolve a CodeScene thread without a corresponding code fix. Group CodeScene comments with their target file for parallel execution.
- Group by file for parallel execution:
## Parallel Execution Plan
### Group A: src/api/route.ts (3 comments → 1 agent)
- #1 [blocking] Line 45 - Add error handling
- #3 [suggestion] Line 67 - Improve validation
### Group B: src/components/Button.tsx (1 comment → 1 agent)
- #2 [suggestion] Line 23 - Add prop types
### Group C: CI Failures (if any → 1 agent)
- Fix lint/type errors
Total: 3 parallel agentsPhase 3: PARALLEL EXECUTION
MANDATORY: Launch agents simultaneously using the Task tool:
Agent 1: "Fix comments on src/api/route.ts"
- Comment #1: Add error handling at line 45
- Comment #3: Improve validation at line 67
Agent 2: "Fix comments on src/components/Button.tsx"
- Comment #2: Add prop types at line 23
Agent 3: "Fix CI failures"
- Lint errors
- Type errorsParallel execution rules:
| Condition | Execution |
|---|---|
| Same file | → Same agent (avoid conflicts) |
| Different files | → Parallel agents |
| CI failures | → Dedicated agent |
| Questions | → Ask human first |
Wait for all agents to complete.
Phase 4: Verification Gate (MANDATORY)
- Run local checks from
references/verification.md - If
gtgis installed, run final verification fromreferences/goodtogo.md(deterministic READY/BLOCK signal) - Verify all resolutions - every comment needs explicit resolution
DO NOT commit until all checks pass. Phase 5 MUST NOT run if Phase 4 verification exits non-zero.
Phase 5: Completion (MANDATORY — DO NOT SKIP)
Follow steps from references/completion.md:
5a. Commit
- Commit all fixes together
5b. Capture timestamp (for shepherd)
- Capture the current UTC timestamp immediately before push:
LAST_TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)5c. Push
- Push to remote
- If push fails: Skip Phase 6-7. The resolution is incomplete.
5d. Post resolution summary
- Post resolution summary comment to PR
5e. Resolve ALL GitHub threads (MANDATORY)
Run the resolve-all-threads script:
~/.claude/skills/pr-resolution/bin/resolve-all-threads $PR_NUMThis script:
- Queries all unresolved threads on the PR
- Resolves each one via GraphQL mutation
- Verifies zero unresolved threads remain
If the script reports failures or remaining threads: DO NOT mark workflow as complete. Fix manually with bin/resolve-pr-thread THREAD_ID.
5f. Final verification (MANDATORY)
- Run an independent GraphQL count check — do NOT rely solely on the script's output:
UNRESOLVED=$(gh api graphql -f query='
query($owner: String!, $repo: String!, $pr: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $pr) {
reviewThreads(first: 1) { totalCount }
unresolvedThreads: reviewThreads(first: 1, filterBy: {resolved: false}) { totalCount }
}
}
}
' -F owner="$OWNER" -F repo="$REPO" -F pr=$PR_NUM \
--jq '.data.repository.pullRequest.unresolvedThreads.totalCount')
echo "Unresolved threads: $UNRESOLVED"If UNRESOLVED > 0: Re-run bin/resolve-all-threads $PR_NUM, then re-check. If threads persist after two attempts, list the thread IDs in your output and proceed — the shepherd will catch them.
Workflow is NOT complete until all threads are resolved.
Phase 6: CI Gate (MANDATORY)
After pushing in Phase 5, monitor CI until green or exit condition. Follow the bounded CI retry loop from references/ci-gate.md.
- Appearance wait — poll every 15s until at least one check exists for HEAD_SHA (2 min timeout)
- Settle wait — poll every 60s until all checks reach terminal status (15 min timeout)
- Classify failures using the decision matrix from
references/ci-gate.md:
- ACTIONS_FIXABLE: GitHub Actions run (app_slug == "github-actions") + failing job name matches fixable pattern + local npm command exists - EXTERNAL: everything else (third-party apps, no local repro, transient infra failures)
- For ACTIONS_FIXABLE failures: a. Fetch truncated failure logs (
tail -n 300, grep for errors) b. Diagnose — prioritize PR-modified files, expand scope if needed c. Fix the code, verify with local command (timeout 120 npm run <command>) d. Commit withfix(ci): resolve <check-name> failuree. Push, wait 60s grace period, update HEAD_SHA and LAST_TIMESTAMP f. Return to step 1 - Max 3 fix attempts per check name (persisted to
/tmp/ci-gate-state-$PR_NUM, keyed by normalized name) - Total timeout: 30 minutes
Exit routing:
CI_GREENorCI_EXTERNAL_ONLY→ proceed to Phase 7CI_TIMEOUTorCI_ESCALATIONorCI_NO_CHECKS→ report status, proceed to Phase 7
Pre-existing failure policy: If a check fails on the branch, fix it. Do NOT classify failures as "pre-existing" to skip them.
Phase 7: Shepherd (MANDATORY — DO NOT SKIP)
After Phase 6 completes, launch the shepherd as a background agent to monitor for new bot comments and CI status.
This phase is MANDATORY — even when zero comments were found in Phase 1. Bots (CodeRabbit, Gemini, Cubic, CodeScene) take 1-5 minutes to post reviews after a PR is created or pushed. The shepherd catches these late-arriving comments. Do not rationalize skipping ("no comments found", "no push made", "unlikely", "docs-only", "no new comments expected") — launch the shepherd every time. If no push was made in Phase 5, use the current UTC timestamp for LAST_TIMESTAMP.
- Capture context:
OWNER_REPO=$(gh repo view --json nameWithOwner -q '.nameWithOwner')
BRANCH=$(git branch --show-current)
RUN_ID=$(date +%s)- Launch background agent:
Agent(
run_in_background: true,
prompt: "Read skills/pr-resolution/shepherd.md and follow it.
Context:
{\"PR_NUM\": $PR_NUM, \"LAST_TIMESTAMP\": \"$LAST_TIMESTAMP\", \"OWNER_REPO\": \"$OWNER_REPO\", \"BRANCH\": \"$BRANCH\", \"RUN_ID\": \"$RUN_ID\"}"
)- Print: "Shepherd monitoring PR #$PR_NUM in background. You'll be notified when it completes."
If agent launch fails: Print the error and exit cleanly. The initial resolution is already complete.
This phase is NOT re-entered during shepherd RE_RESOLVE iterations.
Note: Phase 7 always starts after Phase 6 completes. They never run concurrently.
Example: PR with 6 Comments
## Discovery
1. [blocking] src/api/route.ts:45 - Security issue
2. [suggestion] src/api/route.ts:67 - Add validation
3. [suggestion] src/components/Form.tsx:23 - Add types
4. [nitpick] src/utils/format.ts:12 - Typo
5. [question] src/lib/auth.ts:89 - "Handle null?"
6. CI: Lint error
## Parallel Plan (after asking human about #5)
- Agent 1: src/api/route.ts (#1, #2)
- Agent 2: src/components/Form.tsx (#3)
- Agent 3: src/utils/format.ts (#4)
- Agent 4: src/lib/auth.ts (#5 - if fix)
- Agent 5: CI fix (#6)
## Execution
Launch agents in parallel → Wait → Verify → Commit → PushRelated
| Resource | Description |
|---|---|
detailed-reference.md | Single-threaded detailed reference |
/commit-commands:commit | Clean commit workflow |