Treeship
Concepts

Logs vs receipts

Why an audit log and a green CI check answer a different question than a receipt.

Logs are good at "why did this break." Receipts are good at "did this happen." Most teams have the first and assume it covers the second.

The difference in one line

A log is written by the system whose behavior is in question. A receipt is signed evidence that survives leaving that system.

Everything else follows from that.

LogReceipt
Written bythe system under questionthe same system — but signed
Editable after the factyes, by anyone with write accessno; any edit breaks verification
Proves orderby timestamp, which the writer controlsby parent hash, inside the signed bytes
Detects a deleted middle entrynoyes — the chain breaks
Survives the vendornoyes — verify offline with a public key
Checkable by an outsideronly if they trust your loggingyes, with no trust in you
Answerswhat happened, roughlywhat was reported, by which key, in what order

A log tells you a story. A receipt gives someone else a way to check it without believing you.

Where logs are better

This is not a replacement. Logs win on:

  • Debugging. Full text, stack traces, verbose context. Receipts carry hashes; you cannot read a hash.
  • Volume. Logging every line is cheap. Signing every line is not.
  • Unstructured discovery. Grep is a superb tool for questions you did not know to ask.

Keep your logs. The argument is that they cannot carry the claim receipts carry, not that they should be replaced.

CI checks vs portable receipts

The same distinction, one level up — and this is where it bites hardest.

A green CI check proves something passed in the CI environment. It does not prove the artifact runs in the environment it ships to. The classic failure: twelve checks green, production broken, because the build container had a shared library the runtime container did not.

The check was not wrong. It answered a different question than the one everyone read it as answering.

CI checkPortable receipt
Claim"this passed in the runner""this ran here, under this identity, with this result"
Environmentthe builder'srecorded explicitly (execution_identity)
Which binary ranunrecordedresolved path + sha256
Lives whereyour CI provideranywhere; verify with a public key
After the account closesgonestill verifies
Readable by a customernoyes

The upgrade isn't "more checks." It's stating which claim the check proves. "Builds in runner" and "runs in target" are different receipts, and conflating them is how a green dashboard ends up describing a world it never entered.

When you actually need a receipt

Reach for one when the answer must survive contact with someone who does not trust you:

  • an agent reports work and a human has to decide whether to believe it
  • an auditor asks what touched a record, six months later
  • a customer asks what your agent did with their data
  • two agents hand off, and the second must not re-derive the first's claims
  • a vendor relationship ends and the evidence has to outlive the account

If the only consumer is you, next Tuesday, debugging — a log is the right tool and cheaper.

Being precise about the claim

A receipt does not prove the recorded claim is true. It proves the claim was made by a specific key, in a specific order, and has not changed since. That is narrower than "verified" and it is exactly why it holds. See what a receipt proves.