What the seal binds
Every CAIRN output — a refusal, retrieved passages, a grounded answer with
[n] citations, a held-knowledge card, an integrity report — is an entry in
an append-only hash chain. Recompute the chain and you know whether the record was
altered after the fact. That is the whole claim. It is also the whole proof.
Order, kind, content, linkage
The entry hash is sha256(seq | prev_hash | kind | canonicalJSON(payload)).
Tamper the sequence, the prior-hash link, the kind, or the payload, and
GET /api/ledger/verify returns ok: false with
broken_at set to the first broken line.
curl -s https://law.cairnsemantics.com/api/ledger/verify
# → { "ok": true, "count": N, "broken_at": null }
Wall-clock time
The human-readable ts field is outside the hash. A receipt
proves order and content, not when. Wall-clock trust is a separate problem (NTP, a
timestamping authority). Folding ts into the hash would make two honest
machines with skewed clocks produce irreproducible seals — and would still not prove
the clock was honest. If you need time, record it inside the payload. That field
is hashed.
The chain, not the clock
Recompute. Do not treat ts as evidence. The live boxes keep the
ledger on a volume so a receipt you just sealed is still there after a redeploy. The
refusal path is arithmetic — a model is never asked to fill a gap. Synthesis, when it
runs, is locked to retrieved passages and every sentence cites [n].
