Hash Chains

Every interaction in a Spooled trace is linked via a SHA-256 hash chain, creating a tamper-evident audit trail.

How it works

Each interaction has a payload_hash (SHA-256 of its canonical payload). The chain is formed by computing a signature for each interaction that includes the previous interaction's signature:

# Each interaction's signature includes:
signature = sha256({
    interaction_id,
    sequence,
    interaction_type,
    payload_hash,       # hash of this interaction's content
    prev_hash,          # previous interaction's signature (None for first)
})

# The chain links:
interaction[0].signature = sha256(id, seq, type, payload_hash, prev_hash=None)
interaction[1].signature = sha256(id, seq, type, payload_hash, prev_hash=interaction[0].signature)
interaction[N].signature = sha256(id, seq, type, payload_hash, prev_hash=interaction[N-1].signature)

The final interaction's signature becomes the trace's chain_hash — a single value that represents the entire execution sequence.

Verification

spooled verify trace .spooled/traces/agent-runid.jsonl --verbose

This recomputes every hash in the chain and verifies:

  • Each payload_hash matches the interaction's canonical content
  • Each prev_hash matches the previous interaction's payload_hash
  • The chain is unbroken from first to last interaction

Tamper detection

If any interaction is modified after recording — content changed, order rearranged, interaction inserted or removed — the hash chain breaks. The verification command will report exactly which link is invalid.

CI integration

Hash chain verification runs automatically during spooled ci run and spooled ci compare. A broken chain causes the trace to be flagged.

Compliance use case

For regulated deployments, the hash chain provides tamper-detection evidence that a trace has not been modified after execution. Combined with KMS-signed attestations (Pro/Team), this creates a verifiable audit trail.

Note
Hash chains protect against post-hoc modification only. They do not prevent a compromised SDK from recording false data — they guarantee that once recorded, the data hasn't been tampered with.