watch-prs — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited watch-prs (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Run /pr-status on a self-rescheduling loop until a stop hour. Each tick is an ordinary /pr-status run that ends by scheduling the next one. Unattended — leave it in a tab.
/pr-status owns the shared read-only feedback call at ~/.agents/skills/pr-status/scripts/gh-pr-feedback.py; the watcher must not duplicate it. This preserves stable identity/update comparisons and makes partial fetches visible on each dashboard.
/watch-prs # adaptive cadence, stop at 18:00 (default)
/watch-prs 17 # adaptive, stop at 17:00
/watch-prs 10m # fixed 10-minute interval, stop at 18:00
/watch-prs 5m 17 # fixed 5m, stop at 17:00Only for a normal valid execution request, not when reading this file as context, record once:
~/.agents/skills/watch-telemetry/scripts/watch_telemetry.py record watch-prs {harness} invocationBind {harness} to pi or claude from the known current harness, never a model name or shell probe; otherwise skip. Use only already-permitted recording. Never enable collection, change permissions, or wait for telemetry approval. Missing/denied/failed recording must not block work. Do not count status, reset, recheck, disposition, or internal ticks as invocations. The self-contained tick prompt owns tick recording; do not record again on a nested skill read. See the counter contract for opt-in, partial coverage and retention.
Parse arguments: a positive interval matching \d+m (absent → adaptive mode, the default), and a stop hour from 0 through 23 (default 18). If an argument is invalid, explain the accepted forms and stop. Resolve today's stop hour in local time. If the current time is already at or past that deadline, say so and don't start.
If watch_loop is available, use this path instead of Claude scheduling:
watch_loop with action: status. Continue only when its result reportsprotocolVersion: 1. If another watch is armed, running, or paused, do not replace it; show the status and point at /watch-status, /watch-stop, or /watch-resume. If the version differs, explain the mismatch and stop without scheduling anything.
stopAt. When already permitted, first run `~/.agents/skills/watch-telemetry/scripts/watch_telemetry.py record watch-prs pi tick` once; telemetry failure must not block the watch. Then Load and follow the skill named `pr-status` now. Render its full dashboard as visible text. Do not execute any suggested action. Read the final `next-tick:` line and use its numeric N as the adaptive delay when required. Finish only after the dashboard with the matching `watch_loop complete` call injected by the runtime. action: start
protocolVersion: 1
label: PRs
mode: adaptive
initialDelaySeconds: 60
missedCompletionPolicy: retry
stopAt: <today's local deadline as ISO-8601>
tickPrompt: <the prompt above>The first dashboard lands after about one minute. Each later tick passes /pr-status's numeric next-tick: recommendation as delaySeconds; the runtime clamps it to 60–3600 seconds.
with:
action: start
protocolVersion: 1
label: PRs
mode: fixed
initialDelaySeconds: <interval seconds>
intervalSeconds: <interval seconds>
missedCompletionPolicy: retry
stopAt: <today's local deadline as ISO-8601>
tickPrompt: <the prompt above>Fixed ticks ignore the dashboard's next-tick: value. The runtime owns the interval from each successful completion and reports any 60–3600-second clamp.
State the selected mode and local deadline before action: start, because a successful start ends the turn. Every tick must render the dashboard before watch_loop complete (action: complete). Protocol v1 also exposes model-facing watch_loop stop (action: stop); this watcher leaves ordinary deadline and manual stopping to the runtime and /watch-stop.
If watch_loop is unavailable, retain the existing Claude Code path below. Do not imitate a missing runtime tool. Both Claude modes start through the /loop skill; adaptive mode additionally needs ScheduleWakeup to pace itself. If /loop is unavailable, explain that recurring watches are unsupported and stop.
Session-model guard (adaptive mode only). Before starting the Claude adaptive path, state which model powers this session — your system prompt names it ("You are powered by …"). If it is any Fable model, do NOT start the adaptive loop: say why, point at the alternatives below, and end the turn without starting it. This is not a capability judgment you can pass by intending to render first — on wakeup turns Fable-class models emit their main output as the turn's final message after tool calls, and ScheduleWakeup ends the turn the instant it returns, mechanically discarding that message; every tick will be blank regardless of intent. Alternatives: run the watcher in a tab launched with claude --model sonnet (session-only, leaves the saved default alone), or use fixed mode (/watch-prs 10m), whose cron ticks carry no scheduling duty and work on any model. Sonnet- and Opus-class sessions pass this guard.
This skill selects Sonnet for coordination. Retain the adaptive guard as a fallback if the runtime uses another model; the hint alone is not proof of the effective model.
#### Adaptive mode (default)
ScheduleWakeup paces a loop runtime that already exists — it is the self-pacing primitive of a no-interval /loop, not a way to start one. Called standalone it still reports a scheduled wakeup, but the call is orphaned: no cron entry is written and no tick ever fires. So adaptive mode starts through /loop as well, with the interval omitted.
Do NOT run /pr-status in this turn, and do NOT call ScheduleWakeup yourself. Invoke the /loop skill with no interval and this prompt, substituting the stop hour:
/loop When already permitted, first run `~/.agents/skills/watch-telemetry/scripts/watch_telemetry.py record watch-prs claude tick` once; telemetry failure must not block the watch. Then invoke the pr-status skill and compose its full read-only dashboard without printing it yet. Do not execute suggested actions. Then call ScheduleWakeup once (delaySeconds = N from the dashboard's next-tick line, prompt = this message verbatim, noop = false), or ScheduleWakeup(stop: true) if that wake would land past {stop_hour}:00; after it returns, print the full dashboard — tables, changes, suggested actions, next-tick line — as the closing message of the turnEach tick is then a plain /pr-status run inside the loop the harness is already running. /pr-status closes with next-tick: {hot|warm|cold} (~{N}s) — {reason}; that N (hot ~180s / warm ~600s / cold 1200–1800s, 600 if the line is missing) is the next delay.
Schedule first, print last. Claude Code replaces text written before the final tool call with a one-line auto summary, so a dashboard printed before ScheduleWakeup never shows its tables; text after the call is shown in full. Sonnet and Opus sessions do this; Fable sessions are kept out of adaptive mode by the guard above because they drop text after the call.
#### Fixed mode (interval given)
Invoke the /loop skill with the literal interval; the next-tick: line is ignored:
/loop {interval} When already permitted, first run `~/.agents/skills/watch-telemetry/scripts/watch_telemetry.py record watch-prs claude tick` once; telemetry failure must not block the watch. Then invoke the pr-status skill and render its full read-only dashboard. Do not execute suggested actions.Tell the loop to stop at {stop_hour}:00 local time.
/pr-status is read-only and never prompts, so this loop runs unattended. Its suggested-action footer points at /ready-to-merge, /review-comments, etc. when normalized feedback is new or materially edited — you run those yourself; the watcher never acts. For an attended release gatekeeper, use /watch-release.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.