Release And Exact Identity Contract
Independent semantic release versions and exact language-snapshot/compiler-build identities.
This document owns the distinction between publication versions and exact development identities. Schema identifiers, target architecture releases, and external tool versions remain identifiers in their own domains; none is a Wyst language or compiler semantic version.
# Terms
- A selected snapshot is the exact language contract selected by one source
tree. Its
wyst.language-snapshot.v1identity changes with its canonical contract inputs and carries no publication claim. - A compiler build is one compiler executable produced from an exact source,
dependency, toolchain, target, feature, profile, flag, and release-state
closure. Its
wync.compiler-build.v1identity is exact and is not a semantic version. - A language release version and a compiler release version are independent semantic versions assigned only by publication. A development build has neither. A nominated candidate carries proposed values, which are not released values.
- A release is publication of the exact candidate artifacts and evidence accepted by a passing gate. It is an event, not a roadmap milestone.
- The release gate qualifies one explicitly nominated clean commit, tree, candidate build, proposed version pair, artifacts, and evidence. It validates the claims implemented in that snapshot and never consults roadmap completion.
# Canonical identities
Both roots use SHA-256 and wyst.length-prefixed-records.v1. A field is encoded
as the little-endian u64 byte length of its ASCII field name, the name bytes,
the little-endian u64 length of its value, and the value bytes. Consumers
reject duplicate paths, noncanonical paths, missing files, symlinks, and an
unknown algorithm or encoding.
The language root begins with domain = wyst.language-snapshot.v1 and
encoding = wyst.length-prefixed-records.v1. It then contains, in ascending
UTF-8 path order, file.path followed by file.digest for every entry selected
by language-snapshot-inputs-v1.txt, including
that manifest itself. Each leaf is sha256: plus lowercase SHA-256 of the exact
file bytes. The set contains the vocabulary, manual authority, semantic
database, catalogs, and bundled core declaration. It excludes ROADMAP.md,
tests, coverage evidence, generated reports, publication history, and the
computed root. Thus a meaning-affecting authority change changes the root, while
test-only or publication-record changes do not pretend to change language
meaning.
The compiler-build root begins with domain = wync.compiler-build.v1 and the
same encoding field. Its ordered file records cover wync/Cargo.toml,
wync/Cargo.lock, wync/build.rs, every regular non-symlink file under
wync/src/ and wync/core/, the selected language inputs, and the exact
generator, machine-authority, and execution-witness closures enumerated by
wync/build.rs. Ordered fact records bind the language snapshot identity,
rustc -vV, content digests and version output for the compiler/linker/archiver
tools and configured Rust wrappers, Cargo host/target/profile/optimization/
debug/features/configuration, encoded Rust flags, and release state. Absolute
checkout, output, and temporary paths are not inputs. The generated Rust
constants and final executable bytes are outputs and are excluded, avoiding a
self-referential digest. Publication history and the identity/release record
schemas are also excluded: changing a record of an event must not change the
identity of otherwise identical compiler bytes.
Two builds with the same canonical records have the same identity. A changed leaf, compiler/tool fact, target, feature, profile, flag, release state, or proposed version changes the compiler-build identity. Independent build copies may compare their executable digest in addition to the build identity; the embedded identity never claims to hash the bytes that contain it.
# Release version policy
Language and compiler deltas are classified independently from their respective previous published releases:
| Version range | Incompatible change | Compatible feature | Compatible fix | Documentation, tests, or evidence only |
|---|---|---|---|---|
< 1.0.0 |
next minor, patch zero | next minor, patch zero | next patch | unchanged |
>= 1.0.0 |
next major, minor and patch zero | next minor, patch zero | next patch | unchanged |
A compiler-only publication leaves the language version unchanged. A language change does not prescribe a compiler bump category: the compiler delta is classified independently. No roadmap edit, feature-state edit, schema revision, target release, or package-manifest version performs a semantic-version bump.
# Development, nomination, gate, and publication
Ordinary builds have releaseStatus = development, null language/compiler
release versions, and exact snapshot/build identities. Supplying only part of a
candidate tuple is a build error. The generic release tooling accepts a clean
40-hex commit, its exact tree, prior published versions, independently selected
change classes, and proposed versions. It rejects a dirty or changing tree,
wrong commit/tree, invalid or noncanonical semantic version, incorrect bump,
failed command, mismatched candidate identity, or fuzz evidence for another
snapshot.
wync identity emits wync.compilerIdentity.v1, validated by
compiler-identity-v1.schema.json.
Current generated and release-evidence projections are
wync.generatedManifest.v1, wync.releaseEvidence.v1,
wync.releaseHostFacts.v1, and wync.releaseArchiveFacts.v1; each carries the
release status, nullable release versions, and both exact identities. The
compiler-owned editor projection is wync.editorCatalog.v1 and carries the
same tuple.
Nomination, passing-candidate, and publication records use the closed schemas in
release-records-v1.schema.json. The workflow
is wync/tools/release-gate.sh nominate, verify, then the deliberately
separate publish command; nomination and evidence destinations must be outside
the repository so they cannot alter the nominated tree.
The gate builds the candidate once with the complete proposed tuple, records
the candidate executable digest and exact identities, runs all portable,
generated-authority, documentation/editor, interoperability, build-twice,
runtime/QEMU, compiler-efficiency, and A64 conformance gates, authenticates the
closed release-fuzz verdict for the same commit and tree, then
rechecks the commit, tree, cleanliness, candidate bytes, and identities. A
passing record is only publication-ready. The proposed versions become released
only when maintainers publish those exact bytes and evidence and record the
publication event. A failed or abandoned candidate changes no released version.
Publication records the canonical tag
wyst-release/language-v<language>/compiler-v<compiler> on the nominated
commit. The publish command revalidates the passing record, independent bump
policy, exact clean commit/tree, latest release baselines, and pre-existing
canonical tag before it emits the publication record; creating that tag and
publishing the gated bytes are deliberate maintainer actions, not effects of a
roadmap edit. In the first later repository snapshot that records the event,
maintainers preserve the gate and publication records below
design/release-records/<tag>/, append the authenticated entry to
release-history.json, and advance each baseline to the corresponding value
(including an unchanged value for the side whose delta was none). History
verification rejects a tag, record linkage, or terminal baseline that does not
match. This bookkeeping records a publication already made; it does not create
one by editing the repository.
Historical tags, peeled commits, and source trees are recorded in
release-history.json. Those bounded records retain
the pre-separation unified version labels where they describe actual past
publication; they do not retroactively claim independent historical language
and compiler versions. Current
compiler, report, artifact, cache, benchmark, debug, LSP, or editor data must not
reuse them as an exact identity.