Tamper-evident hash chain
A tamper-evident hash chain is an append-only audit sequence where each entry's hash commits to the prior entry's hash plus its own payload, so editing, reordering, or deleting any interior entry breaks every hash computed after it. Verification recomputes the chain end to end and reports the first index where it breaks.
In code
export function hashChainLink(
prevHash: string | null,
payload: JsonValue,
): string {
return createHash("sha256")
.update(canonicalize([prevHash, payload]))
.digest("hex");
}How it holds
Truncation and rewrite need an anchor
Internal consistency alone doesn't prove completeness: a chain with its last N entries dropped, or a wholly forged replacement chain, still verifies clean. anchorChain mints a committed { length, tipHash, genesisHash } triple held outside the chain in WORM storage; passing it to verifyChain catches both.
Deterministic canonicalization
canonicalize() recursively sorts object keys before hashing, so two payloads that differ only in key order produce the identical hash. The chain is reproducible across machines, languages, and JSON serializers, the hash input, not just the algorithm, is load-bearing.
Pinpoints the first break
verifyChain walks every entry's seq, prevHash linkage, and recomputed hash in order and returns the index of the first failure, not just a pass/fail bit, so an interior edit, insert, reorder, or drop is located precisely.