Skip to content

/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.