Why
The v0.1.3 release was driven end-to-end by an AI agent. It worked, but the agent had to rediscover process knowledge that should have been written down: which gates duplicate CI, which hooks fail silently, what order minimizes serial CI waits, and which failure modes recur (this is the third release train with the same classes of surprise). A release runbook written for agents — imperative, verifiable, with explicit checkpoints — would make the next release a 20-minute supervised run instead of an hour of discovery.
Deliverable
docs/releases/AGENT_RUNBOOK.md (and/or a .claude/skills/release/SKILL.md so Claude Code picks it up automatically). Content:
1. The happy path (post-#260 tooling)
- Preconditions checklist: clean worktree, on
main, CI green on HEAD, gh auth status OK, maintainer identity present (auths whoami)
- One-shot:
just release X.Y.Z = 0_versions.py --set → uv lock ×2 → cargo update → gen-error-docs → commit → auths sign HEAD → tag → single --no-verify push of commit+tag
- Fan-out watch list: release.yml (binaries+brew), publish-crates (idempotent, safe to re-run), publish-python, publish-node, publish-typescript, publish-fastapi, release-go
- Post-release: install matrix (brew/curl/cargo/pip/npm), bump
auths-version pins in release.yml + verify-commits.yml (AFTER the release exists — verify installs a released binary), action repos (auths-dev/sign, auths-dev/verify) bump + re-float v1
2. Verification discipline (agents must not trust exit codes)
- Check every commit landed:
git log -1 after each commit — local hooks have failed silently on three separate trains (prek stash conflicts, exit codes masked by pipes)
- Pipe-masking rule: never
git commit ... | tail — redirect to a file and check $? directly
- After tagging:
git ls-remote --tags origin | grep vX.Y.Z must show the tag at the release SHA
- Commits to main MUST carry Auths trailers (verify-commits.yml is KEL-native and gates release.yml):
auths sign anything that bypassed the prepare-commit-msg hook
3. Wall-clock optimization (lessons from the 0.1.3 train, see #260)
- Local pre-push gate duplicates CI and contains stages that cannot pass locally (Windows ml64.exe cross-check) — release pushes use
--no-verify; CI on the release commit is the authority
- Fold the version bump into the release commit — never bump in a separate post-merge commit (saves a full CI cycle, ~20 min)
- Tag immediately after the release commit's CI is green, not after manual re-verification
- Run independent verifications in parallel (install matrix entries don't depend on each other)
- The ONE shortcut never to take: tagging before CI is green on the release commit — publish-crates is irreversible
4. Known failure modes and remedies (keep this list growing)
- prek 'Stashed changes conflicted' →
git add -A so nothing is left to stash, retry
- 'files were modified by this hook' → lockfile churn; re-stage, retry
uv sync --locked failure in FastAPI CI → uv lock wasn't run after version stamp (now in just release)
- packages/* compile breakage surfacing at release time → the package gates only run on PRs/main; long-lived branches need a draft PR
- HOMEBREW_TAP_TOKEN expiry → manual formula push to auths-dev/homebrew-auths-cli with gh credentials
- publish-crates partial failure → idempotent, re-run the workflow
- Touch ID / Secretive prompts block non-interactive signing → surface to the human, retry once approved
5. Agent-specific guidance
- Background long waits (CI, fan-out) with watchers instead of polling
- Report progress at each phase boundary with the SHA and what gate it passed
- File issues for every recurring friction discovered during the train (this issue exists because of that rule)
Acceptance
Why
The v0.1.3 release was driven end-to-end by an AI agent. It worked, but the agent had to rediscover process knowledge that should have been written down: which gates duplicate CI, which hooks fail silently, what order minimizes serial CI waits, and which failure modes recur (this is the third release train with the same classes of surprise). A release runbook written for agents — imperative, verifiable, with explicit checkpoints — would make the next release a 20-minute supervised run instead of an hour of discovery.
Deliverable
docs/releases/AGENT_RUNBOOK.md(and/or a.claude/skills/release/SKILL.mdso Claude Code picks it up automatically). Content:1. The happy path (post-#260 tooling)
main, CI green on HEAD,gh auth statusOK, maintainer identity present (auths whoami)just release X.Y.Z=0_versions.py --set→uv lock×2 →cargo update→gen-error-docs→ commit →auths sign HEAD→ tag → single--no-verifypush of commit+tagauths-versionpins in release.yml + verify-commits.yml (AFTER the release exists — verify installs a released binary), action repos (auths-dev/sign, auths-dev/verify) bump + re-float v12. Verification discipline (agents must not trust exit codes)
git log -1after each commit — local hooks have failed silently on three separate trains (prek stash conflicts, exit codes masked by pipes)git commit ... | tail— redirect to a file and check$?directlygit ls-remote --tags origin | grep vX.Y.Zmust show the tag at the release SHAauths signanything that bypassed the prepare-commit-msg hook3. Wall-clock optimization (lessons from the 0.1.3 train, see #260)
--no-verify; CI on the release commit is the authority4. Known failure modes and remedies (keep this list growing)
git add -Aso nothing is left to stash, retryuv sync --lockedfailure in FastAPI CI →uv lockwasn't run after version stamp (now injust release)5. Agent-specific guidance
Acceptance
just release X.Y.Z+ node-sdk PR CI gate #260 (one-shot tooling)