name: greenlight-pr description: Greenlight a PR — fix CI failures, triage review comments, iterate until green. argument-hint: "[PR number or URL]" hooks: PostToolUse: - matcher: "*" hooks: - type: command command: 'python3 "$HOME/.claude/skills/skill-feedback/scripts/skill-event.py" --skill greenlight-pr --event skill_activated --agent-harness claude-code --quiet' timeout: 5
Greenlight PR
Drive a PR to green — fix CI, address AI code reviews, iterate until merge-ready.
You are the decision-maker, not the reviewer. AI review bots do the reviewing. You evaluate their feedback, decide what's worth fixing, fix it well, and iterate until clean.
Tool
python3 ~/.claude/skills/greenlight-pr/scripts/gl-snapshot.py [PR]
Returns structured JSON: CI status, review comments (with code context), and recommended actions. State persists in /tmp/gl-{repo}-pr{N}.json.
| Flag | Purpose |
|---|---|
7 |
Explicit PR number |
--mark-seen 123,456 |
Mark comment IDs as processed |
--retry-failed |
Rerun failed CI jobs (budget: 3/SHA) |
--wait-review |
Poll until new comments appear (timeout: 5min) |
--timeout 120 |
Custom timeout for --wait-review |
--reset |
Clear state for fresh start |
Code Review Skill Awareness
The code-review skill posts inline PR comments — just like CodeRabbit or any other bot. Greenlight-pr triages them all the same way.
The difference: code-review signals its status via HTML comment markers in PR comments:
<!-- code-review-status: in_progress -->— review is running<!-- code-review-status: complete -->— review is done, findings posted
Whenever you are about to triage comments or wait for reviews, also check if a code-review is in progress. If it is, wait for it to finish before proceeding (poll every 30s, timeout 10min). This is in addition to the existing --wait-review polling for external bots — both must finish before you triage.
# Check if code-review skill is still running
COMMENTS=$(gh pr view [PR] --comments --json comments -q '.comments[].body')
if echo "$COMMENTS" | grep -q 'code-review-status: in_progress' && \
! echo "$COMMENTS" | grep -q 'code-review-status: complete'; then
# Poll until complete
for i in $(seq 1 20); do
sleep 30
COMMENTS=$(gh pr view [PR] --comments --json comments -q '.comments[].body')
echo "$COMMENTS" | grep -q 'code-review-status: complete' && break
done
fi
Terminal States
| State | Meaning | Agent behavior |
|---|---|---|
done |
CI green, no pending bot reviews, no new comments | Report merge-ready |
stop_pr_closed |
PR was merged or closed | Stop |
stop_exhausted_retries |
Flaky CI retry budget used up | Escalate to user |
stop_waiting_review_pending |
Timed out waiting; external bot review still pending | Report "blocked on external review" and exit cleanly — do not present as finished or merge-ready. Rerun later. |
Main Loop
snapshot = gl-snapshot.py [PR]
actions = snapshot.actions
loop:
if "stop_pr_closed" in actions:
return "PR merged or closed"
if "stop_exhausted_retries" in actions:
return "CI retries exhausted — ask user"
if "fix_ci" in actions:
for each check in snapshot.ci.failed:
if check.classification == "branch":
read check.log_excerpt
find the failure cause in the code
fix it
commit → push
goto snapshot
if "retry_ci" in actions:
gl-snapshot.py --retry-failed
gh pr checks [PR] --watch --fail-fast
goto snapshot
if "triage_comments" in actions:
check for code-review in progress → wait if needed (see above)
run TRIAGE PROCESS (see references/triage-process.md)
push fixes
gh pr checks [PR] --watch --fail-fast # wait for CI first
snapshot = gl-snapshot.py --wait-review # polls with timeout; returns full snapshot
check for code-review in progress → wait if needed
actions = snapshot.actions # may be stop_waiting_review_pending if timed out
continue loop # re-evaluate from wait result
if "wait_review" in actions:
snapshot = gl-snapshot.py --wait-review # polls with timeout; returns full snapshot
check for code-review in progress → wait if needed
actions = snapshot.actions # may be stop_waiting_review_pending if timed out
continue loop # re-evaluate — do NOT re-snapshot
if "wait_ci" in actions:
gh pr checks [PR] --watch --fail-fast
goto snapshot
if "stop_waiting_review_pending" in actions:
return "CI green, no actionable comments yet, but external bot review still pending. Rerun later."
if "done" in actions:
return "CI green, no pending bot reviews, no new comments — merge-ready"
Happy Path Example
Concrete commands for the most common flow: bot posts comments → triage → fix → re-review.
# 1. Snapshot
python3 ~/.claude/skills/greenlight-pr/scripts/gl-snapshot.py 42
# → actions: ["triage_comments"], new_comments: [{id: "123", body: "...", code_context: "..."}]
# 2. Triage (see references/triage-process.md)
# Read comments, spawn sub-agents, decide FIX/DISAGREE/DEFER
# Fix the code...
# 3. Commit and push
git add -A && git commit -m "Address review: fix X, Y" && git push
# 4. Reply to each comment
gh api repos/owner/repo/pulls/42/comments/123/replies -f body="Fixed — description. See abc1234"
# 5. Post round summary
gh pr comment 42 --body "## Greenlight — Round 1
**Fixed (2):** X, Y
**Disagreed (1):** Z — reasoning"
# 6. Mark as seen
python3 ~/.claude/skills/greenlight-pr/scripts/gl-snapshot.py --mark-seen 123,456,789
# 7. Wait for bot re-review, then re-snapshot
gh pr checks 42 --watch --fail-fast
python3 ~/.claude/skills/greenlight-pr/scripts/gl-snapshot.py --wait-review
python3 ~/.claude/skills/greenlight-pr/scripts/gl-snapshot.py 42
# → new round: check actions again
What counts as a comment
The snapshot only returns inline review comments with code_context (the diff hunk). It ignores:
- Big walkthrough/summary comments that bots post at the top of the PR
- Issue-level comments (not attached to a line of code)
- Your own replies
If CodeRabbit auto-marks a comment as "Addressed in commit X", you don't need to reply again unless you want an audit trail.
Recovery after interruption
State persists in /tmp/gl-{repo}-pr{N}.json. If a session is interrupted, just re-run the snapshot — it picks up where you left off with all processed comment IDs intact.
Triage Process (overview)
The full process with sub-agent prompts and decision trees is in references/triage-process.md. Summary:
Phase 1 — EVALUATE
spawn sub-agents to evaluate each comment
each returns: verdict (FIX/DISAGREE/DEFER) + reasoning + confidence
Phase 2 — SYNTHESIZE
collect sub-agent results
resolve conflicts (agents may disagree)
filter: only HIGH/MEDIUM confidence FIXes that pass quality check
Phase 3 — ACT
implement fixes (one commit, grouped)
reply to every comment individually
post round summary as PR comment
gl-snapshot.py --mark-seen <ids>
Guardrails
- Think before fixing. Don't blindly apply every bot suggestion.
- No workarounds. If you can't fix it properly, disagree or defer.
- No over-engineering. Push back on suggestions that add complexity without solving real problems.
- Always reply. Every inline comment gets a reply. Every round gets a summary.
- Wait for re-review. After every push,
--wait-reviewthen re-snapshot. - Know when to stop. 3+ rounds of only nit/duplicate comments → done.
- Escalate. Product decisions → stop and ask user.
References
references/triage-process.md— Sub-agent prompts, decision pseudocode, quality checks, reply templatesreferences/ci-classification.md— Branch vs flaky heuristicsreferences/known-bots.md— AI review bot catalog and re-review patterns
AZ Skill Feedback
After the run, if this skill was useful, confusing, broken, or missing context, submit 1-3 safe sentences. Include --agent-harness when known. Include --model-config only if the harness exposes the exact model/config; otherwise leave it as unknown:
python3 ~/.agents/skills/skill-feedback/scripts/skill-feedback.py --skill greenlight-pr --rating idea --text "..."
Never include secrets, private data, source code, long prompts, or stack traces.