Proof Store (η)

η is where the per-session decision chain becomes a round-level proof. A Merkle tree is built over the session’s thought_records; its root is pinned; downstream readers verify claims about the session against that root without replaying any of the reasoning.

Authoritative specs: ../../../spec/s02-event-taxonomy.md (event shapes) and the hardening requirements of ../../../spec/s13-hardening.md.

The tree

η builds a binary Merkle tree where each leaf is content_hash of a thought_record. Internal nodes are SHA-256(left_child || right_child). If a level has an odd leaf count, the last leaf is duplicated (standard Bitcoin-style rule) so the tree is always balanced.

The root of the tree is the Merkle root for the session. It is a 32-byte SHA-256 digest; no additional metadata is hashed into it.

Finalization workflow

A proof-grade task closes with this order (enforced at convention level in Phase 0; runtime hard-block is a later upgrade):

audit_session_start(session_id, task_id)
  ... thought_record calls interleave with work ...
audit_verify_chain(session_id)
thought_record(type=reflection, ...)       # REQUIRED: closes ζ chain
merkle_finalize(session_id)                # builds η tree, returns root
merkle_root(session_id)                    # idempotent read
audit_session_end(session_id)

Ordering rule: the final thought_record MUST come before merkle_finalize. Once finalized, a session’s tree is immutable. A late reflection would require a new session.

Retention tiers

Three tiers, moving from newest to oldest:

  • Hot — the current round’s sessions. Full tree in merkle_nodes, all content fields in thought_records.
  • Warm — rounds within the retention window (Phase 0 default: the last 3 sealed rounds). Trees kept, content bodies may be compacted to their hashes once the round is sealed.
  • Cold — rounds outside the warm window. Only the Merkle root and an index are retained; full content is archived externally.

The Frozen tier from donor documentation — external blob store, content-addressed — is specified but not implemented in Phase 0. Phase 0 keeps everything in SQLite.

Load-bearing tables

  • merkle_nodes — tree structure; columns (session_id, node_index, level, hash, left_child_index, right_child_index).
  • audit_events — the lower-level ledger of every tool call; a session’s audit_events and thought_records together describe exactly what happened.
  • thought_records — the leaves (see ../../execution/decision-trail.md).

The 19-tool Phase 0 surface

η exposes 2 tools per ADR-004:

  • merkle_finalize(session_id) — build the tree, write nodes, return the root. Idempotent for an already-finalized session: returns the stored root, does not rebuild.
  • merkle_root(session_id) — read the stored root. Returns null if the session exists but is not finalized.

There is no merkle_verify tool in Phase 0; verification is done by re-reading the chain with audit_verify_chain from ζ and re-hashing to the root. A dedicated verify tool is a Phase 1 addition.

Integration with consensus (future)

θ consensus (see consensus.md) will eventually require multiple arbiters to sign the same Merkle root at each finality level. In Phase 0 the runtime is single-writer, so the Merkle root is self-signed by the executing agent and consensus is trivial. The schema already carries a signatures column reserved for this extension, so no migration is needed when consensus activates.

What η is not

  • Not a blob store. η stores hashes of records, not the records’ external artifacts. Files produced by a task live in the repo or the task’s output bundle; η only proves what was decided about them.
  • Not cryptographic proof of truth. A Merkle root proves what was recorded; it does not prove the recording is correct. Correctness of claims comes from verification (VERIFY state in β), not from hashing.
  • Not a backup. A backup is against data loss; η is against tamper. The two concerns overlap but are not the same.

Interaction with rounds

A round’s seal includes the Merkle root of every session that ran inside it. The next round’s genesis embeds those roots as its parent list. This forms a round-level chain on top of the session-level chains — a fractal of SHA-256. See ../../../5-time/round.md.

See also


Back to top

Colibri — documentation-first MCP runtime. Apache 2.0 + Commons Clause.

This site uses Just the Docs, a documentation theme for Jekyll.