Skip to main content
Consumers need confidence that what they install is what was published. This page defines how artifacts are hashed and when those hashes MUST be verified.

Two hashes, two domains

The registry publishes two hashes per version. They are not interchangeable.
canonical fingerprint
SHA-256 of the canonical uncompressed inner tar. This is the domain the lockfile, the cache sidecar, and the build manifest all record, and the anchor for every comparison below.Alongside it, the build manifest records a per-entry hash for every inner-tar entry: facet.json, each primary text asset, and each supplementary file. Verification recomputes every one, so integrity covers every file the archive ships.
transport hash
SHA-256 of the uploaded .facet bytes. Used only for a transport check at download, and never persisted to the lockfile.
Both use the format sha256:<hex>. Gzip is a delivery concern outside the hash contract, so the canonical fingerprint cannot be recomputed from transport bytes without decompressing first.

Obligations

  • At build. The producer computes the canonical fingerprint and the per-entry hashes over the assembled archive.
  • At publish. The registry independently verifies the upload and records both hashes.
  • At download. The transport hash MUST be verified against the raw bytes.
  • Before extraction. The inner archive MUST be decompressed and the canonical fingerprint recomputed over those exact uncompressed tar bytes, never taken from the build manifest’s own claim, and it MUST match both that claim and the registry’s published value. Extracted files do not preserve the tar byte stream, so the fingerprint cannot be recovered from them.
  • After extraction. Every per-entry hash MUST be recomputed from the extracted entry’s bytes and MUST match the hash the build manifest records for that path.
  • On every cache use. Cached content MUST be re-verified against what was recorded when it was cached. Content that fails MUST NOT be materialized.
  • Against the lockfile. When the lockfile pins a version, the verified integrity MUST equal the locked integrity.
  • When recording a lockfile entry. The verified integrity MUST match the registry’s published fingerprint. An unreachable registry MUST fail the operation rather than record an unconfirmed entry.
On reproduction, an implementation MUST also reconcile each recomputed entry hash against the lockfile’s per-file records before writing, and MUST report the exact drifting path. A legitimate new version resolves to a different integrity and has nothing to reconcile against.

Checks

A failure MUST identify which check rejected it. The checks are distinct because their remedies are:
registry
The registry’s fingerprint for a pinned version disagrees with the lockfile. The highest-priority failure: a published version has been redefined.
registry
Verified cache content disagrees with the registry’s published fingerprint.
registry
A downloaded archive’s self-declared integrity disagrees with the registry’s metadata.
registry
Recomputed content disagrees with the archive’s own build manifest, which is a tampered archive.
source build
Content built from a git source disagrees with the locked integrity, which is how a moved tag is detected.
A frozen install requires every facet, including local sources, to reproduce its locked integrity. That failure reports under the lockfile check rather than the git check, so the two are never confused.
Integrity is anchored to the authored name. Archive paths and every hash derive from the name the publisher declared, so aliasing changes nothing here and an alias can never smuggle different content under a familiar name. An omitted text asset is verified too: verification covers the resolved set, not the subset written to disk.

Where hashes live

Lockfile

The canonical fingerprint per facet, plus a { path, integrity } record per authored file.

Build manifest

The canonical fingerprint plus the complete per-entry hash map, embedded in the archive.

Cache sidecar

The same values recorded beside cached content, and re-verified on every hit.

Ownership record

Identities and owned paths, not hashes. Used to decide what may be deleted.