CAP never authorizes. Building an archive is verification evidence, never authority to publish.
The release-candidate boundary is governed by docs/adr/conformance-release-candidate.md; this runbook is the operator sequence for cutting a package release.
1. Gates green
mix qualityThe complete gate must pass on the pinned toolchain: audits, formatting, warnings-as-errors compile, strict credo, the full suite at its coverage threshold, certified-conformance verification and regeneration identity, all named source mutations, Elixir/TypeScript verifier agreement over the repository and unpacked-package corpora, dialyzer, docs, and the release-candidate archive checks.
2. Record identities
After any corpus, registry, spec, or package-boundary byte change:
mix run --no-start scripts/record_conformance_index.exs # full-corpus index
mix run --no-start scripts/render_requirements.exs # requirements matrix
mix run --no-start scripts/record_release_metadata.exs # four identities + archive pinpriv/release-metadata.json carries corpus_digest,
index_sha256_base64url, registry_digest, spec_digest, and
verifier_runtime. The release pin lives in .release-archive.sha256: the
package CONTENT identity — the SHA-256 over the unpacked archive's sorted
path+bytes, excluding the order-generated hex_metadata.config. The
release-candidate gate rebuilds the archive twice, requires the builds to be
byte-identical within the run, and requires the unpacked content identity to
equal the pin (the tarball bytes themselves are not reproducible across
operating systems, so the pin is defined over content, which is).
3. Version and records
@versioninmix.exsmatches the CHANGELOG's unreleased entry.CHANGELOG.mddescribes every public change.spec/changelog.mdrecords spec-set changes; semantic wire changes name theirprotocol_revision(seespec/evolution.mdand the ADRs).
4. Tag and build
git tag vX.Y.Z
mix hex.buildmix quality (step 1) already verified the content pin against this exact
tree; the gate's success line prints both the content identity and the local
archive byte digest. Record the archive byte digest from the release
platform in the release record — it is informational; the pin that CI
re-verifies is the content identity.
5. Publish (separate authority)
mix hex.publish is never aliased or automated. Publishing requires explicit
operator authority for THIS release; the approval covers the named version
and archive digest, nothing more.
6. Post-publish verification
From a clean directory, add the package as a dependency, then:
mix run -e 'System.halt(CharterAgreementProtocol.Conformance.Cli.run(["--corpus", "deps/charter_agreement_protocol/priv/conformance"]))'A process exit status of 0 proves the published corpus recomputes and agrees
with the certified identity (System.halt/1 propagates the CLI's returned
status — a bare mix run -e drops it). Record the published hex checksum beside the
release tag and close the CHANGELOG entry.