v0.24.0 Installation Image Identity Review
Status: complete (2026-08-31). This review closes the installation-identity failure found by adversarial checks after the explicit-value-subject milestone.
Finding
The previous installation manifest named nocter and std but did not identify their contents. When NOCTER_HOME selected another home, byte equality between the running and bundled compiler prevented a compiler mismatch, but neither compiler was bound to that home's standard library. A new compiler copied into an older home could therefore pass installation validation and fail only after package analysis. Editing the standard package declaration also passed nocter doctor.
This was a model defect, not an isolated missing check: release identity described metadata paths while compatibility depended on the unrecorded contents behind those paths.
Closed Model
nocter.manifest v2 is the installed image identity. It binds:
- the exact compiler file through
compiler.sha256; - the complete physical standard-library tree through
std.tree_sha256; - the release, host, default target, implemented targets, license locations, and archive identity.
nocter-content-integrity is the single implementation of physical file and regular-tree hashing. The installation validator, exact-package cache, and packaging tool consume it instead of defining parallel traversal or digest rules. The mechanism assigns no package or release meaning.
nocter-installation validates manifest syntax, artifact paths, compiler bytes, running-compiler identity, and standard-tree bytes before it can construct NocterHome. It passes the manifest release to StandardPackage; it does not parse standard-library source.
nocter-package remains the sole package-declaration authority. After loading the selected standard package, it verifies declaration name std and the installation-selected release. Syntax-invalid declarations continue through the ordinary source-diagnostic path instead of being reinterpreted by installation code.
Release packaging stages the compiler and standard library, computes their identities with the same Rust implementation, renders manifest v2, and asks the staged compiler to validate both doctor and a real offline source check before archiving.
Boundary Review
- Single authority:
nocter-hashowns SHA-256 byte streaming;nocter-content-integrityowns the filesystem projection; manifest decoding owns installed metadata shape; package resolution owns package declarations. PackagingVERSIONis the sole authored release-version value; the installed manifest and archive name derive from it. - No recomputation of decisions: packaging computes artifact facts once for the manifest; installation verifies those facts; package resolution consumes the selected release rather than rediscovering it from a path or installation file.
- No responsibility reversal: installation does not parse Nocter, packaging does not scrape
std/index.nct, and package resolution does not know the manifest schema. - No caller-discipline contract: a
NocterHomecannot be produced before both artifact digests pass.StandardPackagecarries the expected release as required input, and both full-package and standard-only resolution validate it. - No compatibility residue: manifest v1 and exact-package manifest v1 are rejected. The static path-only packaging manifest and its separate validator were removed.
Qualification Evidence
The implementation is covered by focused digest, manifest, installation, cache, package-resolution, CLI, and symlink tests; locked whole-workspace tests; warnings-denied Clippy; generated-document validation; and deterministic local release assembly. Extracted-package checks prove that changing either the compiler or one standard-library byte is rejected before analysis.
No remaining defect in this scope causes an incorrect installation to become a compiler toolchain. Time-of-check/time-of-use races against a concurrently mutated installation are outside the current immutable-installation operating contract and have no observed impact.