Skip to main content

Module fixity

Module fixity 

Source
Expand description

Fixity — content checksums that let prov detect bit-rot, not just broken links.

Link validation in the higher-level prov crate answers “does the graph still hold together?”; fixity answers the other archival question: “are the bytes still the bytes?” A stored hash, recomputed on read and compared, catches the silent corruption an archive most fears — a flipped bit in a decade-old attachment that no link check would ever notice.

§Why this sits in the read core

Everything here is a pure function of bytes: a policy enum, a digest, and two predicates over a recorded string. None of it opens a file, and none of it can change one — the same reason identity sits here rather than above the read boundary. The writes that record a digest (attach, save, the manifest verbs) live in prov, and the pass that reads bytes back to compare them is prov’s check.

§Why SHA-256

The algorithm is SHA-256, and a hash is recorded as sha256:<hex> — the prefix names the algorithm, so the field is self-describing and a future one can be added without ambiguity. SHA-256 is the archival lingua franca: a prov workspace’s fixity is verifiable by anyone, with standard tools (sha256sum, BagIt validators), not only by prov — the same tool-agnostic, self-describing ethos the whole crate is built on.

The compression function comes from sha2 rather than being written out here. This module did once carry its own, on the reasoning that guards exec::block_on and the journal’s FNV checksum — keep the dependency surface tiny and WASM-clean. It is the one place that reasoning loses: sha2 is pure Rust and no_std-capable, so it costs no build toolchain and compiles on wasm32-unknown-unknown like everything else here, while a hand-written loop cannot reach the hardware path — sha2 dispatches to SHA-NI on x86-64 and to the ARMv8 crypto extensions on aarch64, and stamp --all hashes every covered file in the workspace.

What does not change is that correctness here is checked, not trusted: SHA-256 is a fully specified, deterministic function with published test vectors, and the tests below pin this module’s output to the NIST vectors and to what sha256sum produces — now testing the binding rather than a local compression loop, which is exactly what they are for.

Enums§

Fixity
How far content checksums cover a workspace.

Functions§

digest
The fixity digest of bytes, spelled sha256:<lowercase-hex> — the form recorded in a sidecar, a frontmatter field, or a recycle-bin tombstone, and the form verify checks against. The sha256: prefix names the algorithm, so the record is self-describing and a future digest can be distinguished.
is_recognized
Whether recorded is a fixity digest prov can actually check — the predicate that separates “verified” from “unverifiable” so a caller can tell a matching hash from one it had to take on faith.
verify
Whether bytes still hash to the recorded digest. true when the recorded value is empty — nothing was ever recorded, so there is nothing to contradict (a document predating fixity is not “corrupt”). A recorded value prov cannot recognize (a future algorithm) is treated as unverifiable, which is also true: fixity never raises a false alarm over a hash it does not understand, it simply cannot vouch for it.