Where they go
The store is authoritative: receipts and events are rows, andctrlrun receipts, inspect and
stats read them from there. A JSONLEventSink also appends each to .ctrlrun/receipts.jsonl
and .ctrlrun/events.jsonl beside the store, one object per line, in order, so the evidence
survives the process and the file can be shipped anywhere. An OTelEventSink exports one span
per action and one span event per step to a tracing backend, with argument values kept out
unless you ask for them.
Which policy decided it
policy_hash is the SHA-256 of the policy’s canonical decision inputs: the rules, the mode, the
environment and the authority grants, not the file’s bytes, so a reformat changes nothing and a
changed rule changes everything. policy_version is the operator’s own label, recorded and never
authoritative. A receipt from six months ago therefore says what the rules were rather than what
they are now, and where a policy changes between a human approving and an agent executing, the
approval is re-checked against the policy in force at execution.
The chain
Each receipt carriesseq and prev_hash, the hash of the receipt before it. An edit to a
receipt, a deletion from the middle, a reordering: each is detected and named by seq with
ctrlrun receipts --verify-chain. The chain detects alteration. It does not prove authorship:
receipts are not signed, and an administrator who can rewrite every row including the chain head
can rewrite history undetected. The receipt chain says exactly what
it covers and what it does not.
The guarantee it supports
Receipts: G11 (an altered receipt is detected) inctrlrun verify, and every demo receipt is
asserted to carry every field the specification names.
What it does not do
A receipt records what CTRLRun saw, not what the remote did after the reply was lost; anAMBIGUOUS outcome is recorded as ambiguous, and the resolution, when it comes, is a further
event naming who resolved it. A receipt that failed to write leaves no gap in seq; the events
log is where that is reconciled. And receipts are evidence, not a dashboard: there is no UI, by
design.