Skip to content

Write an agent-facing release runbook (docs/releases/AGENT_RUNBOOK.md): every step, every gotcha, optimized for wall-clock #261

@bordumb

Description

@bordumb

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 --setuv lock ×2 → cargo updategen-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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions