richkuo/rk-skills/fix-pr-review-loop
Claude Code and agent skill by richkuo/rk-skills
- community
Checking that the SKILL.md file is still in the repository.
Use when the user asks to fix a PR review and drive it to approval autonomously — "fix the PR review and loop until approved", "fix-pr-review-loop", "keep addressing review comments until this PR is approved". Takes an optional PR number/URL (defaults to the current branch's PR). Repeatedly calls fix-pr-review, waits for the bot's re-review (@claude by default, @codex when selected), and repeats. Stops on a bare LGTM, on the first LGTM past 5 cycles, or to escalate when four or more cycles keep…
Install
npx vskill@latest install richkuo/rk-skills/fix-pr-review-loopSKILL.md
fix-pr-review-loop
Resolve the latest review with fix-pr-review, wait for the bot's re-review, repeat. This skill owns the step 3 stop rules and the step 5 table. work-on-issue-loop runs steps 2 to 4 and reuses step 5's table with deltas; edit its step 4 with that table.
Input
Nothing (the current branch's PR via gh pr view), or #<N> / <N> / URL / owner/repo#N.
Steps
1. Resolve the PR and establish the starting state
Run gh pr view <N|--> --json number,headRefName,headRepositoryOwner,baseRefName,url,state,isDraft; merged or closed: stop and report. Compute review_count (0 on a fresh PR) and pr_cycle_count per Round counts in skills/fix-pr-review/rereview-routing.md, which owns both counts and the pending trigger; a verification limitation there stops the loop: report the missing evidence, post nothing. Fetch feedback with fix-pr-review step 1's three-channel query (reviews, issue comments, inline threads). Take the first case that applies:
- Pending trigger present (per Round counts, naming the selected bot): recover it; never post another. One naming the other bot: stop and report.
- Unaddressed feedback present (a completed bot round newer than any disposition comment, or trusted feedback failing fix-pr-review step 1's bare-LGTM check): step 3, no trigger.
- Stale or failed trigger (per Round counts, naming the selected bot: stale, or its round has no verdict and its answering review run finished without one; a queued or in-progress re-run keeps it pending): repost it. A round with a verdict never takes this case; a note from any other run never makes a trigger failed. After a disposition comment, repost the trigger's exact line; else it was cycle 1: post the first-review trigger.
- Nothing to act on yet (fresh PR, only your own disposition or trigger comments, only untrusted feedback, or only a trusted bare
LGTMor empty approval): post the first-review trigger as its own one-line comment,gh pr comment <N> --body "<trigger>".
Record each recovered or posted trigger comment's id and created_at as the pending trigger, then go to step 2.
First-review trigger. validate-issue step 6 owns the table; this file states no boundary. Score, first hit: a stamped PR review: line in the linked issue's Execution block (overrides the band), the PR title's [C<score>, …] bracket, the closed issue's [C<score>] prefix. A missing score routes to the heaviest row, the one that takes no score. A Fable review runs only on a stamped trigger, at high unless the user asks for xhigh or stamps it.
Map a stamped model before posting it. Stamped sonnet/haiku: @claude sonnet review; opus with no tier: the bare @claude review; opus with a tier: @claude opus review effort:<tier>; fable: @claude fable review effort:high, with a stamped effort:<tier> in place of high. A stamped bare @claude review names Opus 5.5: with no tier it posts the bare @claude review, and with effort:<tier> it posts @claude opus review effort:<tier>. A line that names the standard @claude trigger in prose selects nothing, and the band decides. Codex: sonnet/haiku post @codex luna review, opus/fable the bare @codex review; never carry a @claude shorthand to @codex. A stamp outside these rows is ignored. Admitted: a model word (sonnet, haiku, opus, fable) in @claude <model> review, a bare @claude review, or a line naming the standard @claude trigger, each with at most one effort:<tier> of low, medium, high, xhigh. Any other model word, a route word, extra trigger text, or another tier: post the band trigger and name the ignored stamp in the report. Blocking re-reviews: skills/fix-pr-review/rereview-routing.md owns the ladder and the Codex rule.
Bot selection. @claude by default. @codex only on explicit selection: the user, a caller's reviewBot: codex, or a run started from an @codex comment; a codex.yml alone selects nothing. Never switch bots mid-cycle.
Preflight. A workflow answers the selected bot by its contents, whatever its filename (the minimal Codex template is codex-review.yml). List gh api repos/{owner}/{repo}/contents/.github/workflows --jq '.[].name'; read each .yml/.yaml via gh api repos/{owner}/{repo}/contents/.github/workflows/<file> --jq .content | base64 -d. It answers when it runs on issue_comment, a job condition matches the bot's mention (@claude or @codex), and a job runs anthropics/claude-code-action or openai/codex-action, directly or in a reusable workflow its uses: names (<owner>/<repo>/.github/workflows/<file>@<ref>; confirm it via gh api 'repos/<owner>/<repo>/contents/.github/workflows/<file>?ref=<ref>'). An installed Claude GitHub App also answers Claude. Codex needs the OPENAI_API_KEY secret, plus CODEX_APP_ID, CODEX_APP_PRIVATE_KEY and the CODEX_BOT_LOGIN variable only when the answering workflow carries the write routes (the full bundle's codex.yml). If none answers, stop and point the user at templates/claude-workflow/workflows/claude.yml (plus CLAUDE_CODE_OAUTH_TOKEN, the Claude GitHub App, and a runs-on they have) or templates/codex-review.yml.
2. Wait for the review to land
Wait for an output from the review-bot set (github-actions[bot], claude[bot]; owner skills/fix-pr-review/fetch-recipes.md Author trust), posted after the pending trigger's created_at, that passes Round counts' completed-verdict test. No other author ends the wait.
Use the filter as written; never read authors from gh pr view. <file> is the preflight's answering workflow. Run one inline sanity check that prints verdict on an existing review, then the loop in the background (Monitor tool). Last line verdict: step 3. failed: stop and report the bot did not respond. Cap the wait at roughly 30 minutes, then report the same.
3. Check the review against the stop conditions
Recompute both counts per Round counts (the ended round counts once; a verification limitation stops the loop, naming the missing evidence). Classify the latest completed review-bot round as fix-pr-review steps 1 and 3 do: verdict (LGTM / Needs Updates; none without a bot review) and finding sections (Needs Fixing, Requires Human Review, Recommended Optional, Create Follow-up Issue); a **Verification limitation:** line is no finding. On the whole unaddressed trusted set fix-pr-review step 1 collects (skills/fix-pr-review/fetch-recipes.md Author trust and Collection rules; untrusted feedback never enters), run its two checks: nothing to act on (bare-LGTM check passes) and blocking (a blocking finding). In order:
- Merge conflict.
gh pr view <N> --json mergeable,mergeStateStatusshowsCONFLICTING/DIRTY: never terminal; step 4, even on a bare LGTM. - Clean pass, stop.
LGTMand nothing to act on, at anyreview_count: step 5. - Past the cap, stop.
review_count > 5,LGTM, and not blocking, even withRecommended OptionalorCreate Follow-up Issueitems: step 5. - Diverging, stop.
pr_cycle_count >= 4,Needs Updates, and every blocking finding sits in code an earlier cycle of this loop added: step 5, Diverging row. Such code is a line whosegit blameat the PR head names a commit that is an ancestor of neither<first-push-sha>nororigin/<baseRefName>; a line a step 7 base merge brought in is base-branch work and never counts. An unattributable blocking finding (nofile:line, or a path or line the head no longer has) defeats this rule. - Otherwise, keep going. Every other state, including
Needs Updatesat any count without rule 3, and trusted feedback with no bot verdict yet: step 4.
4. Resolve the review and loop
Invoke fix-pr-review (Skill tool, skill: fix-pr-review). It validates every finding, fixes the real ones, resolves merge conflicts (its step 7), commits, pushes, posts the disposition and its own re-review trigger (its step 10; never add a second), and decides its own delegation (its step 5). Route on its result:
- Trigger posted: record its
idandcreated_atas the pending trigger; step 2. No count changes until step 3. - Retry, no trigger (the same trigger already followed this pass's disposition, its step 10 retry case): recover that comment by the URL and
created_atits report names. No verdict yet: pending trigger, step 2. Verdict: step 3. Never post a trigger for the retry. - Its step 1 stop (a bare
LGTM, or no trusted feedback): step 5 as a clean pass when step 3 had a botLGTM, else post the first-review trigger per step 1; step 2. - Its step 7 merge re-review rule: the rule below decides.
- Its step 6 stop on an ungrounded failing test: step 5, Blocked on a test.
- Any other stop (an irreconcilable conflict, a rejected push, a head mismatch): step 5, Fixer stopped.
Only the step 1 stop and the merge rule's prose-only case report Done.
Merge re-review rule (owner fix-pr-review step 7; milestone-workflow step 5 sub-step 3 applies it): for a bare-LGTM PR whose only work this cycle was a base merge, the complete diff from the reviewed head to the new head decides. Prose only keeps the LGTM, no trigger. A behavior change, any doubt, or no established reviewed head: it posted @claude sonnet review (or @codex luna review); step 2. With no trigger, re-read gh pr view <N> --json mergeable,mergeStateStatus: UNKNOWN (GitHub recomputing), retry every 30 seconds up to roughly 5 minutes, then the bot-never-responded row; MERGEABLE, the LGTM stands, step 5 as a clean pass; CONFLICTING/DIRTY, step 4 again. Only a genuine conflict re-enters fix-pr-review.
5. Report
Report the terminal state; never claim blanket success. Always give the PR URL, cycles run, final verdict, and when escalating exactly what is left. Cap the whole report at 55 words and 5 sentences, plain simple English in ASD-STE100; apply the Response Style rules in CLAUDE.md/AGENTS.md; the unverified-source list sits outside the word cap.
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/fix-pr-review-loop/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/richkuo/rk-skills/fix-pr-review-loop)