Polish
/polish - Iterative PR Green Loop (up to N iterations)
Claude CodeGeneric
---
description: /polish - Iterative PR Green Loop (up to N iterations)
type: llm-orchestration
execution_mode: immediate
---
## ⚡ EXECUTION INSTRUCTIONS FOR CLAUDE
**When this command is invoked, YOU (Claude) must execute these steps immediately.**
**This is NOT documentation - these are COMMANDS to execute right now.**
**Use TodoWrite to track progress through multi-phase workflows.**
**Usage:** `/polish [N] [PR_NUMBER]`
- `N` = max iterations (default: 5)
- `PR_NUMBER` = target PR (default: auto-detect from current branch)
**Goal:** Drive the PR to all 6 green conditions, looping up to N times.
**CRITICAL — DO NOT MERGE:** This command evaluates and fixes PR readiness. It NEVER executes merge commands (`gh pr merge`, `gh api .../merge`). Merging requires explicit human "MERGE APPROVED" in the conversation. Reporting "6-green" is the terminal state — not merging. This rule is enforced by PreToolUse hook `block-merge-worldarchitect.sh` for your-project.com.
---
### 6 Green Conditions (all must hold to stop)
1. **CI passing** — all statusCheckRollup checks show SUCCESS/NEUTRAL/SKIPPED (no FAILURE, ERROR, TIMED_OUT, CANCELLED, ACTION_REQUIRED). If any check has `status: IN_PROGRESS` → not pass — poll/retry until all are COMPLETED, then verify conclusions.
2. **No merge conflicts** — `mergeable: MERGEABLE` (handle UNKNOWN by retrying/poll)
3. **CodeRabbit APPROVED** — latest review by "coderabbitai[bot]" has state `APPROVED`
4. **Cursor Bugbot finished** — if Bugbot is absent from `statusCheckRollup` → acceptable (not configured). If present: conclusion `SUCCESS`/`NEUTRAL`/`SKIPPED` → pass. If present with `conclusion: null` and `status: IN_PROGRESS` → poll/retry until complete. Treat `FAILURE`, `ERROR`, `TIMED_OUT`, `CANCELLED`, `ACTION_REQUIRED` as red, consistent with condition 1.
5. **All inline comments resolved** — Major/Critical from any bot/human are blockers
6. **Evidence review passed** — `/er` returns PASS (skip if no evidence bundle)
---
### Loop Algorithm
```text
# Derive repo context once before the loop
REPO_FULL="$(gh repo view --json nameWithOwner --jq '.nameWithOwner')"
OWNER="${REPO_FULL%%/*}"
NAME="${REPO_FULL##*/}"
PR="<PR_NUMBER>"
for iteration in 1..N:
1. Run /copilot <PR_NUMBER> # fetch + triage all comments, fix blocking issues
2. Run /fixpr <PR_NUMBER> # fix any remaining inline PR blockers
3. Run /er # check evidence bundle (skip if none present)
4. If changes made → commit + push with /pushl
5. Wait for CI to settle (gh run watch or poll statusCheckRollup)
6. Evaluate 6 green conditions:
# Fetch CI status and mergeability
gh pr view <PR_NUMBER> --json statusCheckRollup,mergeable,mergeStateStatus
# Use GraphQL to get bot-specific reviews and thread resolution.
# Paginate reviewThreads: real PRs can exceed 100 threads (see automation/jleechanorg_pr_automation).
# reviewThreads uses cursor-based pagination: on first call omit cursor entirely (pass no cursor param — not even empty string);
# read pageInfo { hasNextPage endCursor }; if hasNextPage is true, re-run with -f cursor=<endCursor>,
# accumulating all nodes until hasNextPage is false. Do NOT pass cursor="" — GitHub GraphQL rejects empty string cursors.
# If any thread may have >20 comments, page through that thread's comments connection using its pageInfo until all comments are collected.
# Note: the reviews connection uses last:100 ordered chronologically by submittedAt — sufficient for most PRs; if CR has >100 reviews, accumulate in reverse order. Add pageInfo to all paginated connections for cursor-based navigation.
gh api graphql \
-f query='
query($owner:String!, $name:String!, $pr:Int!, $cursor:String) {
repository(owner:$owner, name:$name) {
pullRequest(number:$pr) {
reviews(last:100) {
pageInfo { hasNextPage endCursor }
nodes { author { login } state bodyText submittedAt }
}
reviewThreads(first:100, after:$cursor) {
pageInfo { hasNextPage endCursor }
nodes {
isResolved
comments(last:20) {
pageInfo { hasNextPage endCursor }
nodes { author { login } body }
}
}
}
}
}
}
' \
-f owner="$OWNER" -f name="$NAME" -F pr="$PR"
- Check CI: statusCheckRollup shows no FAILURE/ERROR/TIMED_OUT/CANCELLED/ACTION_REQUIRED
- Check mergeable: MERGEABLE (handle UNKNOWN state by polling)
- Filter reviews by author.login matching "coderabbitai" (GitHub GraphQL may return bot logins with or without the `[bot]` suffix — test both `coderabbitai` and `coderabbitai[bot]`) → sort chronologically using `submittedAt`, find most recent APPROVED. If the most recent CR review is NOT APPROVED, fail. Additionally: if the most recent APPROVED has a more recent CHANGES_REQUESTED or COMMENTED after it, the APPROVED is stale — fail in that case too. Only pass when the latest CR review IS APPROVED and no newer CHANGES_REQUESTED/COMMENTED exists after it.
- Filter statusCheckRollup by name containing "Bugbot" → if absent from statusCheckRollup entirely → acceptable (Bugbot not configured for this repo). If present with conclusion SUCCESS/NEUTRAL/SKIPPED → pass. If present with conclusion null AND status IN_PROGRESS → poll/retry (not pass). Treat FAILURE, ERROR, TIMED_OUT, CANCELLED, ACTION_REQUIRED as red.
- Check reviewThreads: verify no unresolved Major/Critical comments
- Check evidence: /er PASS or no bundle
7. If ALL 6 green → STOP, report success
8. Continue to next iteration
Note on CI evaluation timing: Each iteration pushes (step 4) then waits for CI to settle (step 5), so fixes land before the next iteration's evaluation. With N=1 and fixes needed, CI must complete and r ```
Maintain Polish?
Let people know it's listed here — add the badge (live metrics, light/dark aware) or a plain link to your README or docs.
[Polish on getagentictools](https://getagentictools.com/loops/jleechanorg-derive-repo-context-once-before-the-loop?ref=badge)