Provenance

Why did we make that decision?

Every belief carries its lineage. Ask any decision “how did you get here?” and the chain of derivations, evidence, and prior beliefs comes back with hashes attached.

Not a log line saying “approved.” The graph of every input the decision drew from — the episodes that produced it, the beliefs that shaped it, the rules that fired, the documents that were viewed. Traversable, hashable, replayable.

See it live → Cypher reference db.beliefLineage · db.verifyAclChain

The lineage of belief-99. Two source episodes rolled into a belief; the belief rolled into a decision. Every edge is a DERIVED_FROM relationship the store records at write time. Hover any node to see its recorded timestamp and content hash.

Every arrow was written by the code that produced the target node. No inference. No reconstruction six months later. db.beliefLineage(“belief-99”) walks the DERIVED_FROM edges backward and returns the whole tree with recorded timestamps and content hashes attached.

The lineage query

One procedure. The whole chain.

db.beliefLineage takes a belief id and walks its DERIVED_FROM ancestry. It returns one row per hop, deepest first — every ancestor belief, with its claim, confidence, when it was created, when (if ever) it was superseded, and the evidence that produced it.

// Walk the full derivation tree for belief-99. CALL db.beliefLineage("belief-99") YIELD beliefId, claim, confidence, createdAt, supersededAt, depth, evidence RETURN claim, confidence, createdAt, depth ORDER BY createdAt;

Every YIELD column, load-bearing.

beliefId identifies the ancestor. claim is what it asserted. confidence is what it asserted with. createdAt is when the store recorded it — monotonic, hash-chained, not editable. supersededAt is the moment a later revision replaced it (null if still live). depth is how many DERIVED_FROM hops from the root you asked about. evidence is the array of source event ids that produced it — the receipts, one hop up.

Trace a live belief back to its raw episodes.

// Every belief that shaped belief-99, plus the events they came from. CALL db.beliefLineage("belief-99") YIELD beliefId, claim, depth, evidence WHERE depth > 0 RETURN beliefId, claim, depth, evidence ORDER BY depth DESC;
Property provenance

Every value carries its receipts.

Provenance isn't a top-level log — it's woven into every stored value. When a belief's confidence flips from 0.70 to 0.95, the write records who caused it, what evidence backed it, and the hash of the state that produced it. The chain doesn't require trust. It requires re-hashing.

1 · DERIVED_FROM edges

Every derivation is an edge, not a comment.

When a belief is written from source episodes, the write emits DERIVED_FROM edges pointing at each source. When a revision supersedes a prior belief, another edge is written. The lineage isn't reconstructed — it was serialized at write time.

(:Belief)-[:DERIVED_FROM]->(:Episode)
2 · Content hashes

Every recorded value has a sha256.

Node property snapshots are content-hashed. Two beliefs with the same claim + confidence + source set produce the same hash. Two beliefs with a different source set do not — you cannot pass one off as the other, even if the claim text matches.

sha256: 3a1c8f92e4b7d0…
3 · Hash-chained audit log

Every write links back to the last one.

Each recorded event carries the hash of the previous event. Tampering with any historical write invalidates every hash after it — and db.verifyAclChain() will surface exactly which event id broke the chain, and why.

prevHash hash nextHash
Anatomy of an approval

Why was this approved? — walk the evidence.

March 5. Susan approved a $4.2M commercial property policy. Six months later a regulator asks why. In most stacks that's a six-week reconstruction. Here it's a walk of the decision graph — every step queryable, every edge recorded at the moment it happened.

CASE FILE · pol-2026-03-9847
Susan approved a $4.2M commercial property policy.
BIND · recorded 14:32:18Z
1
14:14:33Z · viewed
Loss-run history opened.
7-year history. Two small water claims, both closed. No fire, no liability, no fraud flags. Susan spent 4m 12s on this document — the read was recorded as an episode.
// Reconstruct exactly what Susan saw, in her clock. MATCH (r:Risk {id: "CP-2026-9847"})-[:HAS_HISTORY]->(c:Claim) AT RECORDED "2026-03-05T14:14:33Z" RETURN c.date, c.amount, c.peril, c.status;
loss-run-2019-2026.pdf episode-482
2
14:18:51Z · rules
Sprinkler credit rule fired.
Engineer report attached the week before — NFPA-13 wet system, monitored 24/7. Rule SPRINKLER-CREDIT-12pct matched. 12% off the filed rate.
engineer-report-2026-02-27.pdf rule SPRINKLER-CREDIT-12pct belief-114
3
14:22:09Z · docs
CAT score pulled.
CoreLogic wildfire 24/100. Flood zone X. Earthquake zone 3. Within the appetite band for territory. The external call is a recorded episode with a payload hash — if CoreLogic disputes the number later, the exact response body is retrievable.
CoreLogic API response rule CAT-WITHIN-APPETITE episode-501
4
14:26:42Z · known
Reinsurance treaty checked, ceded to the property quota.
$4.2M is under the $5M single-risk cession threshold. Goes entirely through the per-risk treaty. No facultative negotiation needed. The treaty version at that clock is fetchable via AT RECORDED.
treaty-2026-property-quota.json rule TREATY-AUTOCEDE-LE-5M
5
14:32:18Z · decided
Bound. Quote sent. Signature chain closed.
Premium $48,720 / yr at filed rates with the 12% sprinkler credit. Effective 2026-04-01. The Decision node points DERIVED_FROM at every belief, every rule, every viewed document, every episode — the whole subgraph the outcome drew from.
// Every input the decision drew from, one hop out. MATCH (d:Decision {id: "decision-2026-03-05"})-[:DERIVED_FROM]->(src) RETURN labels(src) AS kind, src.id, src.createdAt ORDER BY src.createdAt;

Five steps. Every one is a Cypher query you can run yourself. That's what “audit-grade” means when the database is the receipts layer — not the log-shipper.

The audit chain

Tamper-evident, by construction.

Every ACL-affecting event is hash-chained. Every property write is content-hashed. db.verifyAclChain takes zero arguments and walks the whole chain end-to-end — re-hashing as it goes. If any historical event was mutated, the procedure returns the exact event id where the chain broke and why.

// Re-hash the audit chain end-to-end. CALL db.verifyAclChain() YIELD status, entries, brokenAtEventId, reason RETURN status, entries, reason;
chain intact status: ok · entries: 48,712 · reason: null re-hashed genesis → head in 84ms · no tampering detected
What the reply looks like if it isn't intact. If any entry was altered, status returns “broken”, brokenAtEventId pinpoints the first event whose hash didn't reproduce, and reason explains whether the payload was mutated or the prevHash link was tampered with. Zero ambiguity, no forensic reconstruction.

Pair this with db.beliefLineage and you get the full receipt: the chain of derivations that produced a belief, plus a cryptographic guarantee that not one entry between genesis and the belief's write has been rewritten. That's the receipts posture regulated buyers keep asking for — and rarely getting.

See it live.

Walk the actual approval — viewed → rules → docs → known → decided. Every step is a query. Every edge was written when it happened.