gh-pr-clean-loop

Installation
SKILL.md

GH PR Clean Loop

Goal

Drive an open GitHub pull request to a clean state by repeatedly:

  1. inspecting CI and review-thread health
  2. fixing concrete issues
  3. committing and pushing updates
  4. resolving only the threads that were actually addressed
  5. waiting 10 minutes
  6. polling again

Stop only when the PR has no failing or pending checks and no unresolved review threads, or when you hit a blocker that needs user input.

When to use

Use this skill when the user asks to:

  • babysit a PR until it is green
  • fix failing GitHub PR checks and review comments
  • clear unresolved review threads on a PR
  • keep re-polling CI and PR comments until the PR is clean

Preconditions

  • gh is installed and authenticated for the target repository
  • the current branch already has an open PR, or the user provides a PR number or URL
  • the agent has push access to the branch
  • the repo can run the relevant local test/build commands

If authentication fails, stop and ask the user to run gh auth login.

Inputs

  • cwd: repository root; default . if obvious
  • pr: optional PR number or URL; default to the PR for the current branch
  • poll interval: default 600 seconds

Quick start

Run the helper from the repo root:

uv run skills/gh-pr-clean-loop/scripts/pr_health.py --cwd .

Useful variants:

uv run skills/gh-pr-clean-loop/scripts/pr_health.py --cwd . --json
uv run skills/gh-pr-clean-loop/scripts/pr_health.py --cwd . --pr 123
uv run skills/gh-pr-clean-loop/scripts/pr_health.py --cwd . --resolve-thread <thread-id>

Core loop

  1. Verify repo and PR context
  • Run gh auth status.
  • Resolve the active PR with gh pr view if the user did not provide one.
  • If no open PR exists for the branch, stop and report that blocker.
  1. Inspect current PR health
  • Run the helper script to collect:
    • failing checks
    • pending checks
    • unresolved review threads
    • current review decision
  • If the helper is unavailable, fall back to:
    • gh pr checks <pr> --json bucket,name,state,link,workflow
    • gh api graphql for reviewThreads
  1. Triage what to address first
  • Prioritize unresolved review threads that point to clear code changes.
  • Then address failing CI jobs.
  • Treat new top-level PR comments or ambiguous reviewer feedback as blocking if they require product or design decisions.
  1. Implement the next batch of fixes
  • Inspect the referenced files, failing job logs, and local code paths.
  • Make the smallest credible change that addresses the problem.
  • Run all applicable local validation before committing:
    • targeted tests for the changed area
    • broader test suites when the failure or touched area warrants it
    • lint
    • build
  • If lint or build is not relevant for the repo, state that explicitly before committing.
  • If the issue is ambiguous or the requested change conflicts with requirements, stop and ask the user.
  1. Commit and push
  • Create a focused commit for the batch you actually addressed.
  • Do not commit until the applicable tests, lint, and build steps for that batch have passed.
  • Push the branch before resolving review threads.
  • Do not lump unrelated fixes into one commit just because they appeared in the same poll.
  1. Resolve addressed review threads
  • Resolve only threads that are actually addressed by the pushed change.
  • Use the helper script with --resolve-thread, or the direct mutation:
gh api graphql \
  -f query='mutation($threadId:ID!) { resolveReviewThread(input:{threadId:$threadId}) { thread { id isResolved } } }' \
  -F threadId='<thread-id>'
  • If a thread needs explanation rather than code, add the explanation first and only then resolve it when appropriate.
  1. Wait and poll again
  • Sleep for 10 minutes:
sleep 600
  • Re-run the helper script.
  • If checks are still pending and there are no new actionable comments, continue waiting and polling.
  • If new failures or review threads appear, repeat the loop.

Clean PR exit criteria

Treat the PR as clean only when all of these are true:

  • no failing checks
  • no pending checks
  • no unresolved review threads

reviewDecision can remain stale after fixes, so do not use it as the sole blocker if the actual threads and checks are clean.

Helper script

Use scripts/pr_health.py to summarize PR status and resolve review-thread IDs.

What it reports:

  • PR number and URL
  • review decision
  • failing and pending checks
  • unresolved review threads with path, line, URL, author, and a short body excerpt
  • whether the PR is currently clean

Exit codes:

  • 0: clean PR
  • 1: PR still has failing or pending checks or unresolved review threads
  • 2: command or auth failure

Guardrails

  • Do not resolve a review thread before the fix is pushed or the reply is posted.
  • Do not mark a PR clean while checks are still pending.
  • Do not guess at CI failures; read the failing job or log details first.
  • Do not skip applicable tests, lint, or build before committing and pushing.
  • Do not rewrite or force-push shared branches unless the user explicitly asks.
  • Stop and ask the user when a comment implies a product decision, architectural disagreement, or conflicting reviewer guidance.
Related skills
Installs
1
First Seen
Apr 24, 2026