// architecture
How a run becomes a record
Six stages. Each one leaves bytes the next stage can check. Nothing in the pipeline is trusted; everything is verified.
The pipeline
The session runs inside a VM we control, on a pinned agent build. Sensors are declared before the run starts: hook events on the tool surface (every tool call and its result) and a boundary view from outside the guest (filesystem walk before and after; network capture is planned, not shipped).
Every observation becomes a transcript entry, and every entry carries the hash of the one before it. Delete, reorder, or edit a single byte anywhere in the run and the chain stops agreeing with itself.
Controls are registered before the run and proven inside it: each one is armed, shown reachable, calibrated, and its outcome is observed. A bundle that cannot show its controls worked is invalid, not clean. A quiet run returns INCONCLUSIVE, never a pass.
Two ed25519 keys, operator and reviewer, in minisign's native format. The verifier enforces that they are distinct keys. The public keys ship in the bundle set and are pinned by their own calendar receipt.
At run start the record carries a drand quicknet receipt (public randomness nobody precomputed). At close, both anchor digests go to the OpenTimestamps calendars, which aggregate them into the Bitcoin chain. The fingerprints are permanent; the content stays off-chain and deletable.
Anyone runs the verifier: stdlib-only Python, offline, no installs. Nineteen named rules over the file set, the schema, the chain, the controls, the citations, the beacon, the anchors, and the signatures. Every rejection names its rule.
What the verifier checks
The nineteen rules, grouped by what they protect. The full definitions are in the spec that ships in the sample zip.
The proof it works, not the promise
The tamper corpus is the test the format is scared of: twenty-two forged bundles, each violating exactly one rule, each rejected with the rule named. The real run is a recorded Claude Code session that took a baited .secrets directory; the control fired and three independent witnesses (stdout, argv, hook spool) agree. A quiet control run returned INCONCLUSIVE, which is what a quiet run is supposed to return.
All of it is in the public set: /evidence/sample. Download, unzip, python3 -m verify. If you have the minisign CLI, the signatures cross-check with a tool we did not write; the recipe is in KEYS.md inside the zip.
What it does not do
- It does not see everything. Coverage is measured and printed in the bundle; blind spots are named, not hidden.
- It does not prove the model behaved. It proves what the declared sensors saw, and that those sensors were working.
- Anchors bind time, not identity. The signing keys are published and pinned, and one human currently holds both roles; that is in the bundle's independence block, in writing.
- Content never goes on-chain. Fingerprints are permanent; bundles stay files you can delete.
Back to agent session evidence or the sample set.