/review-comments skill — contract¶
Project-local Claude Code skill at .claude/skills/review-comments/SKILL.md. Invoked with /review-comments [PR number] on a branch whose PR has open review feedback (or with an explicit PR number).
Why this exists¶
Addressing review comments by hand is the slow part of the review loop: read each thread, find the file, make the fix, write a reply, repeat — and remember which threads you've already answered. This skill does the scan-and-answer pass in one command, and posts the replies under a dedicated bot identity (ogur-claude-bot) so the PR conversation cleanly attributes "the human reviewed, the bot answered."
The skill makes the code fix where a comment requests one, not just a reply — matching this repo's established "address Codex review → targeted fix + regression test" pattern (see commits like db2be67, 0c14231, 21ab139).
The two-identity safety model¶
The gh CLI has two authenticated accounts: khalilouardini (the maintainer, normally active) and ogur-claude-bot. gh auth switch mutates global CLI state, so a botched run could leave the terminal authenticated as the bot and silently mis-attribute the next git push/gh pr. The skill defends against this:
| Guard | Mechanism |
|---|---|
| Identity is always restored | switch→post→switch-back in one subshell with trap 'gh auth switch --user "$ORIG"' EXIT; verified afterward against $ORIG |
$ORIG is never guessed |
captured via gh api user --jq .login before any switch |
| Posting is gated | every draft shown for approval first; reading/drafting are read-only |
| Wrong-identity guard | stop if ogur-claude-bot is absent from gh auth status — never fall back to the human account |
| Commits ≠ comments | code commits use the human's git identity (SSH key); only PR comments go out as the bot |
What counts as "unanswered"¶
The skill reads three comment surfaces and applies a per-surface filter:
| Surface | Source | Unanswered ⇔ |
|---|---|---|
| Inline review thread | GraphQL pullRequest.reviewThreads |
isResolved == false and last comment not authored by ogur-claude-bot and comments not part of a PENDING review |
| Review summary | GraphQL pullRequest.reviews |
submitted, non-empty body, no later reply. PENDING skipped (unsubmitted draft); summaries a human already addressed are annotated and dropped at the gate |
| Conversation comment | REST issues/{pr}/comments |
human-authored, no later bot reply |
[bot] accounts (e.g. cloudflare-workers-and-pages[bot]) are skipped as noise. isOutdated threads are flagged, not skipped. The "last comment by bot ⇒ answered" rule makes re-runs idempotent.
Why the PENDING exclusion matters (caught the first time the skill dry-ran against a real PR): a reviewer's draft review comments show up in the GraphQL reviewThreads of the author's own token but are not published — they don't appear in REST pulls/{pr}/comments, and the reply endpoint rejects them. Filtering on isResolved/last-author alone would surface them; the parent-review-state check (pullRequestReview.state != "PENDING") is what keeps the skill from trying to answer unsubmitted notes.
Scope¶
- In scope: answering existing review feedback on one PR — reply text plus the code fix where warranted.
- Out of scope: initiating reviews, resolving/dismissing threads (left to the human), approving/merging/closing PRs, unattended scheduled runs.
How it differs from existing review surfaces¶
| Skill | Direction | Best for |
|---|---|---|
/review-engine |
Produces findings on ogur/engine/ diffs (prove-the-bug) |
Reviewing your own engine changes before requesting review |
/code-review (built-in) |
Produces findings across any code | Quick PR review |
/review-comments (this skill) |
Consumes findings — answers comments others (or Codex) left | Working through the review feedback you received |
/review-engine and /code-review are reviewer tools; /review-comments is the author's response tool. They sit on opposite ends of the same review loop.
When to invoke¶
- After a reviewer (human or Codex) has left comments on your PR and you want to work through them in one pass.
- When you've lost track of which threads are still open versus already answered — the filter does the bookkeeping.
Implementing rule of thumb¶
Read and draft freely; switch identity and post only once, atomically, after approval. Everything before the confirm gate is reversible; the only outward action is the bot posting, and it must always end with the active account restored.