How it works

From one agent action to evidence a third party can check without trusting the operator, in five steps.

A hash chain anchored by a timestampThree receipts, numbered 0 to 2. Each one stores the SHA-256 hash of the one before it as prev_hash, so they form one chain. The last receipt's hash is the chain head, and an RFC 3161 timestamp authority signs a statement over that head.#0receipt#1receipt#2receiptprev_hashheadTSARFC 3161
  1. Record

    An agent records each consequential action as a receipt: what it did, the action detail, its side-effect class and an idempotency key. The receipt is canonicalized with RFC 8785 and signed with the agent’s own Ed25519 key. Recording the same idempotency key again returns the original receipt and writes nothing new, and a dry run returns the exact receipt that would be written.

    signature = Ed25519(agent key, JCS(receipt))

  2. Hash chain

    Every receipt carries the SHA-256 hash of the complete receipt before it, so the receipts form one chain. Altering, removing or reordering any receipt breaks the chain at that receipt, and local verification names the exact receipt that broke and the ranges that are still intact.

    prev_hash = SHA-256(JCS(previous receipt))

  3. Anchor

    The chain head is timestamped with RFC 3161 by an authority the operator does not control. That will happen when you buy an evidence bundle, once bundles open: we will anchor the head of the chain you send us. Nothing can be bought yet. Cloud (early access, not available yet) is planned to anchor automatically, at most every 15 minutes. The timestamp covers a statement that binds the chain id, position, head hash and receipt count, so a genuine token cannot be replayed against another chain or another position. Re-anchoring a position whose head has changed is refused rather than silently allowed.

    RFC 3161 token over JCS({ v, chain_id, seq, head_hash, receipt_count })

  4. Evidence bundle

    An evidence bundle is a range of the chain exported as JSON, with a human-readable PDF and HTML report. Once bundles open, you will get one by buying a bundle; we will send it back once the chain is anchored. The bundle is self-contained: the receipts as their exact canonical bytes, the agents’ public keys and the timestamp tokens. The one thing it does not carry is the timestamp authority’s trust anchor, because a bundle that vouched for itself would prove nothing.

    receipts + public keys + timestamp tokens → one JSON file

  5. Verify offline

    Anyone checks the bundle with the free MIT verifier, on their own machine, with no network and no account. It recomputes every hash, checks every signature and the full RFC 3161 token, and reports whether the authority is one you trust separately from whether the mathematics holds. It names any receipt that fails and warns about receipts after the last anchor.

    VERIFIED / ANCHORED · VERIFIED / NOT ANCHORED · VERIFICATION FAILED

Keys and identity

The signing key is created by lacre init and kept in agent.key.json in the store directory (by default ~/.lacre), unencrypted, with file mode 0600. It never leaves the machine: only signatures and public keys do. An agent is registered by trust on first use: its id is bound to the first public key registered for it, and a different key for the same id is refused. There is no key rotation or revocation yet; a new key is a new agent identity. A bundle carries its agents’ public keys and nothing else vouches for them, so pin your agents’ key ids out of band, as you pin the timestamp authority. Keys and identity in detail.

What the steps do not give you

Steps 1 and 2 are free and prove internal consistency only: an operator with database access could rebuild the whole chain and it would still verify. Step 3 is what the operator cannot forge. Even then, an anchor does not prove completeness: receipts after the last anchor can be truncated without breaking the chain, which is why Cloud (early access, not available yet) is planned to anchor continuously, and why the verifier reports how far the chain is anchored.