1. A real captured bundle

This is not a mock-up of evidence. It is the actual output of demo/run.sh, run from a fresh clone of public main at commit 1794eed on an independent verifier machine on 2026-08-01 at 07:35 UTC. Nine of nine behaviors observed. Clone to pass took 15 seconds on that machine.

Download the bundle (18 KB) Read the bundle README

SUMMARY.txt (verbatim)
generated: 20260801T073527Z
commit:    1794eed
target:    simulated (mock driver). NOT a real device.
behaviors: 9 observed, 0 not observed

PASS  GREEN read classified and executed
PASS  observation authentication tag verified
PASS  intact record verifies; modified record is rejected
PASS  RED command blocked by the tier gate
PASS  approval signed with a key the collector does not hold
PASS  approved command executed under its verified approval
PASS  single-use approval refused on reuse
PASS  unrecognized command blocked by default
PASS  every session links from its own genesis; approval triple present

Browse the individual records:

The keys inside are published on purpose. The collector's HMAC key and the chain key are in the bundle so you can recompute every tag and replay the chain yourself. They were generated for that one run and protect nothing. The approver's Ed25519 secret key is the one file we removed, because verifying a signature needs only the public half. That asymmetry is the whole reason this site says “authenticated” for observations and “signed” for approvals: we had to publish the symmetric keys for you to check our work, and we did not have to publish the signing key.
One inconsistency, left uncorrected on purpose. The captured records print signature=VALID and signed observation for what this site calls authenticated HMAC material. That is the reference tool's own wording, reproduced byte for byte. Editing captured evidence so it matched our preferred vocabulary would be a far worse thing to do than shipping the mismatch, so the records stand and the CLI rename is tracked as code-level work.

Before publishing, the chain in this bundle was re-verified independently of the harness that produced it: each entry hash was recomputed as SHA-256 over its canonical JSON, and every per-session link was walked from that session's genesis. All six entries verify, across both sessions.

2. Interrogate a record

What the sandbox below is. A worked example whose cryptography is real and computed live in your browser, using the same constructions as the implementation: HMAC-SHA256 over the record material, and chain entry hashes as SHA-256 over canonical JSON. It is a teaching surface, not a second captured session; the captured session is the bundle above. Its genesis values match the real ones: gate-enforce:demo-r1 hashes to bf2e5656… here and in the bundle's database.

This is what a GREEN read produces: the request the collector issued, the material it received, and an authentication tag binding them to the session, the device, and a hash of the exact command. Press a button to alter a field. The page recomputes the tag over the altered material and compares it to the tag the collector produced.

3. The evidence chain

Each session is its own hash-linked sequence. The entry at sequence 0 carries previous_entry_hash = SHA-256("VIRP_CHAIN_GENESIS:" + session_id), and every later entry commits to the previous entry of the same session. This run holds two sessions, which is the normal case: the approval spine and the gate's rejections are separate chains, interleaved in storage.

What the chain does not defend against. Every attack above is detected because it is performed without the collector's key. A holder of the chain key can rewrite entries and recompute both the hashes and the authentication values, and the result verifies. That is the honest boundary: the chain is tamper-evident within the collector trust boundary, not against a compromised collector. Detecting rewrite or truncation requires trusted checkpoints or external anchoring, which are designed and not yet built. See the security page.

4. Verify it yourself, offline

The same records verify without this page and without a network connection:

# produce a real session bundle
git clone https://github.com/nhowardtli/virp
cd virp
docker compose -f demo/docker-compose.yml run --rm demo

# replay the chain from the bundle it wrote
./build/virp-tool chain tail --db demo/output/session-<timestamp>/run/chain.db

# verify a single observation against the collector key
./build/virp-tool inspect <record.bin> <onode.key> okey

# or check the published bundle above, without running anything
unzip virp-demo-bundle-9of9.zip && cd session-20260801T073527Z
./build/virp-tool chain tail --db run/chain.db
./build/virp-tool inspect records/03-observation.bin          run/onode.key okey
./build/virp-tool inspect records/03-observation-tampered.bin run/onode.key okey  # must fail

A bundle contains the per-step records, the collector log, the chain database, the device configuration, and a summary stamped with the commit that produced it. The demo asserts nine behaviors and prints a pass count; it reached 9/9 from a fresh clone on an independent machine.