Decision journal
An append-only JSONL file. Each line commits to the one before it, so history cannot be quietly rewritten.
Format
{"seq":3,"ts":"2026-10-10T22:30:11.000Z","kind":"action","data":{...},"prev":"9f2c...","hash":"b81e..."}
hash = sha256(seq | ts | kind | JSON(data) | prev). The first entry's prev is 64 zeros. Kinds: tick, thought, action, result, risk_denied, error.
Verify
perpad verify journal/agent.jsonl
# ok: 42 entries, hash chain intact
# TAMPERED: chain breaks at seq 17
Opening a corrupt journal for writing throws instead of appending to a broken chain.
What it proves, and what it does not
It proves entries were not edited or removed in the middle of the file. It does not prove the agent's operator did not truncate the tail or start a fresh file. To close that gap, publish the latest hash somewhere you cannot silently change (a signed git tag, a post, an on-chain memo) and let readers compare. Anchoring is on the roadmap.