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 SHA-256, and why hand-rolled
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.
It is implemented here rather than pulled from a crate for the same reason
prov_graph::exec::block_on and the journal’s FNV checksum are: prov keeps
its dependency surface tiny and WASM-clean (no build-toolchain cost, nothing
to audit). SHA-256 is a fully specified, deterministic function with published
test vectors, so correctness is checked, not trusted — the tests below pin
it to the NIST vectors and to what sha256sum produces.
§Not hashing what has not changed
Hashing is cheap to describe and expensive to run, and a capture runs it over
every file in the workspace. FixityCache is the device-local memory that
lets a capture skip the files whose stat says they are untouched — and, just
as importantly, the argument for which passes may consult it and which may
never. See its module documentation; the short version is that the bit-rot
check must not, because bit-rot is exactly the change a stat cannot see.
Structs§
- Fixity
Cache - What this device remembers of a workspace’s file digests.
Enums§
- Fixity
- How far content checksums cover a workspace.
Functions§
- digest
- The fixity digest of
bytes, spelledsha256:<lowercase-hex>— the form recorded in a sidecar, a frontmatter field, or a recycle-bin tombstone, and the formverifychecks against. Thesha256:prefix names the algorithm, so the record is self-describing and a future digest can be distinguished. - is_
recognized - Whether
recordedis 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
bytesstill hash to therecordeddigest.truewhen 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 alsotrue: fixity never raises a false alarm over a hash it does not understand, it simply cannot vouch for it.