watch-release — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited watch-release (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.
Start a /release-manager loop that runs until 18:00 local time, pacing itself adaptively: checking again soon (~3 min) while a push is mid-rollout or CI is running, and backing off (10 → 30 min) once everything is settled. Intended for a dedicated kitty tab during parallel work — it keeps an eye on git/CI/deploy state and prompts you when something is ready to ship, without burning a tick every 10 minutes when nothing is happening.
/watch-release # adaptive cadence, stop at 18:00 (default)
/watch-release 17 # adaptive, stop at 17:00
/watch-release 10m # FIXED 10-minute interval, stop at 18:00
/watch-release 5m 17 # fixed 5m, stop at 17:00Adaptive is the default. Pass an explicit \d+m interval only when you deliberately want a fixed cadence (e.g. demoing, or a tab you glance at on a known rhythm).
Only 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-release {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 optional arguments:
\d+m. Absent → adaptive mode (thedefault). Present → fixed-interval mode at that interval.
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, tell the user 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-release pi tick` once; telemetry failure must not block the watch. Then Load and follow the skill named `release-manager` now. This is one attended release tick. Invoke the skill rather than improvising its steps, render its full dashboard and every confirmation as visible text, and wait for each answer. Never push without the explicit answer to that action's current question in this tick and release-manager's fresh shared-authority recheck. Never invoke release-maintenance, reconcile manifests, sync config, or restart workloads in a watch tick; an answer cannot expand this boundary. A release question (the native `publish_commit` dialog, or `ask_user_question`) blocks the active tick until the user answers; do not call `watch_loop` complete while a question is open. After release-manager has finished all answered prompts and printed its final `next-tick:` line, call the matching `watch_loop` action: complete with outcome: continue. In adaptive mode pass that line's numeric N as delaySeconds; if the line is missing or malformed, use 600. In fixed mode omit delaySeconds. Do not complete before the dashboard, answers, tick summary, and cadence recommendation are visible.minute. Then make the terminating start call:
action: start
protocolVersion: 1
label: Releases
mode: adaptive
initialDelaySeconds: 60
missedCompletionPolicy: pause
stopAt: <today's local deadline as ISO-8601>
tickPrompt: <the prompt above>Each successful tick passes /release-manager's numeric next-tick: recommendation as delaySeconds; the runtime clamps it to 60–3600 seconds. Hot/warm/cold remain approximately 180/600/1200–1800 seconds. A missing or malformed recommendation uses the explicit 600-second fallback.
terminating start call:
action: start
protocolVersion: 1
label: Releases
mode: fixed
initialDelaySeconds: <interval seconds>
intervalSeconds: <interval seconds>
missedCompletionPolicy: pause
stopAt: <today's local deadline as ISO-8601>
tickPrompt: <the prompt above>Fixed ticks ignore next-tick: and let the runtime enforce the requested cadence from each successful completion.
A successful start ends the initiating turn. A release question blocks the active tick until the user answers, and only the later matching action: complete schedules another tick. The pause policy prevents an unanswered, interrupted, or malformed attended tick from retrying by itself. Protocol v1 also exposes model-facing action: stop; ordinary deadline and manual stopping belong to the runtime and /watch-stop.
If watch_loop is unavailable, retain the existing Claude Code paths below.
#### Adaptive mode (no interval given)
Invoke the /loop skill in dynamic (self-paced) mode. The loop prompt is the only text re-injected verbatim on every wakeup — release-manager's SKILL.md is NOT re-read on wakeup turns unless the tick explicitly loads it — so the output contract and ordering must live inside the prompt string itself:
/loop When already permitted, first run `~/.agents/skills/watch-telemetry/scripts/watch_telemetry.py record watch-release claude tick` once; telemetry failure must not block the watch. Then run /release-manager — each tick: invoke the release-manager skill via the Skill tool (never improvise its steps from memory), render its full dashboard and any prompts as visible text; only offer pushes using its fresh shared-authority verdict and current-command confirmation; never invoke release-maintenance, reconcile manifests, sync config, or restart workloads; only THEN call ScheduleWakeup as the very last action of the turn; the turn ends the instant ScheduleWakeup returns, so a tick that schedules before rendering shows the user nothing and has failedPass that whole string as the loop prompt, and echo it back unchanged in every ScheduleWakeup call so later ticks keep the contract. Each tick must render first and call ScheduleWakeup as its final action — text intended after that call is silently dropped.
Then pace each next wake from the recommendation /release-manager prints last in its tick output:
next-tick: {hot|warm|cold} (~{N}s) — {reason}Use {N} as the delaySeconds for the next wake (the dynamic loop clamps to [60, 3600]). Don't second-guess the bucket — /release-manager already weighs the authority's rollout/CI observations and its prompt queue:
quietStreak counter.Stop and don't reschedule once the wake would land past {stop_hour}:00. If a tick produces no next-tick: line (e.g. it errored before the cadence recommendation), fall back to ~600s and continue.
#### Fixed mode (interval given)
Invoke the /loop skill with the literal interval — /release-manager's next-tick: line is ignored. The same per-tick contract applies (minus the ScheduleWakeup ordering — cron fires fixed ticks):
/loop {interval} When already permitted, first run `~/.agents/skills/watch-telemetry/scripts/watch_telemetry.py record watch-release claude tick` once; telemetry failure must not block the watch. Then run /release-manager — each tick: invoke the release-manager skill via the Skill tool and render its full dashboard as visible text; only offer pushes using its fresh shared-authority verdict and current-command confirmation; never invoke release-maintenance, reconcile manifests, sync config, or restart workloads; a tick that only runs scripts is a failed tickTell the loop to stop at {stop_hour}:00 local time. If neither watch_loop nor the required Claude scheduling capability is available, explain that recurring watches are unsupported and stop.
Some harnesses close an idle question on their own. Claude Code does so only when askUserQuestionTimeout is set (60s, 5m, 10m; default never) and the terminal window is unfocused, the normal state of a dedicated watch tab, returning No response after 60s — the user may be away from keyboard. Pi asks through the native publish_commit dialog (push / defer / cancel / why?), which has no timeout and waits; Esc dismisses it. Either way /release-manager treats anything but an explicit current answer as unanswered: it defers the service, stops re-offering that exact head on later ticks, keeps observing, and never pushes. To release such a service, reply push <service> in the watch tab; the manager rechecks the gates first and asks that service's question again, which in Pi is the same native dialog. Keep or change the timeout as you prefer; the loop stays safe at any value.
In Pi, a tick whose model turn fails (for example a dropped provider connection) settles without watch_loop complete, and the pause policy pauses the watch. /watch-status shows the paused state; /watch-resume runs one immediate tick. A resume pushes nothing by itself.
Readiness belongs to ready-to-release/scripts/release-gates, consumed by /release-manager. Do not recompute gates in the scheduler. Configuration sync, manifest reconciliation, and restarts belong to separately invoked /release-maintenance, never this loop, even after a tick answer.
/release-manager prompts (push / defer / cancel) and blocks each tick until you answer, so this loop is meant to run attended in a visible tab. The adaptive interval is time measured after a tick completes (including after you answer a prompt) — so a hot 3-minute cadence only kicks in once you've cleared the prompt. For an unattended, never-blocking view, loop /release-status instead (/loop 10m /release-status) and act on its recommendations manually.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.