Chapter 15 — Verifying: five modes, two surfaces, four asymmetries¶
Mental model¶
Verification is arithmetic over bytes and keys. No verdict in this codebase is about truth, origin, identity, or trusted time. The MCP tool occam_verify and the host-binary CLI occam verify implement the same math on different surfaces — and they are not interchangeable.
Explanation¶
Occam ships six distinct proof kinds across two programs:
| Surface | Modes | What they check |
|---|---|---|
MCP occam_verify |
offline (default), live, prove, citation, history |
Envelope signature, optional content hash, Merkle membership, watch-chain links |
Host CLI occam verify |
receipt, citation, manifest, history |
Same offline math plus dataset manifest binding; requires --pubkey |
Five MCP modes¶
offline— Recompute canonical bytes, verify ECDSA signature, optionally checkcontentHashagainst supplied markdown. Time anchor is reported but non-gating on MCP.live— Re-fetchfinalUrlthrough a bare anonymous pipeline (no session, no playbook, no token budget) and compare hashes.driftedoften means "my re-fetch lacked the original's context," not "the page changed."prove— Emit a citation package{leaf, proof[]}for block index i after verifying leaves reconstruct the signed root.citation— Verify Merkle membership plus envelope signature for a supplied citation package.history— Verify watch-chain link integrity and per-entry signatures.history_verifiedrequires every entry signed and verified; unsigned chains report chain integrity separately (chainIntegrity/signatureStatus), nothistory_verified.
CLI-only manifest¶
Dataset manifest verification exists only on the CLI. A pure-MCP agent cannot verify a dataset export manifest in-band.
Four asymmetries (name them when you verify)¶
manifestis CLI-only — MCP agents structurally cannot verify dataset manifests.liveandproveare MCP-only — the CLI has no equivalent.- Time anchor gates the CLI verdict but not the MCP verdict — a broken anchor yields
verifiedover MCP and exit1on the CLI. --pubkeyis mandatory on the CLI, optional on MCP — MCP defaults to the running host's own key, so verifying a foreign receipt withoutpublic_keyreportssignature_invalidorwrong_key, not "foreign author."
Neither surface via the operator wrapper¶
The friendly occam wrapper has no verify or keys subcommand. Invoke the host binary directly:
dotnet run --project src\FFOccamMcp.Core -- verify --mode receipt --pubkey pub.pem --receipt r.json
# or the published AOT binary with the same verb
Unknown verify modes on MCP silently downgrade to offline and the response claims "mode":"offline".
Verdict vocabulary¶
Write "the signature did not validate under this key" — not "verified against the wrong key" vs "tampered," which the vocabulary cannot distinguish on older paths. Phase 6 added wrong_key / key_mismatch on some surfaces; still no verdict about truth.
CHECK¶
LOCAL. Hand a receipt and exported public PEM to a colleague. They run:
# CLI — pubkey mandatory
occam-host verify --mode receipt --pubkey colleague.pem --receipt receipt.json
Then run the same receipt through MCP occam_verify without public_key. Observe signature_invalid or wrong_key because MCP used the local host's key.
LOCAL (Phase 6 behavior). Build a watch history, strip every Sig field, rebuild prevEntryHash if needed, and verify. Expect chain integrity reporting without history_verified — not exit 0 / history_verified on an unsigned chain.
Common misconception¶
"live mode proves whether the page changed." The re-fetch drops session profile, playbook overlay, content selectors, token budget, and backend pin. drifted usually means the verification fetch lacked the original's context. Every re-fetch failure collapses to refetch_failed with no failure code.
Limitations¶
- No verdict proves truth, accuracy, origin, identity, or trusted time.
- MCP
occam_verifydefaults to the local key — not a third-party verification surface unless you passpublic_key. livemode is not reproducible without network and is context-blind.- CLI trust verbs are unreachable through
occam verifyon the operator wrapper. - Crosscheck verdicts and attest aggregates have no verify mode — they are unsigned.
- Time anchor validity gates CLI exit codes but not MCP verdicts.
Links¶
- Chapter 14 — What a receipt proves
- Chapter 16 — Evidence for claims and corpora
- Chapter 18 — Exposure —
readerprofile and verify visibility - appendix-status-labels.md
- User docs: Receipt verification · occam_verify tool
- Contract:
MCP_API_SPEC.md· Source audit:docs-audit/TRUST-MODEL.md§7–§8