ci-watch
Use for broken checks, flaky tests, or merge-blocking pipeline noise.
Phases
Phase 1 — Triage
- Identify the active PR or HEAD commit.
- List non-passing checks.
- Separate required failures from advisory noise.
Read PR state: gh pr view N --json mergeable,mergeStateStatus,reviewDecision,statusCheckRollup
Phase 2 — Diagnose
- Inspect the first failing required job deeply (logs, not just the summary line).
- Name the smallest fix — or the exact reason the failure is pre-existing / unrelated to the current change.
Phase 3 — Fix or Monitor
- If fixable: apply smallest fix, push, watch checks settle.
- If not fixable now: document the blocker and surface it as output.
- For checks that take >1 min to settle: use a Monitor until-loop rather than busy-waiting.
Output
BLOCKED — <job name>: <one-line cause>
Fix: <smallest concrete action>
Blocks shipping: yes / no
CLEAR — all required checks green
Reconciliation
CI WATCH — <PR/SHA>
Phase 1 Triage: N failing checks (<X> required, <Y> advisory) ✅
Phase 2 Diagnose: root cause: <description> ✅
Phase 3 Fix: <action taken> | (blocked: <reason>) ✅
Result: RESOLVED | BLOCKED (requires: <what unblocks it>)
PR state machine
| mergeable / state | Action |
|---|---|
MERGEABLE + CLEAN |
proceed to merge |
MERGEABLE + UNSTABLE |
non-required check failing; poll required-only checks |
MERGEABLE + BEHIND |
gh pr update-branch or local rebase + force-push |
MERGEABLE + BLOCKED |
check reviewDecision and branch protection |
CONFLICTING + DIRTY |
local rebase first; if GH disagrees → webhook desync, close+recreate |
UNKNOWN + UNKNOWN |
wait 15s, recheck; if STILL UNKNOWN try gh pr merge directly |
Common gotchas
UNKNOWNoften means the PR was already merged in another window.mergeStateStatus: BLOCKEDwith no failing checks = review or branch protection.- PR head SHA disagrees with
git ls-remote= webhook desync. Close + recreate.