Release Process¶
ZapTrace uses PEP 440 package versions, Cargo-compatible SemVer mappings, and v<package-version> release tags. The active development identity and synchronization rules are defined in Version Policy.
Release checklist¶
- Create a repository-owned branch named exactly
release/v<version>, updateCHANGELOG.mdwith a human-readable summary, and move the target release out of[Unreleased]. - Change
pyproject.tomlto the intended RC/final version and synchronize the Cargo/lockfile forms. - Run the strict
release-preparationversion-consistency check plus the required Quality and Security workflows on the release PR. Ordinary pull requests continue to use the stricter development-only context. - Confirm direct Rust tests, pinned Cargo advisory evidence, installed-wheel native boundary evidence, and all distribution clean-install evidence are green.
- Squash-merge the fully green release PR, then create an annotated
v<package-version>tag pointing to the resulting exactmaincommit. The merge push may use the same boundedrelease-preparationcontext for that final identity; the tagged-release workflow then re-runs release identity and artifact gates on the commit. Scheduled/manual main validation remains development-only until the mandatory post-release bump. Cryptographic signing is optional until a reviewed trust-root policy is configured. - Push the
v*tag to trigger.github/workflows/release.yml. - Verify version evidence, release artifacts, SBOM, checksums, provenance/attestation, Cargo advisory, and per-target native boundary steps complete.
- Review generated GitHub release notes before public announcement.
- Open and merge the post-release development bump to the next patch
.dev0line before unrelated development continues.
Post-release development bump¶
The post-release development bump is mandatory. After publishing v0.3.1, main advances to Python 0.3.2.dev0 and Cargo 0.3.2-dev.0; it must not continue presenting the final 0.3.1 identity. The Quality workflow rejects a final version on the development branch and rejects a development line whose corresponding final tag already exists.
Future release tags must be annotated and resolve to the exact checked-out commit. The historical v0.3.0 lightweight tag is grandfathered and remains historical evidence only. Cryptographic tag verification is not currently required; reports state this explicitly and do not claim a verified signature.
Evidence modes¶
Release-critical reports use one shared identity schema.
snapshotevidence is produced for pull requests, branch pushes, schedules, and local validation. It records the exact commit/ref, dirty state, package version, lock hash, source-input hash, generation time, and toolchain, but cannot be represented as a tagged release.releaseevidence is accepted only forrefs/tags/v<package-version>. A dirty tree is rejected unless a non-empty policy override identifier is recorded in the evidence.- The deterministic identity hash includes all identity fields except
generated_at, so repeated generation times do not change the identity while source, lock, ref, mode, or toolchain changes do.
The Quality workflow uploads snapshot-gate-summary.json. The tag workflow uploads tagged-release-evidence.json and includes it in the GitHub Release assets and checksum manifest.
Native-wheel verification¶
Each supported Rust wheel target has a fail-closed sequence:
- build the target wheel;
- create a clean target-compatible virtual environment;
- install the exact
dist/*.whlartifact; - run
scripts/ci_native_boundary.pywithZAPTRACE_REQUIRE_NATIVE=1; - upload
native-boundary-<target>.jsonand Markdown evidence; - upload the wheel only after verification succeeds.
The verifier rejects dirty source and source-tree extensions while a wheel is being claimed, records the wheel SHA-256 and actual extension path, and checks deterministic valid calls, controlled invalid-input exceptions, pre-extraction resource limits, extreme-finite overflow rejection, and same-process survival. See Native Rust and PyO3 Boundary.
Release workflow¶
The release workflow:
- checks that the tag matches the package version;
- creates identity-bound tagged release evidence and rejects dirty or mismatched source context;
- runs Python and Rust quality gates;
- requires direct Rust tests and installed-wheel PyO3 boundary evidence;
- builds the supported source distribution and native-wheel targets from the distribution support matrix;
- clean-installs each claimed artifact and exercises CLI, SDK, REST API, MCP HTTP, and native-extension expectations;
- downloads every
distribution-smoke-*report before release aggregation; - generates an SPDX SBOM;
- attests release artifacts;
- creates a GitHub Release.
The Security workflow also publishes raw and normalized Cargo advisory evidence using a pinned cargo-audit version. A clean advisory report is evidence about the exact lockfile, not proof that the native extension is vulnerability-free.
Publishing policy¶
Automatic PyPI/GHCR publishing is intentionally disabled until package naming, credential policy, and registry ownership are settled. GitHub Releases is the authoritative current artifact channel; see the distribution support matrix. Do not add publishing credentials without a separate reviewed issue and threat model.
Non-claims¶
A release does not certify that generated boards are fabrication-ready, manufacturer-approved, production-ready, formally verified, or safe without human review. Successful Rust/PyO3 tests do not establish immunity from denial-of-service or platform-specific native defects.
Debug symbols¶
Native debug symbols and linker outputs are never tracked in the source tree and are never included in wheels or source distributions. When a release needs debugging support, maintainers produce symbols from the same reviewed release build, bind them to the release commit and binary checksums, and upload them as a separate release artifact with restricted retention or access appropriate to the incident. Publishing symbols does not change or replace the verified package artifacts.
Container security gate¶
Before a GitHub Release is created, the release workflow builds the exact
Docker image for the tag and calls the reusable Container Security gate. The
release is blocked by Critical findings immediately and by unexcepted High
findings after the documented baseline date. The retained evidence includes the image digest, CycloneDX SBOM, Trivy
JSON/SARIF, policy summary, dependency-lock consistency report, embedded build
provenance, and exact-image provenance verification. The provenance binds the
release source commit, pinned base digest, locally built wheel digest, and
committed Python/Alpine dependency-manifest digests; see
docs/security/container-vulnerability-management.md.