- Content integrity — does the artifact match what was published? MUST be verified at download, on every cache hit, and at lockfile-entry creation.
- Cache integrity — has cached content been tampered with since it was written? MUST be verified on every materialization from cache.
Content hashing
What it covers
Facet archives — anything published to the facets registry — participate in the full hashing lifecycle below. Git and local sources are built from source rather than downloaded, so they participate through the lockfile-integrity checks described in Git and frozen variants rather than through registry hashes.Two hashes, two domains
The registry publishes two hashes for each version, serving different purposes:content_integrity(canonical fingerprint) — SHA-256 of the canonical uncompressed inner tar archive. This is the domain the lockfile, cache sidecar, and build manifest all record. It is the trust anchor for integrity confirmation and lockfile comparison. Alongside it, the build manifest records a per-entry hash for every inner-tar entry —facet.json, each primary asset, and each supplementary file — and verification recomputes every one. Integrity therefore covers every file the archive ships, asset or not, including archive-only files likeREADME.md.content_hash(transport hash) — SHA-256 of the uploaded.facettarball (the gzipped delivery bytes). Used only at download time for a raw-bytes transport check. Never persisted to the lockfile.
Format
sha256:<hex-encoded hash> (e.g., sha256:a1b2c3d4e5f6...)
When it is applied
1
2
Download
The transport hash (
content_hash) MUST be verified against the raw downloaded bytes.3
Post-extract recompute
The canonical fingerprint MUST be genuinely recomputed from the extracted content (per-entry hashes + canonical-archive hash) — never taken from the build manifest’s self-declared claim — and MUST match both the manifest’s claim and the registry’s published
content_integrity. An unsupported facetVersion produces a structured failure carrying the observed and supported versions, which the CLI renders as upgrade guidance.4
Cache write
The canonical fingerprint (
content_integrity) and per-entry hashes are written to a sidecar alongside the cached content.5
Cache hit
The cached content MUST be re-hashed against its sidecar (self-audit). Tampered content MUST be evicted and re-fetched.
6
Lockfile comparison
When the lockfile pins a version, the audited integrity MUST equal the locked integrity. On reproduction — when the facet resolves to the integrity already locked — install additionally reconciles the recomputed archive-entry hash against each lockfile per-file record and the verified build-manifest hash before any file is written; a mismatch fails with the exact drifting path. A legitimate change resolves to a different integrity and has nothing to reconcile against.
7
Integrity confirmation
When a lockfile entry is being created or replaced, the audited integrity MUST match the registry’s published
content_integrity. An unreachable registry MUST fail the operation.8
Lockfile record
The canonical fingerprint is recorded for reproducible verification.
Integrity is entirely authored-domain and, in fact, name-agnostic. Archive paths and every hash derive from the name the publisher declared, so aliasing an asset changes nothing here — and an alias can never be used to smuggle different content under a familiar name. An omitted asset is fully verified too: verification covers the resolved set, not the subset written to disk.
What it guarantees
- Transit integrity: the downloaded bytes match what the registry stored (transport hash).
- At-rest integrity: cached content is verified on every use, not just at write time (cache self-audit).
- Lockfile trust: a lockfile entry for a registry facet MUST NOT be created without same-operation registry confirmation of its canonical fingerprint.
- Immutability enforcement: the registry’s invariant that a published
name@versionnever changes is enforced client-side via the lockfile comparison and integrity confirmation.
Where hashes live
Lockfile
Canonical fingerprint (
content_integrity) per facet, plus a { path, integrity } record per authored file inside each asset entry — present even for an omitted asset, which materializes nothing.Cache sidecar
Canonical fingerprint + per-entry hash map (
cache-integrity.json) per cache slot. Written at cache-populate time; re-verified on every cache hit.Build manifest
Canonical fingerprint + complete
files hash map (one entry per inner-tar file). Embedded in the .facet archive.Install receipt
Per-asset authored identity, owned authored paths, and the disposition each asset was materialized under (not hashes — used for offline drift removal). Omitted assets never appear.