verify-vh — offline verifier (in your browser)

Check whether a file someone handed you is byte-for-byte what they signed — and who signed it. Everything runs on this computer; nothing is uploaded.

An INDEPENDENT, read-only, fully OFFLINE verifier for verifyhash evidence packets. It RE-DERIVES the keccak Merkle root from the bytes YOU drop in and recovers the signer with a pure-JS secp256k1 routine — it never trusts the artifact's own stored hashes. This one file contains NO network API at all: your packet bytes never leave this machine (check the devtools Network tab, or disconnect from the internet first — it still works).

Honest boundary: ACCEPT is tamper-evidence that these exact bytes match the seal — and, for a signed seal, WHO vouched (signer recovery + optional vendor pin). It is NOT a trusted timestamp and NOT proof of WHEN without a separate trusted timestamp. For CI/production gating use the node standalone (verify-vh-standalone.js).

Unpinned is NOT provenance: if you do not enter a vendor pin below, the accept is UNPINNED — the bytes verify, but anyone's key passes. An attacker who re-signs a tampered release with their OWN key would still show ACCEPT (rendered amber and labelled UNPINNED here, never the green of a pinned accept). Pin the producer you trust with a vendor address, or gate CI with the node standalone's --strict, which fails closed on an unpinned accept (exit 4).

1 — The 60-second challenge (built in)

A real, genuinely-signed sample packet is embedded in this page (signed by a fixed, published TEST-ONLY key — never a real key). Load it, watch it ACCEPT, then change ONE byte of a sample file below and watch the verifier REJECT it and name the file you changed.

2 — Verify a packet YOU were handed

Drop the sealed artifact (*.vhevidence.json / *.vhseal / attestation / proof bundle / *.vhagent.json agent-session packet) together with the files it references (an agent packet is self-contained) — or pick them below (the folder picker keeps sub-directory paths). Nothing is uploaded; the page reads the bytes locally.

Drag the packet + its files (or a whole folder) here

Leave this blank and you are trusting whatever key signed this packet — anyone's key passes, so an attacker who re-signs a tampered release with their own key still shows ACCEPT (marked UNPINNED, amber). Pin the producer's address to REJECT a different signer (wrong_issuer). For a CI gate that FAILS on an unpinned accept, use the node standalone with --strict (exit 4).

The same offline check also works on AI-agent session logs — a tamper-evident record of what an AI agent was asked, did, and answered.

▸ Show the advanced agent-session demo

The agent-session demo (AgentTrace, built in)

A sample *.vhagent.json AGENT-SESSION packet is embedded in this page: an ordered prompt/tool_call/tool_result/completion log under one RFC-6962-style Merkle head, with the tool_call payload REDACTED behind its hash commitment — and it STILL verifies (redaction can withhold, never silently alter). Load it, watch it ACCEPT, then change ONE byte of a payload below and watch the verifier REJECT it and name the offending event seq.