Open source · for teams running AI agents
Know exactly what
your agent read.
Prove it years later.
Readproof gives every document an agent reads a stable identity, a freshness policy, and a content addressed snapshot. Each run becomes a manifest you can diff against another, replay byte for byte, and export as evidence.
No signup. No services. One Go binary, and nothing leaves your machine.
- 3 source adapters
- 13 MCP tools
- SHA256 replay test in CI
- in-toto evidence bundles
# 1. identity + source + freshness rule, once $ readproof resource add \ readproof://demo/policies/refunds \ --source-type filesystem \ --path policies/refunds.md \ --policy require_fresh # 2. record exactly what run-a was given $ readproof run --id run-a \ readproof://demo/policies/refunds Committed manifest manifest_01M0JED936… for run run-a (1 entry) # 3. pin those bytes as the reviewed version $ readproof tag set \ readproof://demo/policies/refunds \ prod snap_01M0JED935… # 4. someone edits the policy: 30 → 14 days, # and a later run reads the new bytes $ readproof run --id run-b \ readproof://demo/policies/refunds # 5. the diff names the revision that moved $ readproof diff run-a run-b why: source revision sha256:c8b0bb212e93 → sha256:8f4b00474456 -Products can be refunded within 30 days. +Products can be refunded within 14 days. # 6. replay reads the store, never the file $ readproof replay run-a Products can be refunded within 30 days. Replay verified: SHA256 match for 1/1 entries. # 7. and the bundle verifies anywhere $ readproof evidence verify bundle.json evidence verified: 1 entry, merkle root a9b73469f1a6…
What the agent read, pinned by hash. What changed between runs, explained. What was delivered, provable years later.
The problem
Models are probabilistic. Most context failures are not.
The retrieval worked, the prompt was fine, the model was fine. The document had changed underneath, and nobody could show what the agent actually saw. Agent reliability is bounded by context reliability.
It worked on Tuesday
A policy, price table, or runbook changed and the agent quietly started answering from a different version. Readproof records which revision each run read, and readproof diff shows what changed and when.
Can you rerun exactly that?
Tracing tools keep strings. They cannot hand you the bytes again once the source moved. readproof replay rebuilds a run's inputs from the store and verifies every hash again, with no network and no source.
What data did the agent consider?
EU AI Act Article 12 logging for Annex III systems applies from 2 August 2026, and SOC 2 reviews ask the same question. readproof evidence export answers it with a file anyone can verify. Not legal advice, but it is the record.
Benefits
Small surface. Sharp guarantees.
Every run is reproducible
Replay from the store, not the source. readproof replay run-a rebuilds the exact bytes and checks every SHA256 again, after the file changed, the key expired, or the repo was archived.
Diffs explain themselves
Inputs, not just outputs. readproof diff run-a run-b names the source revision and observation time that changed, then prints the unified diff.
Freshness is a policy
Not a cache bug. require_fresh verifies each resolve again, allow_stale reuses within a max age, and @prod pins a reviewed snapshot. Promotion is one pointer move.
Audit is a file, not a dashboard
Portable evidence. readproof evidence export writes an in-toto Statement whose subject digest is a Merkle root over the run. Anyone can verify it, offline.
Plugs into what you run
No rewrite. MCP for Claude Code and Cursor, OpenTelemetry spans, a LangGraph example, a TypeScript SDK, and a plain HTTP API. Embedded SQLite or Postgres with S3.
How it works
Register. Record. Prove.
Three commands, and every one of them is real output from readproof 0.3.2.
01 · register
Give the document an identity
A source (file, GitHub path, or HTTP URL) plus a freshness policy. The URI survives the bytes changing.
# 1. identity + source + policy $ readproof resource add <uri> \ --source-type filesystem \ --path policies/refunds.md \ --policy require_fresh Registered resource …/refunds source: filesystem policy: require_fresh
02 · record
Mount it into a run
Mount resolves and records at the next position; commit freezes the run into a manifest.
# 2. mount + commit, one shot $ readproof run --id run-a <uri> Mounted …/refunds -> snap_01M0JED935… (position 0) Committed manifest manifest_01M0JED936…
03 · prove
Diff, replay, export
Compare runs with the why, rebuild bytes from the store, or export the evidence bundle.
# 3. prove: replay, then verify $ readproof replay run-a Replay verified: SHA256 match for 1/1 entries. $ readproof evidence verify \ bundle.json evidence verified: 1 entry, merkle root a9b73469f1a6…
Proof, not promises
Standards underneath, tests on top.
There are no testimonials on this page because the project has not launched. What exists is verifiable.
- The invariant is a test. The refund agent demo asserts SHA256(original) equals SHA256(replay) over SQLite, over Postgres with MinIO, and over a real HTTP round trip.
- Evidence follows the
in-totoStatement v1 format, with Merkle vectors checked against an independent implementation and tamper tests that must fail. - Telemetry follows the OpenTelemetry GenAI conventions (
gen_ai.data_source.id), and the commit span carries the same Merkle root as the bundle. - The MCP server uses the official Go SDK and is tested through a real client over both the embedded and remote paths.
- CI runs on every push: Go build, vet, and tests, the SDK tests, and a Docker Compose integration run that replays the demo against the built image.
# 1. export the run as an in-toto Statement $ readproof evidence export run-a \ --with-content --out bundle.json evidence bundle written to bundle.json: 1 entry, merkle root a9b73469f1a6… # 2. re-check it anywhere — flip a byte and it exits 1 $ readproof evidence verify bundle.json --offline evidence verified: 1 entry, merkle root a9b73469f1a6…, embedded content 1/1 re-hashed, replay cross-check skipped (--offline)
Integrations
It sits underneath the tools you already run.
Readproof is not a vector database, an observability tool, a prompt registry, or a memory system. It makes their inputs reproducible.
- MCP Claude Code, Claude Desktop, Cursor
- OpenTelemetry GenAI attributes, run spans
- LangGraph manifest id in the checkpoint
- TypeScript SDK zero dependencies
- Storage SQLite embedded, or Postgres with S3
- DeepSeek Harness native plugin bundle + MCP overlay
- Open models via Ollama support agent example, no API key
Claude Code, one line# point Claude Code at a local store $ claude mcp add readproof -- \ /abs/path/readproof mcp \ --data-dir ~/.readproof # then ask, in the session: # "Read readproof://demo/policies/ # refunds@prod and tell me the # refund window."
TypeScript, record a turn// one agent turn = one Readproof run const run = readproof.run({ id }); // mount = resolve + record, in order await run.mount( "readproof://acme/policies/" + "refunds@prod"); // commit freezes it; keep the id const { manifest_id } = await run.commit();
DeepSeek Harness, one line# install the native DSH bundle $ cd integrations/deepseek-harness $ dsh plugin --profile web add \ ./dsh-plugin-readproof $ dsh web # the same 13 readproof_* tools, # one Readproof run per session
MCP setup · SDK · LangGraph · DeepSeek Harness · Support agent example · Observability · HTTP API
FAQ
Questions engineers ask first.
Is Readproof a vector database or a RAG tool?
No. Readproof is about the source documents and what a run actually received. Keep retrieving however you do; mount what you retrieved so the run is reproducible. Derived chunk materializations are on the roadmap, and v0.3 delivers raw bytes only.
Does it replace my tracing or observability tool?
No, it complements it. Traces key on spans; Readproof keys on source identity, adds freshness policy, run to run input diffs, and byte exact replay. The run's Merkle root appears in your trace and in the evidence bundle, so the two join on one field.
Do I need to run a server?
No. Embedded mode keeps everything in a local .readproof directory with SQLite and blobs. readproofd with Postgres and S3 is there when a team, a service, or the MCP server should share one history.
Which sources are supported?
Filesystem, GitHub (a path at a branch or ref, the commit SHA becomes the source revision), and HTTP (any URL, headers may reference environment variables). S3, Confluence or Notion, and generic git are on the roadmap.
How are credentials handled?
Tokens are read from the readproof or readproofd process environment at fetch time and never stored. Sensitive header values are masked in every API response, in readproof inspect, and in evidence bundles. readproofd can require a single API key.
What does the evidence bundle prove, and what does it not?
It proves these bytes, by hash and optionally embedded, were delivered for this run in this order under these resource definitions, and that the store can still reproduce them. It does not prove the model used them or that the source was authoritative. Bundles are not signed yet; signing is on the roadmap.
Does it work with Claude Code, Cursor, and DeepSeek Harness?
Yes. readproof mcp is a stdio MCP server: registered documents become readable readproof:// resources with provenance in _meta, and resolve, runs, diff, replay, tags, and evidence export are 13 tools. One claude mcp add line sets it up. For DeepSeek Harness there is a native plugin bundle that registers the same 13 tools and records one Readproof run per DSH session (dsh plugin --profile web add …), plus a zero-code MCP overlay.
What is the license?
Apache-2.0 — see LICENSE and NOTICE in the repository. The project was renamed from Ctx to Readproof in v0.3.2; the name is final. Everything on this page reflects the code as it is today.
Start
Sixty seconds, no services.
Clone, build one binary, register a document, record a run, replay it. Delete the .readproof directory to uninstall.
Privacy
This page is static. It sets no cookies, runs no analytics, and collects no personal data. The only external request is for fonts from Google Fonts.
Terms
Readproof is provided as is, without warranty, under the Apache-2.0 license, as a pre launch release. Command output shown here was captured from version 0.3.2 and is reproducible from the repository's reference demo.