ADR-007: Reviewed release inputs and verified distribution
Date: 2026-05-24 Status: Accepted original decision and merged SYN-340 amendment; SYN-343 amendment under review Author: Rômulo Febasi Amendment: 2026-10-17, SYN-340 (#343)
Original context and decision
The original decision separated three responsibilities: git-cliff generated
Conventional Commit notes, cargo-release coordinated version/tag changes, and
Axo dist was proposed for cross-platform packaging and installers. The intended
result was a readable changelog, consistent package/tag versions and downloadable
platform archives. The first workflow generated notes after a tag and committed
them back to main. The implementation now uses native Cargo build jobs rather
than an installed/configured Axo distribution pipeline. Neither dist nor
cargo-release is required by the checked-in release workflow.
The original promise of fully reproducible binaries exceeded the evidence: checksums and signatures authenticate selected bytes, but do not establish independent build reproducibility. This amendment narrows that claim.
Observed problems
At source baseline 21242ae, the workflow can package a tag’s old changelog,
then create a different changelog commit on main as github-actions[bot].
That source write bypasses review and the required author/committer identity.
Manual dispatch has no tag input and derives archive names from its branch.
The public mirror infers a tag from workflow_run.head_branch, which is not the
selected build tag for a manual run. Mirror retries delete the existing release
and tag before recreating them. The release job also lacks an exact platform
asset inventory check.
SYN-340 amendment
Prepare before tagging
Review the version, lockfile package version and generated CHANGELOG.md in
ordinary source control. Generate notes with the inspected, already installed
git-cliff 2.12.0 and the repository’s cliff.toml. Commit author and committer
are both Rômulo Febasi romulo@febasi.com.br. Automation creates no source commit,
changes no source branch and does not invent a human author for bot work.
For the current candidate, 73 commits after v1.4.0 add public capabilities such
as the bounded knowledge process contract, Memory CI and governed source/shared
state operations. No breaking commit marker was found, and git-cliff recommends
v1.5.0. This supports a minor candidate, subject to public-contract review and
exact-source CI. The user’s existing release-update authorization applies once
the actual review and validation gates pass; this preparation is not evidence
that tagging or publication occurred.
Stable 1.x command, MCP and frontmatter contracts retain Semantic Versioning;
a breaking change requires explicit review and a major version. The changelog
marks breaking Conventional Commits with BREAKING rather than hiding them.
Bind publication to reviewed inputs
A tag push or a manual dispatch with an explicit existing tag runs preflight.
Manual release dispatch must also select that tag as its workflow ref, rather
than main. Checking out a tag alone does not change the OIDC signing workflow
identity; preflight rejects a branch-based dispatch or a different tag ref.
The selected tag must resolve to checked-out HEAD. The committed Cargo manifest,
lockfile root package and first changelog section must match the tag. Preflight
extracts exactly that reviewed section and records the source commit plus input
and notes SHA-256 digests. Every native build checks out that exact commit and
uses cargo build --locked --release --features network_backends with defaults.
--all-features remains excluded because it enables the deterministic
test_backend, which must not ship as production inference.
The source job does not run git-cliff, rewrite notes or push main. Source CI,
MSRV and independent review must pass before the authorized release tag is created.
Tagging and publication remain separate from this preparation change.
flowchart TB R[Reviewed version and generated notes] --> C[Committed source] O[Authorized release after gates] -. tag or explicit dispatch .-> P[Preflight] C --> P P -->|commit and input receipt| B[Four native builds] B -->|platform archives| V[Exact inventory and checksums] P -->|source and notes receipt| V V --> S[Sigstore manifest signing] S --> G[Source release] G -->|unchanged authenticated assets| M[Public mirror] classDef source fill:#f2efff,stroke:#5B3EE0,color:#1A1A1A classDef artifact fill:#F6F4EF,stroke:#5F596B,color:#1A1A1A classDef evidence fill:#fff0d3,stroke:#FFB454,color:#1A1A1A class R,C,O,P source class B,G,M artifact class V,S evidence
The dotted edge is an owner’s control action. Solid edges carry source, receipts or artifacts. None represents proof of factual truth, universal supply-chain safety, detached process containment or independent build reproducibility.
Preserve actual platform limits
The matrix remains Linux x86_64 and ARM64 on Ubuntu 24.04, Apple Silicon macOS, and Windows x86_64 MSVC. ORT’s downloaded runtime requires modern glibc and libstdc++; these are GNU/Linux archives, not generic musl/Alpine binaries. Intel macOS remains unavailable because the selected ORT release candidate has no corresponding prebuilt. SYN-174 tracks restoration; this amendment adds no unsupported target and makes no macOS notarization or Windows signing claim.
Publication requires exactly those four nonempty archives and the release input
receipt. SHA256SUMS covers the archives and receipt. The existing keyless
Sigstore workflow identity signs that manifest. The receipt binds declared
source and notes to the manifest; it is not an independent SLSA build attestation.
Mirror without destructive replacement
Automatic mirroring reads release-metadata from the exact successful originating
workflow run, with explicit actions: read; it does not infer a tag from a branch.
Before selecting the tag, the receipt’s source commit must equal the authenticated
originating workflow_run.head_sha. Downloading an artifact by run ID alone does
not establish that commit binding.
Manual mirroring requires an explicit tag. Both compare downloaded source notes,
receipt, checksums and original tagged workflow signature before publication.
The public mirror preserves the original manifest and bundle; it does not re-sign
assets under a different identity.
The publishing process refuses an already existing release, including an identical rerun. API failures cannot establish release absence. There is no release/tag delete, force update or asset replacement path. This is a workflow policy, not permanent immutability: repository administrators can still change or delete GitHub objects. A failed partial publication requires owner inspection; a rerun does not silently erase it. The public mirror’s tag is a distribution reference, not a claim that its repository contains the private source commit.
Consequences and alternatives
The reviewed changelog, package versions, native archives and signed receipt share an explicit source boundary. Local dependency-free controls reject wrong tags/commits, dirty or inconsistent versions/notes, incomplete inventories, changed hashes and attempted replacement. These are validator controls, not proof that GitHub Actions permissions or all platform builds have executed.
Preparation and release now require a deliberate source review, replacing the old promise of zero manual steps. The four native builds and publishing services remain external prerequisites. Keeping post-tag bot writes or deleting existing releases on retry was rejected because both replace reviewed state implicitly. Using a new distribution tool is deferred: this amendment hardens the actual native Cargo pipeline without a tool installation or product MSRV change.
See release verification for exact signing identity, selected-archive checks and the separate best-effort installer limitations.
Platform archive layout
Unix packaging sets COPYFILE_DISABLE=1 for tar. macOS otherwise adds AppleDouble
entries for host provenance attributes, outside the declared binary/README/license/
changelog layout. The consumer keeps its exact-member policy. An independent
actual-shell test observes this environment setting, invokes the real local tar
and checks exact archive members and bytes. Representative ZIP fixtures preserve
Windows layout coverage; no local Windows 7z execution is claimed.
The metadata-free producer receipt keeps the actual shell regression, local normalized tar compatibility and platform-build limits separate.
SYN-343: Canonical documentation bytes before signing
The published Windows v1.5.0 archive contains a CRLF-converted full changelog. Converting its 1,317 CRLF sequences to LF reproduces the tagged Git blob exactly. The strict downstream npm workflow correctly stopped before publication because the archive bytes do not match the source receipt. Source and mirror publication success did not prove that inner documentation matched the receipt.
The forward repair packages
README.md, LICENSE and CHANGELOG.md from git cat-file blob HEAD:<document>.
A checkout’s line-ending conversion cannot redefine these selected bytes. Release
metadata retains schema version 1 and the same field set. Its input digests now
read exact committed blobs after the existing dirty-input check, so uncommitted
manifest, lockfile or changelog edits still fail preflight.
Before writing the signable checksum manifest, the source publishing job reads the full changelog in each of the four staged archives without extracting files. It requires one bounded regular member at the declared platform path and an exact SHA-256 match to the verified source receipt. Missing, duplicate, malformed or changed changelogs stop this job before Sigstore signing or release creation. This narrow producer check complements the downstream archive checks; it does not replace them or establish independent build reproducibility.
The repair targets a new v1.5.1 patch release. Existing v1.5.0 tags, assets, notes and manifests remain unchanged. The npm consumer remains strict. Local evidence uses an actual Git CRLF checkout, the actual packaging Bash stage and local tar, plus representative ZIP archives. Windows 7z execution and all four new hosted platform builds remain pending. See the bounded verification receipt.