This runbook defines the maintainers' standard release flow.
Last verified: February 25, 2026.
- Keep releases predictable and repeatable.
- Publish only from code already in
main. - Verify multi-target artifacts before publish.
- Keep release cadence regular even with high PR volume.
- Patch/minor releases: weekly or bi-weekly.
- Emergency security fixes: out-of-band.
- Never wait for very large commit batches to accumulate.
Release automation lives in:
.github/workflows/pub-release.yml
Modes:
- Tag push
v*: publish mode. - Manual dispatch: verification-only or publish mode.
- Weekly schedule: verification-only mode.
- Pre-release tags (
vX.Y.Z-alpha.N,vX.Y.Z-beta.N,vX.Y.Z-rc.N): prerelease publish path. - Canary gate (weekly/manual): promote/hold/abort decision path.
Publish-mode guardrails:
- Tag must match stable format
vX.Y.Z(pre-release tags are handled byPub Pre-release). - Tag must already exist on origin.
- Tag must be annotated (lightweight tags are rejected).
- Tag commit must be reachable from
origin/main. - Publish trigger actor must be in
RELEASE_AUTHORIZED_ACTORSallowlist. - Optional tagger-email allowlist can be enforced via
RELEASE_AUTHORIZED_TAGGER_EMAILS. - Matching GHCR image tag (
ghcr.io/<owner>/<repo>:<tag>) must be available before GitHub Release publish completes. - Artifacts are verified before publish.
- Trigger provenance is recorded in
release-trigger-guard.jsonandaudit-event-release-trigger-guard.json. - Multi-arch artifact contract is enforced by
.github/release/release-artifact-contract.jsonthroughrelease_artifact_guard.py. - Release notes include a generated supply-chain evidence preface (
release-notes-supply-chain.md) plus GitHub-generated commit-window notes.
- Ensure required checks are green on latest
main. - Confirm no high-priority incidents or known regressions are open.
- Confirm installer and Docker workflows are healthy on recent
maincommits.
Run Pub Release manually:
publish_release:falserelease_ref:main
Expected outcome:
- Full target matrix builds successfully.
verify-artifactsenforces archive completeness against.github/release/release-artifact-contract.json.- No GitHub Release is published.
release-trigger-guardartifact is emitted with authorization/provenance evidence.release-artifact-guard-verifyartifact is emitted withrelease-artifact-guard.verify.json,release-artifact-guard.verify.md, andaudit-event-release-artifact-guard-verify.json.
From a clean local checkout synced to origin/main:
scripts/release/cut_release_tag.sh vX.Y.Z --pushThis script enforces:
- clean working tree
HEAD == origin/main- non-duplicate tag
- stable semver tag format (
vX.Y.Z)
After tag push, monitor:
Pub Releasepublish modePub Docker Imgpublish job
Expected publish outputs:
- release archives
SHA256SUMSCycloneDXandSPDXSBOMs- cosign signatures/certificates
- GitHub Release notes + assets
release-artifact-guard.publish.json+release-artifact-guard.publish.mdaudit-event-release-artifact-guard-publish.jsonproving publish-stage artifact contract completenesszeroclaw.sha256sums.intoto.json+audit-event-release-sha256sums-provenance.jsonfor checksum provenance linkagerelease-notes-supply-chain.md/release-notes-supply-chain.jsonwith release-asset references (manifest, SBOM, provenance, guard audit artifacts)- Docker publish evidence from
Pub Docker Img:ghcr-publish-contract.json+audit-event-ghcr-publish-contract.json+ghcr-vulnerability-gate.json+audit-event-ghcr-vulnerability-gate.json+ Trivy reports
- Verify GitHub Release assets are downloadable.
- Verify GHCR tags for the released version (
vX.Y.Z), release commit SHA tag (sha-<12>), andlatest. - Verify GHCR digest parity evidence confirms:
digest(vX.Y.Z) == digest(sha-<12>)digest(latest) == digest(vX.Y.Z)
- Verify GHCR vulnerability gate evidence (
ghcr-vulnerability-gate.json) reportsready=trueand thataudit-event-ghcr-vulnerability-gate.jsonis present. - Verify install paths that rely on release assets (for example bootstrap binary download).
Run CI Canary Gate (.github/workflows/ci-canary-gate.yml) in dry-run first, then execute when metrics are complete.
Required inputs:
- candidate tag/SHA
- observed error rate
- observed crash rate
- observed p95 latency
- observed sample size
Decision output:
promote: thresholds satisfiedhold: insufficient evidence or soft breachabort: hard threshold breach
Abort integration:
- In
executemode, if decision isabortandtrigger_rollback_on_abort=true, canary gate dispatchesCI Rollback Guardautomatically. - Default rollback branch is
dev(override withrollback_branch). - Optional explicit rollback target can be passed via
rollback_target_ref.
For staged release confidence:
- Cut and push stage tag (
vX.Y.Z-alpha.N, then beta, then rc). Pub Pre-releasevalidates:- stage progression
- stage matrix completeness (
alpha|beta|rc|stablepolicy coverage) - monotonic same-stage numbering
- origin/main ancestry
- Cargo version/tag alignment
- Guard artifacts publish transition audit evidence and stage history:
transition.type/transition.outcometransition.previous_highest_stageandtransition.required_previous_tagstage_history.per_stageandstage_history.latest_stage
- Publish prerelease assets only after guard passes.
If tag-push release fails after artifacts are validated:
- Fix workflow or packaging issue on
main. - Re-run manual
Pub Releasein publish mode with:publish_release=truerelease_tag=<existing tag>release_refis automatically pinned torelease_tagin publish mode
- Re-validate released assets.
If prerelease/canary lanes fail:
- Inspect guard artifacts (
prerelease-guard.json,canary-guard.json). - For prerelease failures, inspect
transition+stage_historyfields first to classify promotion, stage iteration, or demotion-blocked attempts. - Fix stage-policy or quality regressions.
- Re-run guard in
dry-runbefore any execute/publish action.
- Keep release changes small and reversible.
- Prefer one release issue/checklist per version so handoff is clear.
- Avoid publishing from ad-hoc feature branches.