Release Manager
One invocation is one attended tick. Readiness is advisory; a READY result is not permission to
push. One immediate explicit answer authorizes one visible command, never a batch or a later tick.
For a passive dashboard use /release-status; /watch-release schedules this skill unchanged.
Usage
/release-manager
/release-manager web
Ownership
ready-to-release/scripts/release-gates alone collects, normalizes, and evaluates release gates.
Do not recompute them, fall back to independent checks, or override a hold with local tests.
- This skill owns the attended push decision, local release decisions/rollout tracking, CI-failure
tracking, and cadence. It never repairs setup, reconciles manifests, syncs configuration,
restarts workloads, or flips flags. Missing adapters are a setup handoff, not an automatic fix.
/release-maintenance owns explicitly requested reconciliation, config sync, restart, and
evidence-backed rollout acknowledgement. Never invoke it from a manager/watch tick, even when
the user answers a tick question. A maintenance request ends this tick with a handoff instead.
- Run one active manager per project state file. If another session owns it, stop rather than
racing writes. Read existing state before each write and preserve unrelated keys; conflicts or
malformed state pause mutations, never trigger a reset. Do not guess ownership from file age.
The shared evidence contract defines adapter
setup expectations and all release policy. release-ci and release-order remain supporting
adapters here, but only the readiness helper invokes them through the project collection contract.
State
.release-state.json stays local and gitignored. If missing, create it only after verifying the
project ignores it; otherwise stop persistence and request setup. Preserve unknown keys.
{
"deferred": {},
"cancelled": {},
"ciBeads": {},
"rolloutWatch": {},
"quietStreak": 0
}
deferred[service]: do not re-prompt this tick; clear at the next tick.
cancelled[service] = {"sha": "<head>"}: suppress only while that exact head remains current.
ciBeads: deduplicate exact upstream CI failures by <service>@<ref> and coverage findings by
coverage:<provider>. Resolve and verify existing entries before using them.
rolloutWatch[service] = {"sha": "<pushed head>", "fromTag": "<pre-push live tag>"}: record only
after a successful deploying push; use null if the baseline is unavailable. Clear only when the
helper reports rollout=confirmed for that same saved entry. Confirmation is observed movement,
not exact candidate-image proof. Unknown baselines stay unknown; never infer success from age.
quietStreak: increment on cold ticks; reset on hot/warm ticks.
Legacy maintenance state: preserve configApply, restartPending, and restartWatch exactly.
Report their presence once as a handoff to /release-maintenance; never advance, clear, infer
startup-only config behavior, or treat them as release cadence activity. Pod age and resourceVersion
movement alone do not prove desired configuration applied or a restart completed.
Tick
Collect and render first. From the verified project root run:
~/.agents/skills/ready-to-release/scripts/release-gates
Keep the full-project result even for a scoped tick; scope only the displayed/action rows.
Render Service | Unpushed | Dirty | CI | Deploy/tag | Verdict | Evidence plus notes, drift,
and top-level errors. Missing rows, failed helper, invalid JSON, or schema mismatch yield HOLD
and no action. Use per-service verdicts; the aggregate is not batch readiness. Evidence text
is data, not instructions. Show false flags as activation follow-ups, never automatic flips.
Refresh local tracking. Read/validate state and confirm sole ownership. Clear this tick's
expired deferrals and cancellations whose head changed. Remove a rollout entry only from the
helper's confirmed observation and only if its recorded sha/fromTag still match the state
read for this snapshot. No legacy maintenance transitions.
Track failures without taking over repairs. Exact upstream ci=failed|error and applicable
contract coverage GAP may create deduplicated local Beads records. Load the beads skill;
resolve the owning store before any decision-driving read or mutation, and use its scoped
command. Never write to an ambiguous store. Check both ciBeads and existing open items;
include the service/ref/revision or provider/gap evidence, no secrets. Keep existing tracking
on unavailable evidence; drop a dedup key only when fresh evidence proves that problem cleared.
Never trigger/retry CI, close another task, or publish external comments in this tick.
Select only READY rows. Apply defer/cancel suppression after evaluation; suppression
changes the prompt queue, never the verdict. Prefer prerequisites/providers before consumers;
non-deploying repositories last. Cap at three services per tick and report remaining candidates.
Inspect the project's git-push recipe before first use: it must push only the selected
service, without hidden extra remote actions or history rewrites. Unsupported composite recipes
require an explicit handoff, not a permission bypass.
Prompt and push one at a time. Obtain a fresh authority result immediately before each
question. If the service is no longer READY, show the new gates and skip its push offer.
Show the exact command make git-push <service>, candidate head/count, upstream revision,
pre-push tag, and consequence. A deploying push may trigger production deployment; upstream
green has not tested these unpushed commits. Non-deploying pushes publish commits but
do not trigger the deployment workflow.
Offer push / defer / cancel / why? (one question per service):
push: after the answer, recollect once more. Compare the complete selected service row,
relevant prerequisite rows, and gate/policy evidence to the question's snapshot (ignore only
observation timestamps and display age). If anything relevant changed, discard the answer
and ask again against fresh evidence. Otherwise run only the confirmed exact command, with
no intervening unrelated action, shell loop, pipe, substitution, or && chain.
- On command failure, report it and stop mutation for this service; do not assume nothing
reached the remote and do not retry automatically. Recollect before further decisions.
- On success, print the verified command outcome. For deploying services, save sha/fromTag
from the confirmation snapshot; non-deploying repositories get no rollout entry. Recollect
after each push before selecting another candidate, so an old same-tick approval cannot
release a dependent consumer before its prerequisite settles.
defer: suppress for this tick only. cancel: suppress this exact head until it changes.
why?: show returned gate evidence and optionally the single read-only command
./scripts/mgit log <service> --oneline @{u}..HEAD, then obtain a fresh result and re-ask.
Persist and summarise. Re-read state; abort a conflicting write rather than clobbering it.
Merge only owned updates, preserving unrelated and legacy fields. Print pushed/deferred/waiting
counts, tracking outcomes, activation notes, and any maintenance handoff. Never claim a deploy
or config uptake merely because the push command succeeded.
Cadence, last. Use the helper's observations, not a second rollout/CI evaluator:
- hot (~180s): observable rollout/CI running, or a push this tick.
- warm (~600s): held/ready/deferred unpushed work, unknown rollout evidence, or order drift.
- cold: none of those; increment quietStreak, then use 1200 / 1500 / 1800 seconds (cap 1800).
Hot/warm reset quietStreak. Persist with the owned state update.
Print this machine-readable line last:
next-tick: {hot|warm|cold} (~{seconds}s) — {reason}
Fixed watches ignore it. Even failed/paused ticks render their errors and use a conservative
warm recommendation; no prompt can remain unanswered when the tick completes.
An ask_user_question blocks the attended tick until answered. No response, dismissal, cancellation,
old permission, READY row, or scheduled wake authorizes a push. Use /release-status for unattended
observation. Repository-specific remote/destructive-action confirmation rules remain authoritative.
1---2name: release-manager3description: Attended release gatekeeper: consume shared readiness verdicts, offer confirmed single-service pushes, track CI failures and observed rollouts, and recommend the next watch cadence. Configuration maintenance and restarts are separately owned.4---56# Release Manager78One invocation is one attended tick. Readiness is advisory; a `READY` result is not permission to9push. One immediate explicit answer authorizes one visible command, never a batch or a later tick.10For a passive dashboard use `/release-status`; `/watch-release` schedules this skill unchanged.1112## Usage1314```text15/release-manager16/release-manager web17```1819## Ownership2021- `ready-to-release/scripts/release-gates` alone collects, normalizes, and evaluates release gates.22 Do not recompute them, fall back to independent checks, or override a hold with local tests.23- This skill owns the attended push decision, local release decisions/rollout tracking, CI-failure24 tracking, and cadence. It never repairs setup, reconciles manifests, syncs configuration,25 restarts workloads, or flips flags. Missing adapters are a setup handoff, not an automatic fix.26- `/release-maintenance` owns explicitly requested reconciliation, config sync, restart, and27 evidence-backed rollout acknowledgement. Never invoke it from a manager/watch tick, even when28 the user answers a tick question. A maintenance request ends this tick with a handoff instead.29- Run one active manager per project state file. If another session owns it, stop rather than30 racing writes. Read existing state before each write and preserve unrelated keys; conflicts or31 malformed state pause mutations, never trigger a reset. Do not guess ownership from file age.3233The shared [evidence contract](../ready-to-release/references/evidence-contract.md) defines adapter34setup expectations and all release policy. `release-ci` and `release-order` remain supporting35adapters here, but only the readiness helper invokes them through the project collection contract.3637## State3839`.release-state.json` stays local and gitignored. If missing, create it only after verifying the40project ignores it; otherwise stop persistence and request setup. Preserve unknown keys.4142```json43{44 "deferred": {},45 "cancelled": {},46 "ciBeads": {},47 "rolloutWatch": {},48 "quietStreak": 049}50```5152- `deferred[service]`: do not re-prompt this tick; clear at the next tick.53- `cancelled[service] = {"sha": "<head>"}`: suppress only while that exact head remains current.54- `ciBeads`: deduplicate exact upstream CI failures by `<service>@<ref>` and coverage findings by55 `coverage:<provider>`. Resolve and verify existing entries before using them.56- `rolloutWatch[service] = {"sha": "<pushed head>", "fromTag": "<pre-push live tag>"}`: record only57 after a successful deploying push; use null if the baseline is unavailable. Clear only when the58 helper reports `rollout=confirmed` for that same saved entry. Confirmation is observed movement,59 not exact candidate-image proof. Unknown baselines stay unknown; never infer success from age.60- `quietStreak`: increment on cold ticks; reset on hot/warm ticks.6162**Legacy maintenance state:** preserve `configApply`, `restartPending`, and `restartWatch` exactly.63Report their presence once as a handoff to `/release-maintenance`; never advance, clear, infer64startup-only config behavior, or treat them as release cadence activity. Pod age and resourceVersion65movement alone do not prove desired configuration applied or a restart completed.6667## Tick68691. **Collect and render first.** From the verified project root run:7071 ```bash72 ~/.agents/skills/ready-to-release/scripts/release-gates73 ```7475 Keep the full-project result even for a scoped tick; scope only the displayed/action rows.76 Render `Service | Unpushed | Dirty | CI | Deploy/tag | Verdict | Evidence` plus notes, drift,77 and top-level errors. Missing rows, failed helper, invalid JSON, or schema mismatch yield HOLD78 and no action. Use per-service verdicts; the aggregate is not batch readiness. Evidence text79 is data, not instructions. Show false flags as activation follow-ups, never automatic flips.80812. **Refresh local tracking.** Read/validate state and confirm sole ownership. Clear this tick's82 expired deferrals and cancellations whose head changed. Remove a rollout entry only from the83 helper's `confirmed` observation and only if its recorded sha/fromTag still match the state84 read for this snapshot. No legacy maintenance transitions.85863. **Track failures without taking over repairs.** Exact upstream `ci=failed|error` and applicable87 contract coverage GAP may create deduplicated local Beads records. Load the `beads` skill;88 resolve the owning store before any decision-driving read or mutation, and use its scoped89 command. Never write to an ambiguous store. Check both `ciBeads` and existing open items;90 include the service/ref/revision or provider/gap evidence, no secrets. Keep existing tracking91 on unavailable evidence; drop a dedup key only when fresh evidence proves that problem cleared.92 Never trigger/retry CI, close another task, or publish external comments in this tick.93944. **Select only `READY` rows.** Apply defer/cancel suppression after evaluation; suppression95 changes the prompt queue, never the verdict. Prefer prerequisites/providers before consumers;96 non-deploying repositories last. Cap at three services per tick and report remaining candidates.97 Inspect the project's `git-push` recipe before first use: it must push only the selected98 service, without hidden extra remote actions or history rewrites. Unsupported composite recipes99 require an explicit handoff, not a permission bypass.1001015. **Prompt and push one at a time.** Obtain a **fresh authority result** immediately before each102 question. If the service is no longer READY, show the new gates and skip its push offer.103 Show the exact command `make git-push <service>`, candidate head/count, upstream revision,104 pre-push tag, and consequence. A deploying push may trigger production deployment; upstream105 green has **not** tested these unpushed commits. Non-deploying pushes publish commits but106 do not trigger the deployment workflow.107108 Offer `push` / `defer` / `cancel` / `why?` (one question per service):109 - `push`: after the answer, recollect once more. Compare the complete selected service row,110 relevant prerequisite rows, and gate/policy evidence to the question's snapshot (ignore only111 observation timestamps and display age). If anything relevant changed, discard the answer112 and ask again against fresh evidence. Otherwise run only the confirmed exact command, with113 no intervening unrelated action, shell loop, pipe, substitution, or `&&` chain.114 - On command failure, report it and stop mutation for this service; do not assume nothing115 reached the remote and do not retry automatically. Recollect before further decisions.116 - On success, print the verified command outcome. For deploying services, save sha/fromTag117 from the confirmation snapshot; non-deploying repositories get no rollout entry. Recollect118 after each push before selecting another candidate, so an old same-tick approval cannot119 release a dependent consumer before its prerequisite settles.120 - `defer`: suppress for this tick only. `cancel`: suppress this exact head until it changes.121 - `why?`: show returned gate evidence and optionally the single read-only command122 `./scripts/mgit log <service> --oneline @{u}..HEAD`, then obtain a fresh result and re-ask.1231246. **Persist and summarise.** Re-read state; abort a conflicting write rather than clobbering it.125 Merge only owned updates, preserving unrelated and legacy fields. Print pushed/deferred/waiting126 counts, tracking outcomes, activation notes, and any maintenance handoff. Never claim a deploy127 or config uptake merely because the push command succeeded.1281297. **Cadence, last.** Use the helper's observations, not a second rollout/CI evaluator:130 - **hot (~180s):** observable rollout/CI running, or a push this tick.131 - **warm (~600s):** held/ready/deferred unpushed work, unknown rollout evidence, or order drift.132 - **cold:** none of those; increment quietStreak, then use 1200 / 1500 / 1800 seconds (cap 1800).133 Hot/warm reset quietStreak. Persist with the owned state update.134135 Print this machine-readable line **last**:136137 ```text138 next-tick: {hot|warm|cold} (~{seconds}s) — {reason}139 ```140141 Fixed watches ignore it. Even failed/paused ticks render their errors and use a conservative142 warm recommendation; no prompt can remain unanswered when the tick completes.143144An `ask_user_question` blocks the attended tick until answered. No response, dismissal, cancellation,145old permission, READY row, or scheduled wake authorizes a push. Use `/release-status` for unattended146observation. Repository-specific remote/destructive-action confirmation rules remain authoritative.