Decision Trail (ζ)

ζ is the append-only journal of why the system did what it did. Every agent decision that matters — a plan, an analysis step, a choice between options, a reflection at task close — lands as a thought_record whose hash participates in a chain. The chain’s closure (at η) is what makes later claims auditable without re-running the world.

Authoritative state model: ../../spec/s03-state-model.md.

Record types

Four types. Anything else is a schema error.

Type When written What it holds
plan Start of a phase or sub-task The intended trajectory
analysis Mid-phase observation What was learned from context or a partial result
decision Choosing between options The choice, the alternatives, the why
reflection At phase or task close What happened, what was proved, what remains uncertain

A reflection always closes the chain for a task. There is no “informational” type: facts worth recording are either observations (analysis) or decisions.

Chain formula

Every record has two hashes:

content_hash    = SHA-256(canonical_serialization(record_fields))
chain_hash      = SHA-256(content_hash || parent_chain_hash)

parent_chain_hash is the chain_hash of the previous record in the same session (or the session’s genesis hash for the first record). Records are per-session; cross-session continuity is achieved by embedding a session’s last chain_hash into the first record of its successor.

Genesis

The first thought_record of a session uses a genesis parent_chain_hash equal to the SHA-256 of the session metadata record (session id, start time, caller identity). The genesis hash is itself recorded as an audit event, so there is no “silent” session start.

Load-bearing tables

Three tables carry the chain in Phase 0:

  • thought_records — the records themselves, with content_hash, chain_hash, parent_chain_hash, session_id, task_id, type, content.
  • merkle_nodes — the tree structure once records are sealed (see ../physics/laws/proof-store.md).
  • audit_events — the lower-level per-tool-call ledger that α writes; thought records reference audit events for provenance.

These three tables plus the task table are the Phase 0 load-bearing set. Everything else in the schema is either index or optimization.

Writeback ordering

The ordering rule is absolute: the final thought_record of a proof-grade task MUST be written before merkle_finalize. If merkle_finalize runs first, the closing reflection is outside the Merkle root and the proof does not cover the task’s own explanation of what it did.

The full writeback sequence for a proof-grade task:

audit_session_start(...)
  ... work happens; intermediate thought_record calls interleave ...
audit_verify_chain(...)                    # chain integrity check
thought_record(type=reflection, ...)       # REQUIRED: closing reflection
merkle_finalize(...)                       # seals the tree
merkle_root(...)                           # returns the root for pinning
audit_session_end(...)                     # closes the session

Non-proof-grade tasks drop the audit_session_start/audit_verify_chain/merkle_* calls but still require the closing thought_record.

The 19-tool Phase 0 surface

ζ exposes the writing and reading tools inside the “Audit + Proof” block of ADR-004. That block totals 6 tools across ζ and η:

  • ζ (4 tools): audit_session_start, thought_record, audit_verify_chain, audit_session_end
  • η (2 tools): merkle_finalize, merkle_root

Integrity checks

audit_verify_chain walks a session’s thought_records in order and recomputes chain_hash for each row. Any mismatch is a hard failure; the tool returns the first broken index and does not continue. This check runs before merkle_finalize and again as a standalone audit operation when a caller wants to re-prove an existing session.

Tamper semantics

Editing a historical thought_record changes its content_hash, which invalidates every chain_hash from that record forward. audit_verify_chain catches this deterministically. The engine does not offer an “edit with re-hash” API: corrections are new records, typed as analysis or decision, that reference the prior record by id.

What ζ is not

  • Not a logger. Log lines describe process state; thought records describe decisions. Logs can be lost; thought records cannot.
  • Not a metrics store. Timing and resource counters live elsewhere; ζ only carries reasoned content.
  • Not the proof. The chain is necessary but not sufficient: without an η Merkle root over it, nothing anchors the chain into a round’s seal.

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.