# Release candidates This is a contributor and release-engineering procedure, not an end-user setup path. Publication is a three-stage transaction: 1. `candidate` builds immutable archives and a manifest with paths relative to the manifest directory. 2. `live-test` downloads that exact candidate in a clean job, deploys it, and records the full named production-shaped acceptance result plus deployment, runtime configuration, and proxy configuration identities. 3. `final` downloads the candidate and evidence in another clean job, verifies every binding, and publishes without rebuilding any binary. Set `CLUSTERFLUX_RELEASE_STAGE=candidate` while creating the candidate and `CLUSTERFLUX_RELEASE_STAGE=final` while finalizing it. The final stage requires `CLUSTERFLUX_RELEASE_CANDIDATE_MANIFEST` and complete live evidence. There is no incomplete-evidence publication override. The `clusterflux-release` runner must provide `CLUSTERFLUX_DEPLOY_COMMAND` as a protected secret. The command runs locally with `CLUSTERFLUX_CANDIDATE_ARCHIVE`, `CLUSTERFLUX_CANDIDATE_COORDINATOR`, and their SHA-256 identities exported. It must deploy that executable and restart the configured service. `scripts/deploy-release-candidate.sh` then independently compares the running `/proc//exe` digest with the candidate and records the service and proxy unit identities; a mismatch stops the release. Clusterflux release binaries are built once. The public client/node archive and the private-source hosted-service archive are both digest-bound to the same candidate. The hosted archive is deployed, the strict production-shaped batch uses the public archive against it, and finalization copies both archives without rebuilding. Create the candidate in a dedicated directory: ~~~bash CLUSTERFLUX_PUBLIC_RELEASE_DIR=target/release-candidate \ CLUSTERFLUX_RELEASE_STAGE=candidate \ ./scripts/prepare-public-release.js ~~~ Deploy `target/release-candidate/assets/clusterflux-public-binaries-*.tar.gz`. Set `CLUSTERFLUX_PUBLIC_RELEASE_MANIFEST` to the candidate manifest while running the strict batch. Set `CLUSTERFLUX_QUALITY_GATE_EVIDENCE_PATH` to the JSON record from the private and public acceptance commands. The result records the source commit, source-tree and public-tree identities, candidate binary digests, deployment generation, and configuration identity. Finalize into a different directory after the strict result passes: ~~~bash CLUSTERFLUX_PUBLIC_RELEASE_DIR=target/public-release \ CLUSTERFLUX_RELEASE_CANDIDATE_MANIFEST=target/release-candidate/public-release-manifest.json \ CLUSTERFLUX_FINAL_RESULT_PATH=target/acceptance/cli-happy-path-live.json \ ./scripts/prepare-public-release.js ~~~ Finalization rejects a changed commit, source tree, public tree, candidate archive, binary digest set, deployment binding, or strict result. It never runs the release binary build when a candidate manifest is supplied.