| name | address-review |
| description | Drive the iterative response loop on a PR you own — fetch every piece of review feedback (automated reviewers like CodeRabbit / gemini-code-assist AND human reviewers), triage it, fix the real issues with one focused commit each, run the repo's pre-flight, push, then post a reply to every thread (inline file:line replies plus a PR-level round summary) — because silence makes bots re-raise the same items and leaves humans unsure you saw them. Wait for the next round and repeat until the PR is approved. Reads the repo config for repo slug, default branch, and pre-flight commands. Use whenever the user wants to address, respond to, handle, work through, or iterate on review comments on their PR — "address the review feedback", "respond to the review on PR |
Address review feedback (bots + humans)
This skill drives the full response loop on your own PR: fetch → triage → fix → push → reply →
wait → repeat, until the PR is approved. It treats automated reviewers (CodeRabbit, gemini-code-assist,
and any other review bot) and human reviewers as equal first-class sources of feedback — both get
triaged on the merits, both get a reply to every thread.
It is the counterpart to create-pr: create-pr opens the PR, address-review carries it through
review to approval.
When to use
Trigger when the user wants to work through and respond to review comments on their own PR.
Do not use it for:
- Creating a new PR (use
create-pr).
- Reviewing someone else's PR (this responds to reviews of the user's own work; the reply
mechanics need PR-author authority).
- A one-off question about a single comment when the user just wants context, not the loop.
Load the repo config
Before anything else, read .claude/maintainerd.json from the repo root (see
../../../core/reference/config-schema.md). If it does
not exist, stop and tell the user:
This repo has no .claude/maintainerd.json. Run /bootstrap to generate it, then re-run me.
Keys this skill uses:
config.repo — GitHub owner/name; pass it as --repo to every gh call (so it works the same
interactively and under a scheduled/remote agent).
config.defaultBranch — the PR's base branch; used when reasoning about merge conflicts.
config.commands.{format,lint,build,typecheck,test} — the pre-flight gate run before each push.
Treat any null as "this repo has no such step — skip it, don't invent one."
config.review.bots (optional) — additional automated-reviewer logins to recognize. Defaults
to ["coderabbitai[bot]", "gemini-code-assist[bot]"] if absent. Humans don't need listing —
any reviewer who isn't the PR author is treated as a human reviewer.
The principle: never leave silence
The single most important rule: post a reply to every review thread you address — and to threads
you decide not to address. A one-sentence "Done in <sha>" or "Disagree because " is
enough; the point is closing the loop, not eloquence.
Why it matters, for both kinds of reviewer:
- Bots (CodeRabbit especially) treat unanswered comments as unresolved and re-raise them
next pass — silence literally manufactures more review noise.
- Humans wonder whether you saw the comment at all, and an unanswered thread stalls the merge.
This applies to inline review comments (file/line specific) and to PR-level review summary
bodies. A terse, factual reply is always cheaper than another review round.
Inputs
Usually invoked with a PR number: /address-review 123 or "address the review on #456".
If no PR number is supplied, infer it from the current branch:
gh pr view --repo <config.repo> --json number,headRefName,baseRefName,state,reviewDecision
If multiple PRs match or none exist for the branch, ask which one before doing anything.
Workflow
Phase 1 — Fetch the full review state
Pull all the relevant data in parallel; it lives at four endpoints (substitute <config.repo> for
{owner}/{repo}):
gh pr view <PR> --repo <config.repo> --json number,state,reviewDecision,headRefOid,headRefName,mergeable,statusCheckRollup,author
gh api "repos/<config.repo>/pulls/<PR>/reviews" --paginate
gh api "repos/<config.repo>/pulls/<PR>/comments" --paginate
gh api "repos/<config.repo>/issues/<PR>/comments" --paginate
Filtering and threading:
- A reviewer is anyone other than the PR author. Classify each as automated (login matches the
known/
config.review.bots set) or human — but triage both on the merits; the distinction only
changes a few bot-specific heuristics below.
- A thread is unresolved if its newest message is from a reviewer (the PR author hasn't replied
since the reviewer's last message). Use
in_reply_to_id to reconstruct inline threads.
- CodeRabbit posts both a summary review body and individual inline comments — handle both;
its summary often has an "Actionable comments posted" / "Nitpick comments" header listing what's
already inline, so don't double-count.
- gemini-code-assist tends to post a review summary with a markdown table; treat the table rows
as separate items.
- A human review may be a single approving/blocking summary, inline comments, or both — treat each
inline comment and each substantive point in the summary as its own item.
- Skip your own past replies (filter by author = PR author).
Persist the head SHA you observed and the set of comment IDs — you'll diff against this next loop to
detect "what's new."
Phase 2 — Triage
Before changing any code, classify every unresolved comment into exactly one of:
| Category | Action |
|---|
| Valid bug or correctness issue | Fix with a focused commit |
| Valid improvement (clarity, perf, idiom) | Fix with a focused commit, OR reply explaining why you're keeping the original |
| Nitpick (style, naming, micro-opt) | Either fix quickly or reply with a brief reason for skipping |
| Question | Reply with the answer; only change code if the answer reveals a real issue |
| False positive | Reply explaining why the suggestion doesn't apply (cite the actual code if it helps) |
| Out of scope | Reply acknowledging + (optionally) link a follow-up issue |
Reviewers are not always right — bot or human. Automated reviewers in particular flag safe code,
suggest anti-patterns ("wrap everything in try/catch"), and repeat issues a human already accepted;
their severity calibration is loose. Treat each suggestion on its merits.
When reviewers conflict (e.g. CodeRabbit wants a guard the human reviewer called unnecessary, or
two humans disagree), surface the conflict to the user before deciding — don't pick a side silently.
As a default, a human reviewer's explicit call outranks a bot's on the same point: if a human
dismissed a bot's suggestion, trust the human, skip the work, and reply to the bot pointing at the
human's comment.
Phase 3 — Address with focused commits
One logical fix per commit. This is the heart of the workflow.
Why: reviewers (and bots' follow-up logic) map commits to comments. Bundling unrelated fixes into one
commit makes re-review harder, breaks the comment→fix correspondence, and gives a bot nothing
specific to match against — so it re-raises the same issues.
Commit subjects reference the area, not the review:
- ✅
fix(auth): handle nil session in middleware
- ✅
refactor(api): extract token validator
- ❌
fix: address review comments — useless on the timeline
- ❌
address coderabbit feedback — no signal about what changed
Collect a coherent batch before pushing so the round isn't fragmented across many force-pushes.
Phase 4 — Verify before pushing
Before any push, run:
git status
git log @{u}..HEAD --oneline
This catches two specific failure modes:
- Working-tree-only edits.
sed/awk/scripted edits live in the working tree until you
git add them — they are not in any commit. A push at this point ships only the committed
work. git status forces you to confirm the tree is clean (or any remaining diff is intentional).
- Wrong commit selection. If you reset/rebased mid-session, the local branch may have commits
you didn't expect (or be missing some).
git log @{u}..HEAD confirms the push delivers exactly
what you think.
Then run the repo's pre-flight:
- Prefer delegating to the
create-pr skill if it's installed — it runs the repo's full gate.
- Otherwise run
config.commands.format, config.commands.lint, config.commands.build,
config.commands.typecheck, and config.commands.test in turn, skipping any that are null.
If a check fails, fix it before pushing — broken code in response to a review just creates more
review noise. No --no-verify.
Phase 5 — Push, then reply
Push first, then reply, so commit SHAs in replies are valid:
git push
NEW_HEAD=$(git rev-parse HEAD)
Now post replies. Reply to every thread you addressed — and every one you decided not to.
Inline review-comment reply (continues the same file:line thread):
gh api -X POST "repos/<config.repo>/pulls/<PR>/comments/<comment_id>/replies" \
-f body="Fixed in $NEW_HEAD — moved the nil check to the entry point so we don't leak the session."
PR-level round summary (a regular issue comment — use it to reply to a review summary body, and
to pin what changed this round). Always write one per round; it's the human-readable digest a busy
reviewer reads first:
gh pr comment <PR> --repo <config.repo> --body "Round 2 summary:
- nil session: $NEW_HEAD
- file handle leak: <other_sha>
- naming nit: skipped — \`data\` matches the surrounding convention"
Optionally resolve threads you fixed or explained (only if the repo uses GitHub's native
thread-resolution UI):
gh api graphql -f query='mutation($id:ID!){resolveReviewThread(input:{threadId:$id}){thread{isResolved}}}' -f id="<thread_node_id>"
Don't resolve a thread where the reviewer asked an open question you haven't answered — let them
resolve those.
Tone for replies: terse and factual. Don't apologize, don't thank the bot, don't gush at the
human. Examples that work:
- ✅
Fixed in <sha>.
- ✅
Disagree — already validated upstream at <file>:<line>; a second check would be dead code.
- ✅
Skipped: intentional. <one-sentence reason>.
- ❌
Thanks for the feedback! Great catch! Let me address that… — sycophantic, wastes everyone's time
Phase 6 — Wait for the next round
Note the head SHA you just pushed. The next round's signal is one of:
- A new entry in
.../pulls/<PR>/reviews (timestamp later than your push)
- New review comments after your push timestamp
reviewDecision flips to APPROVED
Polling cadence:
- 5–15 minutes for an active iteration — bots usually re-review within ~10 minutes of a push.
- 30–60 minutes if waiting on a human reviewer.
- Don't poll faster than 5 minutes: a bot takes time to ingest the diff and you'll just see "review
pending" repeatedly.
Two ways to handle the wait:
- Manual — finish Phase 5, tell the user "Pushed round N, replied to M threads, waiting for
re-review", and stop. They re-invoke when they see new feedback.
- Autonomous — run inside
/loop (the user invokes /loop /address-review <PR>, or you
suggest it when they ask for autonomous iteration). Each invocation does one round and exits; the
loop wrapper handles cadence. Inside a /loop dynamic-mode session, use ScheduleWakeup with
600–900 seconds for the next check.
When you wake, re-run Phase 1 and compare against the saved comment IDs and head SHA:
- New comments → loop back to Phase 2.
- No new comments and
reviewDecision != APPROVED → wait again (longer; the human is busy).
reviewDecision == APPROVED and no unresolved threads → done, report and stop.
Loop exit conditions
Done when all of:
reviewDecision == APPROVED
- No unresolved review threads (every reviewer comment has a PR-author reply newer than the
reviewer's last message)
- No new comments since the last push
- Required status checks pass (
statusCheckRollup rolls up to SUCCESS)
If any is false, there's more work.
Edge cases
- CI failing on the latest commit: fix CI before responding to comments — bots dismiss
everything else until the PR is green, and a human won't approve over red checks.
- Merge conflicts with
config.defaultBranch: resolve before pushing. If non-trivial, ask the
user before merging/rebasing — destructive history rewrites should not be silent.
- Already approved but new comments arrived: still address them; approval can be revoked.
- A bot re-flags something you already replied to: reply again with the prior commit SHA. Don't
re-fix.
- A reviewer requests scope creep: reply acknowledging, file a follow-up issue, link it from the
reply. Don't expand the PR. (If
create-issue is installed, use it to file the follow-up.)
- Comment volume is huge (50+ items): surface the count to the user before diving in. Group by
file, address highest-impact first; some bot comments may be safely batch-skipped with one
explanation.
- The PR author is not the user (helping someone else): bail out — this skill is for responding
to reviews of the user's own PRs. Bystander replies muddy the thread.
Anti-patterns
- ❌ One mega-commit titled "address review comments"
- ❌ Pushing without replying to threads
- ❌ Blindly applying every bot suggestion (judgment is part of the job)
- ❌ Sycophantic replies ("Thanks so much for catching that!")
- ❌ Force-pushing without
git status first — scripted edits live in the working tree, not commits
- ❌ Resolving threads where the reviewer asked an open question you haven't answered
- ❌ Looping at a too-tight cadence (<5 min) — the bots haven't even ingested the push yet
- ❌ Silently siding with a bot over a human (or vice versa) when they conflict — surface it
A complete example
User: /address-review 234
gh pr view 234 --repo <config.repo> ... → branch feat/auth, head abc1234, OPEN,
decision CHANGES_REQUESTED.
- Fetch all four endpoints in parallel. Find: 3 CodeRabbit inline, 1 CodeRabbit summary review,
2 human inline, 0 prior replies from me.
- Triage: 4 valid (1 CodeRabbit + 1 human are bug-level, 2 CodeRabbit are clarity), 1 nitpick
(skip + reply), 1 human question (reply only).
- Four commits:
fix(auth): nil session check, fix(auth): close listener on shutdown,
refactor(auth): extract token validator, docs(auth): clarify TTL semantics.
git status clean; git log @{u}..HEAD --oneline shows exactly those 4.
- Pre-flight via
create-pr (or config.commands.*) green.
git push → new head def5678.
- Post 6 replies — 4 inline referencing the new SHAs, 1 inline "skipped, here's why", 1 PR-level
round-2 summary.
ScheduleWakeup in 600s (or stop and report "round 2 pushed, 6 replies posted, waiting").
- Wake: CodeRabbit posted 1 new inline (a regression it sees). Loop to Phase 2.
- Fix, push, reply. Wake again: CodeRabbit and the human both approved, no unresolved threads, CI
green. Report done.