Context
- Repo: !
git remote -v
- Current branch: !
git branch --show-current
- Git status: !
git status --porcelain=v2 --branch
Parameters
Parse these parameters from the command (all optional):
| Parameter |
Description |
$1 |
PR number (if omitted, use PR of current branch; if no such PR, list actionable PRs). Mutually exclusive with --all. |
--commit |
Create commit(s) after addressing feedback. |
--push |
Push changes after committing (implies --commit). |
--all |
Address feedback on every actionable open PR. Dispatches one subagent per PR in an isolated worktree; the orchestrator pushes, replies, and resolves. Implies --commit --push unless --dry-run is set. Mutually exclusive with $1. |
--dry-run |
With --all, print the dispatch plan and stop — no subagents spawned, no commits, no pushes. Ignored without --all. |
--limit N |
Maximum concurrent subagents under --all (default 3). Use a small number to stay under GitHub rate limits and avoid API rate-limit cascades from many concurrent subagents — the hazard bites 1M-context sessions, which on Fable is every session, since 1M is its default window (see skill-fork-context.md). |
--include-automation |
With --all, also surface automation-authored PRs (release-please, dependabot, renovate, *[bot], *-bot). Excluded by default because they carry no human review feedback and their CI failures are resolved by automation re-running, not hand edits. |
Mode selection:
| Mode |
Triggered when |
Flow |
| Single-PR |
No --all |
Steps 1–7 below operate on one PR. |
| Multi-PR |
--all is passed |
Step 1A dispatches subagents; the orchestrator finalises (push, reply, resolve, re-request) and writes a combined summary. Skip Steps 1–6. |
If both $1 and --all are given, error and stop with: --all is mutually exclusive with a PR number argument.
When to Use This Skill
| Use this skill when... |
Use another skill instead when... |
| A PR has reviewer comments to address |
CI checks are failing with no review comments -> use git-fix-pr |
| You need to systematically work through review feedback |
You're creating a new PR -> use git-commit-push-pr |
| A reviewer has requested changes |
You want to understand PR workflow patterns -> use git-branch-pr-workflow |
Your Task
Review PR workflow results and reviewer comments, then address substantive feedback.
For feedback categorization, decision trees, commit format, and report templates, see REFERENCE.md.
Step 1: Determine PR and Gather All Data
If --all is set, skip this step and jump to Step 1A: Multi-PR Mode below.
Parse owner/repo from the git remote URL.
Resolve the PR number in this order:
If $1 was provided, use it.
Otherwise, try the PR for the current branch:
gh pr view --json number -q '.number'
If step 2 fails (no PR for the branch) or the command is on a detached/default branch, fall back to listing actionable PRs:
bash ${CLAUDE_SKILL_DIR}/scripts/list-actionable-prs.sh <owner> <repo>
The script emits a JSON array of open, non-draft PRs that have unresolved review threads, failing/errored CI, or CHANGES_REQUESTED. Handle the result as follows:
| Result |
Action |
| Empty array |
Report "No PRs need attention." and stop. |
| One entry |
Use that PR number and continue. |
| Multiple entries |
Print a compact table (number, author, CI, unresolved, reviewDecision, title) ordered as returned, then stop and instruct the user to re-run /git:pr-feedback <number>. Do not guess which PR they meant. |
Switch to PR branch if not already on it:
gh pr view $PR --json headRefName -q '.headRefName'
git switch <branch-name>
git pull origin <branch-name>
Fetch ALL PR data using the bundled script (single GraphQL query):
bash ${CLAUDE_SKILL_DIR}/scripts/fetch-pr-data.sh <owner> <repo> <pr-number>
For failed checks only, fetch detailed logs:
gh run view $RUN_ID --log-failed
| Check Status |
Action |
| All passing |
Skip to Step 2 |
| Failed CI |
Get logs with gh run view, may need fixes |
| Pending |
Note status, focus on comments |
If the GraphQL query fails with a rate limit error, wait 60 seconds and retry once.
Step 1A: Multi-PR Mode (--all)
Reached only when --all is passed. The orchestrator dispatches one subagent per actionable PR; subagents commit inside isolated worktrees but never push. The orchestrator handles all GitHub-side mutations.
Parse owner/repo from the git remote URL.
List actionable PRs with the bundled selector (append --include-automation if that flag was passed):
bash ${CLAUDE_SKILL_DIR}/scripts/list-actionable-prs.sh <owner> <repo>
The script returns a JSON array of open, non-draft PRs with unresolved review threads, failing/errored CI, or CHANGES_REQUESTED. Automation-authored PRs (release-please, dependabot, renovate, *[bot], *-bot) are excluded by default — dispatching a subagent on one is almost always wrong (no review threads to act on, protected changelog/version files). Pass --include-automation to include them, or set PR_FEEDBACK_AUTOMATION_AUTHORS to extend the recognised author list. If the array is empty, report No PRs need attention. and stop.
Print a compact dispatch table (number, author, ci, unresolved, reviewDecision, head, title) so the user can see what is about to be processed.
--dry-run short-circuit: if --dry-run was also passed, additionally print the per-PR subagent prompt that would be dispatched (one per row, using the template in REFERENCE.md "Multi-PR Subagent Prompt"), then stop. No subagents spawn, no commits, no pushes.
Dispatch subagents, capped at --limit N concurrent (default 3). For each PR call the Task tool with:
subagent_type: "general-purpose"
isolation: "worktree" — each subagent gets its own git worktree
description: Address review feedback for PR #<n>
prompt: see REFERENCE.md "Multi-PR Subagent Prompt" for the canonical template. The prompt must instruct the subagent to switch its worktree to the PR's headRefName, run the single-PR feedback flow with --commit (not --push), and return a structured JSON summary.
Dispatch one batch of N Task calls in a single message (per the parallel-dispatch contract). When all return, dispatch the next batch until the queue is empty.
Collect subagent results. Each subagent returns JSON with: pr, branch, worktree_path, commits[], addressed[] (each with thread_id, database_id, action, reply, resolve), deferred_issues[], co_authors[], blockers[]. Treat any subagent that fails to return parseable JSON as blocked — record its raw output and continue with the rest of the batch.
Orchestrator finalisation — for each PR with successful commits, run sequentially (push and the GitHub mutation tools share the same rate-limit pool):
git push origin <branch> from the main checkout — worktrees share the underlying .git/, so commits made by the subagent are already visible by branch name. No cd into the subagent's worktree is required.
Capture the resolving SHA (git rev-parse origin/<branch> after the push).
For each addressed[] entry, post the reply via mcp__github__add_reply_to_pull_request_comment, substituting the resolving SHA into any {{SHA}} placeholder the subagent left in the reply text.
Resolve threads via the GraphQL resolveReviewThread mutation per Step 6's rules. Resolution is the default after a reply — only skip when the subagent set resolve: false for a documented exception (follow-up question, partial fix, reviewer asked to keep open, or a third-party PR without user approval). Treat any resolve: true paired with a successful reply as a mandatory call. Use:
gh api graphql -f query='mutation($id:ID!){resolveReviewThread(input:{threadId:$id}){thread{isResolved}}}' -F id="$THREAD_ID"
Re-request review per Step 5a's rules.
Skip Steps 2–6. Go directly to Step 7 with a combined summary that includes a per-PR section plus a top-level rollup: dispatched, succeeded, blocked, total threads resolved, total commits pushed.
Failure handling
| Subagent state |
Orchestrator action |
| Returned valid JSON, has commits, no blockers |
Push + reply + resolve as above |
| Returned valid JSON, no commits (only questions / declined nitpicks) |
Skip push; still post replies and resolve declined nitpick threads |
Returned valid JSON, has blockers[] |
Surface in the summary; do not push partial work — let the user decide |
| Failed to return parseable JSON |
Surface its raw output in the summary as blocked: parse-error; do nothing further for that PR |
Reported a merge conflict on git pull --ff-only |
Surface in the summary as blocked: branch-out-of-sync; user resolves manually |
A blocked subagent does not abort the whole batch; the orchestrator continues with the others.
Step 2: Analyze Feedback
Categorize all comments from the GraphQL response (see REFERENCE.md for category definitions):
- Skip any thread where
isResolved: true or isOutdated: true — already handled.
- Categorize each remaining comment as Blocking, Substantive, Suggestion, Question, or Nitpick.
- For each actionable comment, capture: thread
id, top-level comment databaseId, file, line, scope, and whether the body contains a ```suggestion block.
- Track one item per actionable thread, including the thread
id and databaseId so Steps 3–5 can reply and resolve — via TodoWrite when the session has the task tools (see .claude/rules/agentic-permissions.md § Task-tool availability), otherwise as a checklist you keep in the response.
Step 3: Address Feedback
Verify before accepting — especially claims from an automated reviewer. Before accepting or acting on any suggestion, independently verify the claim against the actual source, the live system, or upstream documentation. This matters most for automated reviewers (Gemini Code Assist, Copilot, and other bot authors), whose suggestions are frequently confidently-wrong: read the code/config the claim is about, check the rendered/live behaviour, and confirm against docs rather than applying a bot suggestion on trust. A claim that fails verification is refuted — reply with the refutation and the supporting evidence, and do not change the code. A written refutation with evidence is a legitimate way to resolve a thread (see Step 6).
Work through actionable items systematically. For each thread, decide using the table below — see REFERENCE.md for the full decision tree.
| Comment shape |
Action |
Contains a ```suggestion block, fix is correct |
Accept the suggestion: apply the suggestion's exact replacement to the file (see REFERENCE.md "Accepting Suggestions"). Record the comment author's login and name/email for co-author attribution in Step 4. |
Contains a ```suggestion block, fix needs adjustment |
Implement an improved variant; explain the deviation in the reply. Record the suggester for co-author attribution. |
| Inline code comment without suggestion |
Read context, implement fix, verify no regressions |
| Claim that verification refutes (wrong on the facts) |
Refuted: do not change the code. Reply with the refutation and the evidence that disproves it (the source line, rendered config, live behaviour, or doc that contradicts the claim), then resolve. Apply this whenever a bot/automated-reviewer suggestion does not survive verification. |
| Question / clarification |
Skip code change; draft an inline reply for Step 4 |
Blocking review (REQUEST_CHANGES) |
Address every concern before resolving any thread |
| Failed CI check |
Identify failure type (lint/type/test/build), fix locally, run to verify |
| Out-of-scope feedback |
Do not implement in this PR. Open a follow-up issue (see Step 3a) and reference its number in the reply. |
Mark each item in progress while working it and done once the file change (if any) lands locally. Do not resolve threads yet — replies and resolution happen after the commit so reviewers see the linked SHA.
Step 3a: File follow-up issues for out-of-scope feedback
For any thread categorised as out-of-scope (or where the user opts to defer rather than implement now):
- Draft a one-line title and short body that quotes the reviewer comment and links the PR thread URL.
- Use
mcp__github__issue_write (action create) or gh issue create -R <owner>/<repo> --title "<title>" --body "<body>" to file the issue.
- Capture the returned issue number — Step 6's reply uses it (
Deferred to #<n> — <reason>.).
Skip this step if the user has explicitly said not to file follow-ups. When ambiguous, ask via AskUserQuestion before creating an issue.
Step 4: Commit Changes (if --commit or --push)
Group related fixes into logical commits — one commit per logical group of accepted suggestions, not one per suggestion. See REFERENCE.md for commit message format.
For any commit that contains an accepted (or adapted) suggestion, append a Co-authored-by: trailer for each unique suggester. This mirrors GitHub's "Commit suggestion" / "Add suggestion to batch" behaviour, which credits the suggester as co-author. See REFERENCE.md "Co-author Attribution" for how to construct the trailer line and resolve the suggester's email.
Run pre-commit hooks if configured, then stage any formatter changes.
Step 5: Push Changes (if --push)
git push origin HEAD
Step 5a: Re-request Review (if --push)
After a successful push that addresses substantive feedback, re-request review from any reviewer whose threads were resolved or who left a CHANGES_REQUESTED review. Skip this step when only nitpicks or questions were addressed.
Determine reviewers to re-request from the GraphQL response captured in Step 1:
latestReviews entries with state == "CHANGES_REQUESTED"
- Authors of any review thread you resolved in Step 6
Then call:
gh api -X POST \
/repos/<owner>/<repo>/pulls/<pr>/requested_reviewers \
-f 'reviewers[]=<login1>' \
-f 'reviewers[]=<login2>'
If gh api returns 422 ("Reviews may only be requested from collaborators"), the reviewer cannot be re-requested via the API — note it in the Step 7 summary and continue.
Step 6: Reply and Resolve Threads
For every actionable thread tracked in Step 2, post a reply and then resolve the thread by default. Owner/repo/PR are the same values used in Step 1.
Resolving is the default action after replying — leaving threads open is the exception, reserved for the explicit cases listed in step 3. A reply alone does not end the conversation in GitHub's UI: the thread stays in the reviewer's "unresolved" queue until someone clicks Resolve conversation. Without this step the PR will continue to show unresolved feedback even after every concern has been addressed.
Reply with mcp__github__add_reply_to_pull_request_comment using the top-level comment's databaseId (a number, not the GraphQL node ID). Keep replies short — see REFERENCE.md "Reply Templates".
- Code change made → reference the commit SHA:
Fixed in <sha> by <one-line summary>.
- Suggestion accepted verbatim →
Accepted suggestion in <sha>.
- Suggestion adapted → explain the deviation:
Applied a variant in <sha>: <reason>.
- Deferred / out of scope → reference the follow-up issue filed in Step 3a:
Deferred to #<issue> — <reason>.
- Question → answer it directly.
- Refuting a suggestion (claim verification disproved) → state the reasoning with evidence:
Leaving as-is: <reason> — <evidence that disproves the claim>.
Always resolve with the GraphQL resolveReviewThread mutation using the thread id (a PRRT_… GraphQL node ID). Resolution is the default after a reply — only skip when one of step 3's "leave open" exceptions applies. Call:
gh api graphql -f query='mutation($id:ID!){resolveReviewThread(input:{threadId:$id}){thread{isResolved}}}' -F id="$THREAD_ID"
Resolve when any of these completion conditions hold and none of step 3's "leave open" exceptions apply:
- You pushed a commit that addresses the concern (
Fixed in <sha>, Accepted in <sha>, Applied a variant in <sha>).
- You answered the reviewer's question directly.
- You refuted or declined the suggestion with explicit reasoning in the reply (a written refutation — not silence — completes the thread).
- You deferred to a follow-up issue filed in Step 3a (the deferral and issue link are the resolution).
Resolving must happen in the same turn as the reply. Treat "reply posted but thread unresolved" as an incomplete step — re-run the resolve call before reporting Step 7.
Leave the thread open only when one of these holds:
- Your reply asks the reviewer a follow-up question (you are waiting on them).
- The fix is partial — some of the concern still applies to this PR.
- The reviewer explicitly asked to keep the thread open.
- You haven't pushed yet (no resolving SHA exists) — finish Step 5, then resolve.
- You're acting on a PR you don't own and the user has not approved resolving on third-party PRs.
If --commit/--push was not passed, still post replies for questions and refutations, but defer resolution until a future invocation with --push lands the SHA. Note these pending resolutions in the Step 7 summary so they're not forgotten.
Step 7: Summary Report
Provide a summary table of feedback addressed, replies posted, threads resolved, and next steps. See REFERENCE.md for the report template.
Agentic Optimizations
| Context |
Command / Tool |
| All PR data (single query) |
bash ${CLAUDE_SKILL_DIR}/scripts/fetch-pr-data.sh <owner> <repo> <pr> |
Actionable PRs (selector / --all source) |
bash ${CLAUDE_SKILL_DIR}/scripts/list-actionable-prs.sh <owner> <repo> |
| Actionable PRs incl. automation |
bash ${CLAUDE_SKILL_DIR}/scripts/list-actionable-prs.sh --include-automation <owner> <repo> |
Dispatch a per-PR subagent (--all) |
Task({subagent_type: "general-purpose", isolation: "worktree", prompt: <REFERENCE.md template>}) |
| Failed check logs |
gh run view $ID --log-failed |
| Quick check status (fallback) |
gh pr checks $PR --json name,state,conclusion |
| Reply to a review comment |
mcp__github__add_reply_to_pull_request_comment (commentId = databaseId) |
| Resolve a review thread |
gh api graphql -f query='mutation($id:ID!){resolveReviewThread(input:{threadId:$id}){thread{isResolved}}}' -F id="$THREAD_ID" (threadId = PRRT_… node ID) |
| Re-request review after push |
gh api -X POST /repos/<owner>/<repo>/pulls/<pr>/requested_reviewers -f 'reviewers[]=<login>' |
| File follow-up issue for deferred feedback |
mcp__github__issue_write (action create) or gh issue create -R <owner>/<repo> --title <t> --body <b> |
See Also
- /git:fix-pr - Focus on CI failures specifically
- gh-cli-agentic skill - Optimized GitHub CLI patterns
- git-branch-pr-workflow skill - PR workflow patterns
1---
2created: 2026-01-30
3modified: 2026-09-02
4reviewed: 2026-09-02
5allowed-tools: Bash(gh pr checks *), Bash(gh pr view *), Bash(gh pr diff *), Bash(gh run view *), Bash(gh run list *), Bash(gh api *), Bash(gh repo view *), Bash(gh issue create *), Bash(git status *), Bash(git diff *), Bash(git log *), Bash(git add *), Bash(git commit *), Bash(git push *), Bash(git switch *), Bash(git pull *), Bash(git fetch *), Bash(pre-commit *), Bash(npm run *), Bash(uv run *), Bash(bash *), Read, Edit, Write, Grep, Glob, Task, mcp__github__pull_request_read, mcp__github__add_reply_to_pull_request_comment, mcp__github__pull_request_review_write, mcp__github__issue_write
6args: "[pr-number] [--commit] [--push] [--all] [--dry-run] [--limit N] [--include-automation]"
7argument-hint: "[pr-number | --all] [--commit] [--push] [--dry-run] [--limit N] [--include-automation]"
8disable-model-invocation: true
9description: "Address PR review comments and resolve threads. Use when CHANGES_REQUESTED is set, working through unresolved review threads, or replying to reviewer feedback."
10name: git-pr-feedback
11agent: general-purpose
12---
13
14## Context
15
16- Repo: !`git remote -v`
17- Current branch: !`git branch --show-current`
18- Git status: !`git status --porcelain=v2 --branch`
19
20## Parameters
21
22Parse these parameters from the command (all optional):
23
24| Parameter | Description |
25|-----------|-------------|
26| `$1` | PR number (if omitted, use PR of current branch; if no such PR, list actionable PRs). Mutually exclusive with `--all`. |
27| `--commit` | Create commit(s) after addressing feedback. |
28| `--push` | Push changes after committing (implies `--commit`). |
29| `--all` | Address feedback on every actionable open PR. Dispatches one subagent per PR in an isolated worktree; the orchestrator pushes, replies, and resolves. Implies `--commit --push` unless `--dry-run` is set. Mutually exclusive with `$1`. |
30| `--dry-run` | With `--all`, print the dispatch plan and stop — no subagents spawned, no commits, no pushes. Ignored without `--all`. |
31| `--limit N` | Maximum concurrent subagents under `--all` (default `3`). Use a small number to stay under GitHub rate limits and avoid API rate-limit cascades from many concurrent subagents — the hazard bites 1M-context sessions, which on Fable is every session, since 1M is its default window (see [`skill-fork-context.md`](../../../.claude/rules/skill-fork-context.md)). |
32| `--include-automation` | With `--all`, also surface automation-authored PRs (release-please, dependabot, renovate, `*[bot]`, `*-bot`). Excluded by default because they carry no human review feedback and their CI failures are resolved by automation re-running, not hand edits. |
33
34**Mode selection**:
35
36| Mode | Triggered when | Flow |
37|------|----------------|------|
38| Single-PR | No `--all` | Steps 1–7 below operate on one PR. |
39| Multi-PR | `--all` is passed | **Step 1A** dispatches subagents; the orchestrator finalises (push, reply, resolve, re-request) and writes a combined summary. Skip Steps 1–6. |
40
41If both `$1` and `--all` are given, error and stop with: `--all is mutually exclusive with a PR number argument.`
42
43## When to Use This Skill
44
45| Use this skill when... | Use another skill instead when... |
46|------------------------|----------------------------------|
47| A PR has reviewer comments to address | CI checks are failing with no review comments -> use `git-fix-pr` |
48| You need to systematically work through review feedback | You're creating a new PR -> use `git-commit-push-pr` |
49| A reviewer has requested changes | You want to understand PR workflow patterns -> use `git-branch-pr-workflow` |
50
51## Your Task
52
53Review PR workflow results and reviewer comments, then address substantive feedback.
54
55For feedback categorization, decision trees, commit format, and report templates, see [REFERENCE.md](REFERENCE.md).
56
57---
58
59### Step 1: Determine PR and Gather All Data
60
61> If `--all` is set, **skip this step** and jump to **Step 1A: Multi-PR Mode** below.
62
631. **Parse owner/repo** from the git remote URL.
64
652. **Resolve the PR number** in this order:
66 1. If `$1` was provided, use it.
67 2. Otherwise, try the PR for the current branch:
68 ```bash
69 gh pr view --json number -q '.number'
70 ```
71 3. If step 2 fails (no PR for the branch) **or** the command is on a detached/default branch, fall back to listing actionable PRs:
72 ```bash
73 bash ${CLAUDE_SKILL_DIR}/scripts/list-actionable-prs.sh <owner> <repo>
74 ```
75 The script emits a JSON array of open, non-draft PRs that have unresolved review threads, failing/errored CI, or `CHANGES_REQUESTED`. Handle the result as follows:
76
77 | Result | Action |
78 |--------|--------|
79 | Empty array | Report "No PRs need attention." and stop. |
80 | One entry | Use that PR number and continue. |
81 | Multiple entries | Print a compact table (number, author, CI, unresolved, reviewDecision, title) ordered as returned, then stop and instruct the user to re-run `/git:pr-feedback <number>`. Do **not** guess which PR they meant. |
82
833. **Switch to PR branch** if not already on it:
84 ```bash
85 gh pr view $PR --json headRefName -q '.headRefName'
86 git switch <branch-name>
87 git pull origin <branch-name>
88 ```
89
904. **Fetch ALL PR data** using the bundled script (single GraphQL query):
91 ```bash
92 bash ${CLAUDE_SKILL_DIR}/scripts/fetch-pr-data.sh <owner> <repo> <pr-number>
93 ```
94
955. **For failed checks only**, fetch detailed logs:
96 ```bash
97 gh run view $RUN_ID --log-failed
98 ```
99
100| Check Status | Action |
101|--------------|--------|
102| All passing | Skip to Step 2 |
103| Failed CI | Get logs with `gh run view`, may need fixes |
104| Pending | Note status, focus on comments |
105
106If the GraphQL query fails with a rate limit error, wait 60 seconds and retry once.
107
108---
109
110### Step 1A: Multi-PR Mode (--all)
111
112Reached only when `--all` is passed. The orchestrator dispatches one subagent per actionable PR; subagents commit inside isolated worktrees but never push. The orchestrator handles all GitHub-side mutations.
113
1141. **Parse owner/repo** from the git remote URL.
115
1162. **List actionable PRs** with the bundled selector (append `--include-automation` if that flag was passed):
117 ```bash
118 bash ${CLAUDE_SKILL_DIR}/scripts/list-actionable-prs.sh <owner> <repo>
119 ```
120 The script returns a JSON array of open, non-draft PRs with unresolved review threads, failing/errored CI, or `CHANGES_REQUESTED`. Automation-authored PRs (release-please, dependabot, renovate, `*[bot]`, `*-bot`) are excluded by default — dispatching a subagent on one is almost always wrong (no review threads to act on, protected changelog/version files). Pass `--include-automation` to include them, or set `PR_FEEDBACK_AUTOMATION_AUTHORS` to extend the recognised author list. If the array is empty, report `No PRs need attention.` and stop.
121
1223. **Print a compact dispatch table** (number, author, ci, unresolved, reviewDecision, head, title) so the user can see what is about to be processed.
123
1244. **`--dry-run` short-circuit**: if `--dry-run` was also passed, additionally print the per-PR subagent prompt that *would* be dispatched (one per row, using the template in [REFERENCE.md](REFERENCE.md) "Multi-PR Subagent Prompt"), then stop. No subagents spawn, no commits, no pushes.
125
1265. **Dispatch subagents**, capped at `--limit N` concurrent (default `3`). For each PR call the `Task` tool with:
127 - `subagent_type: "general-purpose"`
128 - `isolation: "worktree"` — each subagent gets its own git worktree
129 - `description`: `Address review feedback for PR #<n>`
130 - `prompt`: see [REFERENCE.md](REFERENCE.md) "Multi-PR Subagent Prompt" for the canonical template. The prompt must instruct the subagent to switch its worktree to the PR's `headRefName`, run the single-PR feedback flow with `--commit` (not `--push`), and return a structured JSON summary.
131
132 Dispatch one batch of `N` `Task` calls in a single message (per the parallel-dispatch contract). When all return, dispatch the next batch until the queue is empty.
133
1346. **Collect subagent results**. Each subagent returns JSON with: `pr`, `branch`, `worktree_path`, `commits[]`, `addressed[]` (each with `thread_id`, `database_id`, `action`, `reply`, `resolve`), `deferred_issues[]`, `co_authors[]`, `blockers[]`. Treat any subagent that fails to return parseable JSON as blocked — record its raw output and continue with the rest of the batch.
135
1367. **Orchestrator finalisation** — for each PR with successful commits, run sequentially (push and the GitHub mutation tools share the same rate-limit pool):
137 1. `git push origin <branch>` from the **main checkout** — worktrees share the underlying `.git/`, so commits made by the subagent are already visible by branch name. No `cd` into the subagent's worktree is required.
138 2. Capture the resolving SHA (`git rev-parse origin/<branch>` after the push).
139 3. For each `addressed[]` entry, post the reply via `mcp__github__add_reply_to_pull_request_comment`, substituting the resolving SHA into any `{{SHA}}` placeholder the subagent left in the reply text.
140 4. Resolve threads via the GraphQL `resolveReviewThread` mutation per Step 6's rules. Resolution is the default after a reply — only skip when the subagent set `resolve: false` for a documented exception (follow-up question, partial fix, reviewer asked to keep open, or a third-party PR without user approval). Treat any `resolve: true` paired with a successful reply as a mandatory call. Use:
141
142 ```bash
143 gh api graphql -f query='mutation($id:ID!){resolveReviewThread(input:{threadId:$id}){thread{isResolved}}}' -F id="$THREAD_ID"
144 ```
145 5. Re-request review per Step 5a's rules.
146
1478. **Skip Steps 2–6**. Go directly to **Step 7** with a combined summary that includes a per-PR section plus a top-level rollup: dispatched, succeeded, blocked, total threads resolved, total commits pushed.
148
149#### Failure handling
150
151| Subagent state | Orchestrator action |
152|----------------|---------------------|
153| Returned valid JSON, has commits, no blockers | Push + reply + resolve as above |
154| Returned valid JSON, no commits (only questions / declined nitpicks) | Skip push; still post replies and resolve declined nitpick threads |
155| Returned valid JSON, has `blockers[]` | Surface in the summary; do **not** push partial work — let the user decide |
156| Failed to return parseable JSON | Surface its raw output in the summary as `blocked: parse-error`; do nothing further for that PR |
157| Reported a merge conflict on `git pull --ff-only` | Surface in the summary as `blocked: branch-out-of-sync`; user resolves manually |
158
159A blocked subagent does not abort the whole batch; the orchestrator continues with the others.
160
161---
162
163### Step 2: Analyze Feedback
164
165Categorize all comments from the GraphQL response (see [REFERENCE.md](REFERENCE.md) for category definitions):
166
1671. Skip any thread where `isResolved: true` or `isOutdated: true` — already handled.
1682. Categorize each remaining comment as Blocking, Substantive, Suggestion, Question, or Nitpick.
1693. For each actionable comment, capture: thread `id`, top-level comment `databaseId`, file, line, scope, and whether the body contains a ` ```suggestion ` block.
1704. Track one item per actionable thread, including the thread `id` and `databaseId` so Steps 3–5 can reply and resolve — via `TodoWrite` when the session has the task tools (see `.claude/rules/agentic-permissions.md` § Task-tool availability), otherwise as a checklist you keep in the response.
171
172---
173
174### Step 3: Address Feedback
175
176**Verify before accepting — especially claims from an automated reviewer.** Before accepting or acting on any suggestion, independently verify the claim against the actual source, the live system, or upstream documentation. This matters most for automated reviewers (Gemini Code Assist, Copilot, and other bot authors), whose suggestions are frequently confidently-wrong: read the code/config the claim is about, check the rendered/live behaviour, and confirm against docs rather than applying a bot suggestion on trust. A claim that fails verification is **refuted** — reply with the refutation and the supporting evidence, and do **not** change the code. A written refutation with evidence is a legitimate way to resolve a thread (see Step 6).
177
178Work through actionable items systematically. For each thread, decide using the table below — see [REFERENCE.md](REFERENCE.md) for the full decision tree.
179
180| Comment shape | Action |
181|---------------|--------|
182| Contains a ` ```suggestion ` block, fix is correct | **Accept the suggestion**: apply the suggestion's exact replacement to the file (see [REFERENCE.md](REFERENCE.md) "Accepting Suggestions"). Record the comment author's `login` and `name`/`email` for co-author attribution in Step 4. |
183| Contains a ` ```suggestion ` block, fix needs adjustment | Implement an improved variant; explain the deviation in the reply. Record the suggester for co-author attribution. |
184| Inline code comment without suggestion | Read context, implement fix, verify no regressions |
185| Claim that verification refutes (wrong on the facts) | **Refuted**: do not change the code. Reply with the refutation and the evidence that disproves it (the source line, rendered config, live behaviour, or doc that contradicts the claim), then resolve. Apply this whenever a bot/automated-reviewer suggestion does not survive verification. |
186| Question / clarification | Skip code change; draft an inline reply for Step 4 |
187| Blocking review (`REQUEST_CHANGES`) | Address every concern before resolving any thread |
188| Failed CI check | Identify failure type (lint/type/test/build), fix locally, run to verify |
189| Out-of-scope feedback | Do not implement in this PR. Open a follow-up issue (see Step 3a) and reference its number in the reply. |
190
191Mark each item in progress while working it and done once the file change (if any) lands locally. Do **not** resolve threads yet — replies and resolution happen after the commit so reviewers see the linked SHA.
192
193### Step 3a: File follow-up issues for out-of-scope feedback
194
195For any thread categorised as out-of-scope (or where the user opts to defer rather than implement now):
196
1971. Draft a one-line title and short body that quotes the reviewer comment and links the PR thread URL.
1982. Use `mcp__github__issue_write` (action `create`) or `gh issue create -R <owner>/<repo> --title "<title>" --body "<body>"` to file the issue.
1993. Capture the returned issue number — Step 6's reply uses it (`Deferred to #<n> — <reason>.`).
200
201Skip this step if the user has explicitly said not to file follow-ups. When ambiguous, ask via `AskUserQuestion` before creating an issue.
202
203---
204
205### Step 4: Commit Changes (if --commit or --push)
206
207Group related fixes into logical commits — one commit per logical group of accepted suggestions, not one per suggestion. See [REFERENCE.md](REFERENCE.md) for commit message format.
208
209For any commit that contains an **accepted (or adapted) suggestion**, append a `Co-authored-by:` trailer for each unique suggester. This mirrors GitHub's "Commit suggestion" / "Add suggestion to batch" behaviour, which credits the suggester as co-author. See [REFERENCE.md](REFERENCE.md) "Co-author Attribution" for how to construct the trailer line and resolve the suggester's email.
210
211Run pre-commit hooks if configured, then stage any formatter changes.
212
213### Step 5: Push Changes (if --push)
214
215```bash
216git push origin HEAD
217```
218
219### Step 5a: Re-request Review (if --push)
220
221After a successful push that addresses substantive feedback, re-request review from any reviewer whose threads were resolved or who left a `CHANGES_REQUESTED` review. Skip this step when only nitpicks or questions were addressed.
222
223Determine reviewers to re-request from the GraphQL response captured in Step 1:
224
225- `latestReviews` entries with `state == "CHANGES_REQUESTED"`
226- Authors of any review thread you resolved in Step 6
227
228Then call:
229
230```bash
231gh api -X POST \
232 /repos/<owner>/<repo>/pulls/<pr>/requested_reviewers \
233 -f 'reviewers[]=<login1>' \
234 -f 'reviewers[]=<login2>'
235```
236
237If `gh api` returns 422 ("Reviews may only be requested from collaborators"), the reviewer cannot be re-requested via the API — note it in the Step 7 summary and continue.
238
239### Step 6: Reply and Resolve Threads
240
241For every actionable thread tracked in Step 2, post a reply and then **resolve the thread by default**. Owner/repo/PR are the same values used in Step 1.
242
243Resolving is the default action after replying — leaving threads open is the exception, reserved for the explicit cases listed in step 3. A reply alone does **not** end the conversation in GitHub's UI: the thread stays in the reviewer's "unresolved" queue until someone clicks **Resolve conversation**. Without this step the PR will continue to show unresolved feedback even after every concern has been addressed.
244
2451. **Reply** with `mcp__github__add_reply_to_pull_request_comment` using the top-level comment's `databaseId` (a number, not the GraphQL node ID). Keep replies short — see [REFERENCE.md](REFERENCE.md) "Reply Templates".
246 - Code change made → reference the commit SHA: `Fixed in <sha> by <one-line summary>.`
247 - Suggestion accepted verbatim → `Accepted suggestion in <sha>.`
248 - Suggestion adapted → explain the deviation: `Applied a variant in <sha>: <reason>.`
249 - Deferred / out of scope → reference the follow-up issue filed in Step 3a: `Deferred to #<issue> — <reason>.`
250 - Question → answer it directly.
251 - Refuting a suggestion (claim verification disproved) → state the reasoning **with evidence**: `Leaving as-is: <reason> — <evidence that disproves the claim>.`
252
2532. **Always resolve** with the GraphQL `resolveReviewThread` mutation using the thread `id` (a `PRRT_…` GraphQL node ID). Resolution is the default after a reply — only skip when one of step 3's "leave open" exceptions applies. Call:
254
255 ```bash
256 gh api graphql -f query='mutation($id:ID!){resolveReviewThread(input:{threadId:$id}){thread{isResolved}}}' -F id="$THREAD_ID"
257 ```
258
259 Resolve when **any** of these completion conditions hold and none of step 3's "leave open" exceptions apply:
260 - You pushed a commit that addresses the concern (`Fixed in <sha>`, `Accepted in <sha>`, `Applied a variant in <sha>`).
261 - You answered the reviewer's question directly.
262 - You refuted or declined the suggestion with explicit reasoning in the reply (a written refutation — not silence — completes the thread).
263 - You deferred to a follow-up issue filed in Step 3a (the deferral and issue link are the resolution).
264
265 Resolving must happen in the **same turn** as the reply. Treat "reply posted but thread unresolved" as an incomplete step — re-run the resolve call before reporting Step 7.
266
2673. **Leave the thread open** only when one of these holds:
268 - Your reply asks the reviewer a follow-up question (you are waiting on them).
269 - The fix is partial — some of the concern still applies to this PR.
270 - The reviewer explicitly asked to keep the thread open.
271 - You haven't pushed yet (no resolving SHA exists) — finish Step 5, then resolve.
272 - You're acting on a PR you don't own and the user has not approved resolving on third-party PRs.
273
274If `--commit`/`--push` was not passed, still post replies for questions and refutations, but defer resolution until a future invocation with `--push` lands the SHA. Note these pending resolutions in the Step 7 summary so they're not forgotten.
275
276### Step 7: Summary Report
277
278Provide a summary table of feedback addressed, replies posted, threads resolved, and next steps. See [REFERENCE.md](REFERENCE.md) for the report template.
279
280---
281
282## Agentic Optimizations
283
284| Context | Command / Tool |
285|---------|----------------|
286| All PR data (single query) | `bash ${CLAUDE_SKILL_DIR}/scripts/fetch-pr-data.sh <owner> <repo> <pr>` |
287| Actionable PRs (selector / `--all` source) | `bash ${CLAUDE_SKILL_DIR}/scripts/list-actionable-prs.sh <owner> <repo>` |
288| Actionable PRs incl. automation | `bash ${CLAUDE_SKILL_DIR}/scripts/list-actionable-prs.sh --include-automation <owner> <repo>` |
289| Dispatch a per-PR subagent (`--all`) | `Task({subagent_type: "general-purpose", isolation: "worktree", prompt: <REFERENCE.md template>})` |
290| Failed check logs | `gh run view $ID --log-failed` |
291| Quick check status (fallback) | `gh pr checks $PR --json name,state,conclusion` |
292| Reply to a review comment | `mcp__github__add_reply_to_pull_request_comment` (commentId = `databaseId`) |
293| Resolve a review thread | `gh api graphql -f query='mutation($id:ID!){resolveReviewThread(input:{threadId:$id}){thread{isResolved}}}' -F id="$THREAD_ID"` (threadId = `PRRT_…` node ID) |
294| Re-request review after push | `gh api -X POST /repos/<owner>/<repo>/pulls/<pr>/requested_reviewers -f 'reviewers[]=<login>'` |
295| File follow-up issue for deferred feedback | `mcp__github__issue_write` (action `create`) or `gh issue create -R <owner>/<repo> --title <t> --body <b>` |
296
297## See Also
298
299- **/git:fix-pr** - Focus on CI failures specifically
300- **gh-cli-agentic** skill - Optimized GitHub CLI patterns
301- **git-branch-pr-workflow** skill - PR workflow patterns