ADR-0090: Release & Versioning Policy — Deliberate Releases, One Auditor-Facing Number¶
- Status: accepted (Nicolas 2026-07-22, train session — V1 "semver sounds good … start at 0.8", V2 "totally agree", V3 "agree", plus the wire-breaking allowance below)
- Date: 2026-07-22
- Deciders: Nicolas Burri, design by Claude. Origin: his versioning question — "I wonder if an auditor does understand that [the requirements baseline + git hash] is also a great marker for a software version … auditors have a hard time understanding software."
- Relates to: ADR-0061 (the validation report this policy feeds), ADR-0062 (the tag-gated SBOM job — the ritual's existing half), ADR-0060 (the canonical backup a release references), the requirements baseline process (docs/requirements/README.md).
Context¶
The identity triple (requirements-baseline tag, git sha, image digest) is precise and engineer-friendly — and opaque to auditors, who parse "version 1.0" instinctively and shas not at all. Separately, a regulatory conversation Nicolas had surfaced a real worldview gap: regulatory people found "all tests run on every commit" strange (where is the validated version?), while to engineering the strange thing is testing ONLY releases. Both are right; the policy must say so.
Decision¶
- Product versioning is plain semver, starting
v0.8.0. Milestone semantics, deliberately:0.9is reserved for the ALM-function milestone (the ADR-0084 Stage C arc, when it lands);v1.0.0is gated on October audit-readiness: CSV package complete (signed validation report, released C-V2 intended-use + tool-risk documents, PQ executed), backup cadence automated, e-signature posture decided. "LQMS 1.0" is a sentence an auditor can act on. - A release is a deliberate act, not every merge — and both testing worldviews are policy:
every commit runs the full verification pipeline (engineering discipline; nothing unverified
ever sits on main); a RELEASE is the communicated validation point (regulatory discipline).
The ritual: cut the tag
vX.Y.Z→ the tag-gated CI jobs run (SBOM already; same trigger extends) → the validation report is generated AT the tag (removing the provenance note by construction) → the GitHub release carries the report + SBOMs + the canonical-backup reference. The requirements baseline decouples: a release RECORDS the baseline in force; it does not force a new baseline. - Where the version shows: the UI build/version info (incl. the user-badge area where build
info already surfaces — the product version leads, build shas behind it),
/api/version(productVersion field), and the validation report's §1 top row. Document exports keep their DOCUMENT identity clean — the exporting tool version is recorded in theEXPORTEDaudit event (queryable evidence), never printed on controlled-copy faces. - Pre-1.0 wire policy (Nicolas, same session): while the test system is the only
installation, API wire-breaking changes are allowed WITHOUT deprecation windows (there is
nothing to migrate). First consumer: the
documentRowId/humanIdnaming unification (the 2026-07-20 review's wire-ambiguity finding) lands as a direct rename. This allowance ends at the first external installation or v1.0, whichever comes first.
Consequences¶
- A small plumbing slice: version from
git describe --tagsinto build-info → UI badge +/api/version+ EXPORTED events; the report generator's §1 keys on the release tag when one is given (requirements baseline becomes an attribute row). Queued behind the running ADR-0085/0088 wave (i18n/build-info collision avoidance). v0.8.0is cut when the 0085/0088 wave lands — fresh-stack verification, new canonical backup, then the first full ritual: tag, report-at-tag, GitHub release. The first auditor-shaped release of LQMS.- Release notes convention: the GitHub release body lists the wave headlines + the ADRs decided since the previous release (the material already lives in the worklog).
Addendum (2026-07-22): local evidence archival¶
Nicolas's concern while wiring the §4 gate references: continued access to the GitHub-hosted CI logs is not guaranteed — the open/closed-source future is undecided, the repository host may change, and GitHub Actions logs and artifacts expire on a retention window (90-day default). A validation package whose verification evidence is only a set of hosted URLs is therefore not self-contained.
Decision: the report generator gains --archive-evidence. At release time it downloads each §4 gate
reference's run metadata + job summaries (not full logs) into docs/validation/<tag>/evidence/<gate>/,
and §4 cites the local bundle as primary provenance with the GitHub URL kept as secondary. The rule
is archive-then-reference: package self-containment must not depend on repository or CI access. Offline
generation degrades honestly (archive skipped — offline), leaving the standing workflow definition as
the gate specification.