Most systems sign the report. FahCel signs every reading — and chains them together — so tampering with any value, anywhere in the history, becomes mathematically undeniable.
Sealing happens at ingestion, so the proof already exists before anyone asks for it. For a QA manager, that turns three familiar scrambles into things that are simply ready.
Export a signed, timestamped PDF with the full reading-level history and its verification result — laid out for review against the records you're already assessed on.
EU GDP · 21 CFR Part 11 §11.10(e)The moment a reading crosses a threshold, the team is notified — and the record is already sealed into the chain, not reconstructed after the fact.
Sealed at ingestion · not at report timeHand over the dataset and the open verifier. An inspector can recompute the chain themselves, offline, and reach the same result you did.
Deterministic · offline · open-sourceA single hash would tell you if a reading was edited in place. It wouldn't tell you if a reading was deleted, reordered, or silently inserted. Two hashes — one over the payload, one over the payload plus the previous record_hash — make every form of tampering detectable.
A fingerprint of the reading's business content, independent of its position in the chain. The exact field set and canonicalization rule are proprietary — but deterministic: the same reading always produces the same hash, on any system, forever.
The chain link. Every record_hash embeds the previous reading's record_hash, so the hashes form a one-way dependency graph. Genesis reading uses prev_hash = '0'.
A linked list where every link is independently verifiable. If reading #3 is altered, readings #4 through #N all fail verification — because their stored record_hash no longer matches the recomputed one.
The verifier is deterministic and identical to the code that seals the chain: the same readings always produce the same verdict. Customers and auditors run the full version offline against any exported dataset — the core sealing rule stays proprietary.
// hashChain.js export function verifyChain(readings) { const sorted = [...readings].sort( (a, b) => a.device_timestamp - b.device_timestamp ); let prev_hash = sorted[0].prev_hash; // anchor ('0' at genesis) let firstTampered = null; for (const r of sorted) { core sealing — proprietary, redacted const data_hash = sha256(canon(██████████)); const record_hash = sha256(canon({ ████████ ┄ ████, prev_hash, ████████████ })); if (data_hash !== r.data_hash || prev_hash !== r.prev_hash || record_hash !== r.record_hash) { firstTampered ??= r.seq; // remember first failure } prev_hash = r.record_hash; // walk forward regardless } return { valid: firstTampered === null, first_tampered_at: firstTampered, total: sorted.length, }; }
The verifier walks readings in device_timestamp order — not ingestion order. A reading that arrives late but was captured earlier slots into the right position in the chain.
For every reading, the verifier rebuilds data_hash and record_hash from the stored fields using the same canonicalization rules. It does not trust the stored values — it recomputes them and compares.
The first mismatch — in either hash — is flagged. Every reading after it inherits suspicion: even if their own hashes look valid, the chain has already lost integrity.
valid, first_tampered_at, and total readings walked. The same values land in your audit PDF — so the inspector sees exactly what your QA team saw, and can replay it themselves.
A single hash detects a reading edited in place, but not one deleted, reordered or silently inserted. FahCel stores two: a data_hash over the reading’s payload, and a record_hash over that payload plus the previous reading’s record_hash. Together they make every form of tampering detectable, not just field-level edits.
record_hash in a cold-chain log?The record_hash is the chain link. It is the SHA-256 of the reading’s canonical payload combined with the previous reading’s record_hash, so the hashes form a one-way dependency graph. The first reading in a shipment uses prev_hash = '0'. Alter any reading and every record_hash after it changes.
Run verifyChain() over the exported readings. It recomputes each data_hash from the payload and each record_hash from the payload plus its predecessor, then compares them to the stored values. The check is deterministic, replayable and works offline, so an auditor can reproduce the result without trusting FahCel.
Verification fails from that reading onward. If reading #3 is altered, readings #4 through #N all fail because their stored record_hash no longer matches the recomputed one. The first broken link is flagged and everything downstream is marked untrusted, so you learn where the tampering started, not just that it happened.
Hashing uses SHA-256 as specified in FIPS 180-4. The tamper-evident audit trail is designed against 21 CFR Part 11 §11.10(e), which requires secure, computer-generated, time-stamped audit trails that do not obscure previously recorded information, and it supports EU GDP record-keeping expectations.
In a 20-minute QA demo, we'll seal a stream of temperature readings at ingestion, run verifyChain in front of you, then tamper with a single reading and show you exactly where the chain catches it. No slideware — the actual system, the actual hashes.