SemVer-Trust

ADR-034 — Ecosystem publishing profiles constrain resolver-routing claims

Status: Accepted (2026-07-13) Date: 2026-07-13 Supersedes: ADR-001 Related: ADR-011 Decision: trust remains encoded in SemVer pre-release position for the canonical git tag, and build metadata remains rejected as the trust carrier. ADR-011’s language-agnostic core and plugin-architecture decisions remain accepted. This ADR revises ADR-011’s registry-projection clause: trust pre-releases provide native ordering friction, but default resolver behavior is ecosystem-specific and MUST be described by an explicit publishing profile. Registry routing is not attestation verification, and a clean version carries no visible trust level unless the consumer verifies the accepted release attestation. The portable baseline defines profiles for Go modules, npm, and Cargo, and defers Python/PyPI projection until an injective mapping is accepted. Rationale: primary ecosystem documentation does not support the earlier unconditional “opt-in with zero consumer tooling” claim. Go’s latest selects the highest pre-release when no release version exists, even though release versions are otherwise preferred. npm range semantics exclude prereleases by default, but npm publish sets the latest dist-tag unless another tag is supplied, and ordinary npm install <pkg> installs latest. Cargo dependency requirements and cargo install avoid pre-releases unless explicitly requested. PEP 440 allows prereleases when already installed, explicitly requested, or the only satisfying candidate, and it cannot carry the -tN.I identifier. The earlier PyPI rc<iteration> projection is non-injective because SemVer-Trust iterations restart when the trust level changes; v1.2.3-t0.1 and v1.2.3-t2.1 would collide as 1.2.3rc1. Same-source promotion also does not imply identical artifact digests when registry artifacts embed different version metadata; the portable promise is source identity unless a reproducible-build profile proves more. Rejected: preserving the unconditional zero-consumer-tooling claim (overstates resolver behavior and confuses routing with verification); retaining the baseline PyPI rc<iteration> projection (non-injective); using build metadata as the trust carrier (ADR-001’s precedence and portability objections still hold); treating registry dist-tags or package indexes as trust anchors (storage and routing are never the authority). Primary references: npm dist-tags and publish behavior (https://docs.npmjs.com/cli/v10/commands/npm-dist-tag/), npm semver prerelease range behavior (https://github.com/npm/node-semver#prerelease-tags), Go module version queries (https://go.dev/ref/mod#version-queries), Cargo prerelease dependency behavior (https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#pre-releases), and PEP 440 prerelease handling (https://peps.python.org/pep-0440/#handling-of-pre-releases). Revisit trigger: an ecosystem profile demonstrates an injective Python/PyPI projection, or another major registry changes resolver/publication behavior enough to alter the profile.