Stall watchdog and automation health review. Pulls recent runs, merges, no-op rate, failures, rate-limit hits and stuck PRs; classifies each stall; proposes exactly one change or "no change"; and takes over orphaned work. Use when unattended delivery stalled ("why did it stall overnight", "no merges in N hours", "it was fast the first few days, now slow"), when an automation fails or its output drops, when rate limits or quotas are hit, or on a schedule while agents run unattended.
npx skills add https://github.com/github/lever --skill run-health-review
Unattended work fails quietly. A host restarts and children sit idle, a quota runs out at 2am, a prompt drifts, the pool empties, CI goes red and every worker politely no-ops. Without a watchdog, the human computes "time since last merge" by eye every morning. This skill makes that check a job: measure health from GitHub state, name the stall, change one thing (or nothing), and pick up work that was left half-done.
automation_failed) or its useful-output rate dropped.progress-contract for attended work.pr-shepherd's job.keep-the-pool-full).ACTED / NOOP / BLOCKED mix, failures by reason (reported, crashed, timed_out), latest revision and date.STALL_THRESHOLD and no signal crossed its threshold, end NOOP(healthy) and post nothing.TAKEOVER allows (protocol below).time since last merge: x → y, merged count, stalls by class, the one change (or "no change") with its prediction, takeovers, human-only list. Next run, check last run's prediction first.| Class | Signal | Typical one change |
|---|---|---|
| Supply | Pool empty or low; workers NOOP(no eligible work) | Run keep-the-pool-full; raise its target |
| CI | Main red, or PRs red on the same job | Route to main-red triage; quarantine a proven flake |
| Rate limit (secondary) | 403 or 429 with a rate-limit body or Retry-After; bursts of content-creating writes from many lanes on one identity | Classify as retryable, not permission. Record "not attempted, retry after <absolute time>". Pace all lanes through one budget; serialize writes |
| Quota (primary) | Hourly API, CI-minute or credit cap exhausted | Lower concurrency or trigger breadth; adopt the shared API budget below |
| Permission | BLOCKED on a missing tool, scope or ruleset | One human-only request; or remove the step that needs it |
| Prompt drift | Rising BLOCKED or invalid outputs after a revision; humans overriding outputs | Revert to the last good revision, or propose one contract-rule change |
| Orphaned | Branch or PR with an owner that stopped (host restart, interrupted session) | Take over (below) |
| Trigger | Eligible items with no run (filter too narrow); or many runs per item (too broad) | Adjust one trigger filter; add a sweep |
| Review / merge | Green PRs waiting on threads or approvals | Thread-resolution sweep; check the autonomy level is what the human intended |
| Busy-but-idle | Session reports busy, but there has been no new turn or tool call for longer than IDLE_AFTER | Rekick with what changed and what's expected. Judge liveness by the last tool timestamp, not a status flag |
| Host restart | Coordinator and children went idle at the same time, right after a deploy of the platform they run on | Resume the root first, then its children. Make "resume self" the last step of any self-deploy |
| Self-echo / no-op storm | No-op wakes above 50%, or any wakes triggered by the agent's own writes | Tighten the wake filter (see automate-it step 3) |
| Tool-profile mismatch | A tool fails on every call; a write tool sits in a read-only profile | Remove it, or fix the profile. Every-call failures are a config bug, not flakiness |
ORPHAN_AFTER, whose owner session or automation is no longer running.TAKEOVER allows closing.Quota is the failure mode that grows with success: more agents, more polling, more calls per merge.
Rate limit or Quota stall.| Dial | Default | Options |
|---|---|---|
| STALL_THRESHOLD | 2 h without a merge during active hours, report only | Minutes; per repo |
| Schedule | Hourly during active runs; weekly otherwise | interval; automation_failed |
| TAKEOVER | propose (list candidates, don't act) | continue (claim and push), continue_and_close |
| ORPHAN_AFTER | 2 h without commits and no live owner | Duration |
| Change authority | Propose only | Apply prompt changes via a human; never self-update automations |
| Merge stalled green PRs | Off | On, at the level set in docs/autonomy.md |
| API budget | 75 REST calls per merged PR | Integer; per-hour ceiling |
| Quiet hours | None | No human pings between X and Y; batch into the morning report |
propose_automation_update or a PR to a prompt file.To run the weekly automation half unattended, install automations/automation-health.
Take github/run-health-review from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.