Install
$ agentstack add skill-richkuo-rk-skills-work-on-issue-loop ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
work-on-issue-loop
Drive an issue from "validated" to "PR reviewed to convergence" without stopping in between: implement (work-on-issue), wait for the review bot, resolve what it finds (fix-pr-review), and repeat. Past 5 cycles the bar for "done" relaxes — any LGTM ends the loop — so a PR with recurring minor findings doesn't get fix-pr-review'd forever. Steps 2–5 below are this same convergence loop that fix-pr-review-loop runs standalone against any already-open PR — use that skill directly when there's no issue to implement first, just an existing PR to drive to approval.
Input
- Nothing — default to the issue just validated this session, else the latest open issue (
gh issue list --limit 1). #/ `/ full URL /owner/repo#N`.
Steps
1. Implement, open the PR, and trigger the first review
Invoke the work-on-issue skill for the issue (Skill tool, skill: work-on-issue). It implements the fix in an isolated worktree, verifies it, commits, pushes, and opens the PR (Closes #) — it does not request review; that's this loop's job.
Gate on its outcome before continuing — work-on-issue can legitimately stop early:
- Stopped with no PR (issue already closed, an existing PR already addresses it, wrong repo checked out) → there is nothing to drive; stop and relay its report.
- PR opened → capture the PR number/URL and the branch, then trigger the first review yourself. Don't wait on CI or poll
gh pr checks— CI runs in parallel and the reviewer surfaces check failures itself. Post a separate, one-line comment so the bot fires cleanly (match the repo's trigger phrase if it differs — check recent PR comments; a trigger mention is not authored content — no footer):
gh pr comment --body "@claude review"
Preflight — confirm a review bot exists before waiting on one. This loop assumes an automated reviewer that answers @claude review comments. Before entering the wait, check the repo for one: gh api repos/{owner}/{repo}/contents/.github/workflows --jq '.[].name' and look for a workflow that responds to @claude (e.g. claude.yml), or confirm the Claude GitHub App is installed. If you find none, don't sink 30 minutes into a review that will never come — tell the user the PR is pushed but no review bot is configured, and point them at templates/claude-review.yml in this repo (copy it to .github/workflows/, add an ANTHROPIC_API_KEY secret). Proceed into the wait only if a reviewer is present or the user confirms one is configured elsewhere.
Record the timestamp of the trigger comment and set review_count = 1 — that review is #1 in flight.
2. Wait for the review to land
Poll the PR for a new review or issue comment posted after the last trigger you sent — reviews can land as a formal PR review or as an issue comment (the @claude bot usually posts as an issue comment; see fix-pr-review step 1 for the gh calls to check — it also fetches inline diff threads, which matter when a human reviewer weighs in). An until-loop is the right shape here — you want to be notified once the condition is true, not to busy-poll inline:
until gh pr view --json comments,reviews --jq '
([.comments[] | select(.createdAt > "")] |
any(.body | test("(^|\\n)(LGTM|Needs Updates)"))) or
([.reviews[] | select(.submittedAt > "")] | length > 0)
' | grep -q true; do sleep 60; done
Two load-bearing details in that condition (both have silently broken monitors before — a wrong filter here reads as "no review yet" forever):
- Match the verdict with
(^|\\n), not^+ themflag. In jq's regex (Oniguruma),mmeans dot-matches-newline, NOT multiline anchoring —^only matches the very start of the body. The@claudeGitHub Action buries its verdict below a**Claude finished …**header and a---, so an anchored-at-start pattern never matches. (The bot also edits its placeholder comment in place rather than posting a new one;createdAtstays at placeholder time, which is still after your trigger, so the timestamp filter is fine.) - Pipe through
grep -q true.gh --jqprintstrue/falsebut exits 0 either way, so a bareuntil gh …; dowould exit the loop on the first poll regardless of the value.
Run this as a background until-loop (e.g. via the Monitor tool) so you're notified on completion instead of blocking synchronously. Cap the wait at roughly 30 minutes; if no review appears in that window, stop and report to the user that the @claude bot didn't respond — don't loop indefinitely on a bot that may be down or misconfigured. Before trusting a freshly armed monitor, sanity-check its condition once inline against the live PR — if a review is already present it must print true.
3. Check the review against the stop conditions
Fetch the latest review and classify it exactly like fix-pr-review steps 1–2: verdict (LGTM / Needs Updates) and which sections are present (Needs Fixing, Requires Human Review, Recommended Optional, Create Follow-up Issue).
Evaluate in this order:
- Clean pass — stop, success. Verdict is
LGTMand no sections at all — nothing under Recommended Optional or Create Follow-up Issue either. Nothing left to fix, at anyreview_count. Go to step 5. - Past the cap and it's an LGTM — stop, first one wins.
review_count > 5and verdict isLGTM(even with Recommended Optional / Create Follow-up Issue items still listed). Once the loop has run more than 5 cycles, the first LGTM it sees ends it — don't spend a 6th+ fix-pr-review cycle chasing non-blocking findings. Go to step 5. - Otherwise — keep going. Verdict is
Needs Updates(at anyreview_count— there is no cycle count that alone stops aNeeds UpdatesPR; only an LGTM does, per rules 1–2), or verdict isLGTMwith findings still listed andreview_count " --state all).
- Include every filed issue URL (and any deliberately-unfiled item) in the step 5 report.
The failure mode this prevents: a PR merges with follow-ons named only in prose, everyone moves on, and the work silently evaporates.
5. Report
Stop the loop and report the terminal state — don't claim blanket success:
| Terminal state | Report as | |---|---| | Clean LGTM, no findings, at or before review_count 5 | Done. PR is approved with nothing outstanding. | | review_count > 5 and an LGTM (with non-blocking items remaining) ended the loop | Done, with leftovers. PR is approved; note the remaining optional/follow-up items that were left unaddressed once the loop passed 5 cycles. | | Bot never responded within the wait window | Escalate. Report that the PR is implemented and pushed but review never landed; the user should check the @claude GitHub Action / bot status. | | work-on-issue stopped with no PR (closed issue / existing PR / wrong repo) | Nothing to drive. Relay its report; zero review cycles ran. |
There is no "stuck on Needs Updates past the cap" case to report — per step 3, Needs Updates never stops the loop by cycle count alone; it keeps calling fix-pr-review until an LGTM appears (or the bot stops responding, the row above).
In every case, give: PR URL, number of review cycles run, final verdict, which model each fix cycle ran on (per fix-pr-review's findings-based selection), any follow-on issues filed in step 4.5 (URLs) or deliberately left unfiled, and (if escalating) exactly what's left.
Cap the report at 55 words, ELI18 — plain language, no jargon, as if explaining the outcome to a smart 18-year-old with no context on this codebase or its internals.
Red Flags — STOP
| Situation | Action | |---|---| | review_count > 5 and the latest verdict is LGTM | Stop right there — don't invoke fix-pr-review again just because non-blocking findings remain; report per step 5 | | review_count > 5 and the latest verdict is still Needs Updates | Keep going — invoke fix-pr-review and loop again; the cap only changes what counts as "done" on an LGTM, it never force-stops a Needs Updates PR | | Latest "review" is your own prior fix-pr-review disposition comment or an @claude review trigger comment, not an actual review | Skip it — keep waiting/polling for the real next review, same rule as fix-pr-review step 1 | | Review bot hasn't responded after ~30 minutes | Stop waiting; report that review didn't land rather than polling forever | | Tempted to treat "LGTM with Recommended Optional items" as terminal at review_count <= 5 | It isn't — below the cap, LGTM-with-findings still goes through fix-pr-review; only past the cap does the first LGTM end it regardless of findings | | PR gets closed or merged mid-loop (e.g. by the user) | Stop immediately; don't keep pushing fixes to a closed/merged PR | | work-on-issue stopped with no PR | Don't trigger a review or enter the wait loop — gate on its outcome in step 1 and report per step 5 | | About to report "Done" while the PR/README names follow-on work with no issue filed | Stop — run step 4.5 first; a named follow-on with no issue and no "deliberately unfiled" note in the report is a silent drop |
Common Mistakes
- Treating any LGTM at or below
review_count5 as terminal. Below the cap, only a bare LGTM (no sections) stops the loop; an LGTM with leftover optional/follow-up findings still goes through another fix-pr-review cycle. - Hard-stopping a
Needs UpdatesPR oncereview_countpasses 5. There's no such rule — the cap only lowers the bar for what counts as "done" once an LGTM shows up; it never stops the loop on its own. - Losing count across cycles. Track
review_countexplicitly — it's what distinguishes "full fix cycle" from "first-LGTM-wins" behavior. - Polling synchronously forever. Use an until-loop with a timeout so a non-responding bot doesn't hang the whole run.
- Re-triggering review on top of fix-pr-review's own trigger. fix-pr-review already posts its own re-review trigger as a separate comment (its step 7) — don't add a second one here.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: richkuo
- Source: richkuo/rk-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.