Verified Transcript Cache Protocol
Reference implementation: donotreadagain (dnr)
Read once, never again. A small protocol for faithful, signed transcripts of expensive-to-parse source files, so AI agents stop re-OCR/re-parsing the same PDF, image, scan, spreadsheet, or audio every time.
Tell your agent:
Use dnr for this folder.
That one line is the adoption path. The agent fetches SKILL.md, checks cached transcripts before parsing files, and records any expensive read it had to do anyway.
This repo contains the Verified Transcript Cache Protocol, its record
schema and conformance vectors under spec/, and dnr, the reference
CLI implementation. Harnesses can call the CLI today or implement compatible records
natively later.
The problem
AI agents re-parse the same file every time they touch it — re-OCR a scan, re-run vision on a screenshot, re-transcribe an audio clip, re-extract a PDF. It's slow, it burns tokens and model calls, and it's non-deterministic. In repeat-access corpora (legal, research, compliance) the same documents get read dozens of times; with multi-agent setups every agent re-parses independently. The waste compounds exactly where it hurts.
The idea
The protocol defines a cache/trust/index layer for expensive source-file reads. A local
extractor, local ASR model, or the calling AI agent
reads a file once; dnr stores the resulting transcript + structured metadata as a signed JSON
record in a folder .dnr.db by default, so original files stay byte-identical. Any agent that
opens it later reads the cached transcript instead of re-parsing. A per-folder SQLite + FTS5
index makes a whole folder searchable without opening anything. Portable in-file records remain
available with explicit --embed, but file modification is never the default.
The second view is the win:
| first view (re-parse) | second view (cached) | |
|---|---|---|
| born-digital PDF | local text extraction (PyMuPDF→pypdf) | ~60 ms — no PDF parse |
| image / scan / audio | a vision / Whisper model call | a few ms of text — no model at all |
…and the cache is trustworthy: a record is used only if it's signed by a trusted key and its content_hash still matches the file, so "fast" never means "stale or forged."
Protocol contract
For agents and harnesses, the protocol is a small pre-read loop:
- Known file: run
dnr read <file>before parsing it. If stdout has text, use it and do not re-read. - Miss: if the task still needs the file, parse/look/listen once, then cache that result with
dnr ingestordnr record. - Folder question: run
dnr index <folder>, thendnr query <folder> ...before opening files. - Folder preparation: use
dnr status <folder> --pending; rundnr backfill <folder>only when the user wants a folder pass. - Boundary: never bulk-transcribe just because files are pending; only cache work the task actually needs.
Harness maintainers can copy the integration contract and reference adapters from HARNESS.md, or implement the protocol directly from PROTOCOL.md.
Demo
$ dnr ingest contract.pdf # transcribe once → sign → cache in .dnr.db
ingested contract.pdf [db-only (index)]
method=text-extract transcriber=pymupdf
signed key_id=ce6d170a497238f7
$ dnr read contract.pdf # later (or from any agent): verified cache hit — no re-parsing
LOAN AGREEMENT
Lender: Acme Capital LLC
Borrower: Jordan Smith
Principal: USD 1,200,000
...
$ dnr index ./contracts
$ dnr query ./contracts --match damages --context 40 # search a whole folder, no files opened
contract.pdf
… Principal: USD 1,200,000 Maturity: 2026-12-31 Damages clause: section 7.
The transcript lives in the folder's .dnr.db by default, so contract.pdf itself stays untouched.
If you explicitly need the cache to travel inside the file, add --embed.
Quickstart
Recommended install:
pipx install donotreadagain
dnr --version
# one-off/fallback when installing is not available:
uvx --from donotreadagain dnr <cmd>
# audio ASR:
pipx inject donotreadagain faster-whisper # ffmpeg may also be needed for decoding
dnr ingest report.pdf # extract once (local) → sign → store in .dnr.db
dnr backfill ./case-folder # folder pass: local-provider files now, agent/vision worklist after
dnr read report.pdf # print the cached transcript (verified), or fall back
dnr index ./case-folder # build .dnr.db
dnr status ./case-folder --pending # honest usable/pending/repair coverage
dnr query ./case-folder --match "손해배상" --tag 가압류 --since 2025-01-01
For a scan / image / anything you must look at, the agent transcribes it and records the result:
dnr record scan.png --transcript-file t.md --method vision --transcriber <your-model>
How it fits together
File = canonical truth Index .dnr.db = default cache
┌────────────────────────────┐ harvest ┌────────────────────────────┐
│ original file bytes │ ───────▶ │ signed record + FTS5 search │
│ content_hash · transcript │ │ path · tags · transcript … │
│ provenance · fields · sig │ └────────────────────────────┘
└────────────────────────────┘ ▲ query via sqlite3 — dnr CLI optional for reads
▲ transcribe once · sign · store db-only (expensive)
Where the record lives (no sidecar files):
- db-only by default in the folder's
.dnr.db, so original files stay byte-identical. If the source file changes, the stale record is removed and the file must be re-ingested/re-recorded. - Optional in-file with explicit
--embedfor formats with a metadata slot — PDF→XMP, MP3→ID3, M4A/MP4/MOV→MP4 freeform atom, FLAC/OGG/OPUS→Vorbis/Opus comments, PNG→iTXt, JPEG→APP segment. This makes the transcript travel with the file, but it rewrites file bytes and is never the default. - Nothing for already-readable text (
.txt/.md/.csv) — an agent just reads it.
Current format support:
| Format | Transcription | Record storage | Status |
|---|---|---|---|
local text layer (PyMuPDF first, pypdf fallback) or agent vision for scans |
db-only default; optional XMP with --embed |
partial | |
| PNG / JPEG | agent-supplied vision transcript | db-only default; optional PNG iTXt / JPEG APP with --embed |
implemented |
| HEIC / HEIF | agent-supplied vision transcript; optional pillow-heif hash |
db-only | partial |
| MP3 / WAV / M4A / FLAC / OGG / OPUS | local Whisper provider via donotreadagain[audio], if installed |
db-only default; optional in-file for non-WAV carriers with --embed |
partial |
| DOCX | local python-docx text extraction |
db-only | implemented |
| XLSX | local openpyxl sheet extraction |
db-only | implemented |
| MP4 / MOV video | agent-supplied transcript/ASR+vision | db-only default; optional MP4 freeform with --embed |
partial |
| PPTX / other office/media | planned providers or agent-supplied transcript | db-only until carriers land | planned |
Using it
- Read (consumer):
dnr read <file>returns the cached transcript only if it's present, trusted, and still matches (self-validating — a changed file silently misses). No dnr tool? An agent can read.dnr.dbdirectly with ambientsqlite3(the db's_dnr_readmetable self-describes). - Transcribe (producer):
dnr ingest(local: PyMuPDF→pypdf / python-docx / openpyxl / optional faster-whisper) ordnr record(agent supplies a vision/OCR transcript). dnr is an opportunistic cache: do this when the current task already requires reading/parsing that file, not just because a folder has pending files. If a needed file's cached transcript is empty/garbled/unusable, repair that file immediately; ask only before expanding into whole-folder OCR/searchability work. - Backfill a folder:
dnr backfill <folder>(alsodnr ingest <folder>) ingests locally-processable files in one pass, skips already-readable text, and prints a worklist for images/scans/videos or low-quality results that need agent/vision repair. - Query a folder:
dnr query <folder>combines--match(FTS, Korean/CJK ok) ∩--tag a,b∩--since/--until∩ restricted--whereover fixed columns; plus--any(OR sweep),--dedup,--context(KWIC),--format json. Save composed queries with--save/--use; accumulate labels withdnr tag. - Agents onboard locally: point an agent at a dnr folder and it fetches SKILL.md once for that task/folder. Recommended install is
pipx install donotreadagain; one-off fallback isuvx --from donotreadagain dnr ....dnr initjust ensures a signing key by default; to persist the bootstrap in a project instruction file, rundnr init --agent-file AGENTS.md(or--agent-file CLAUDE.md). Harness authors can integrate the same read-through cache hook with HARNESS.md.
Design principles
- Protocol first, CLI as proof. The Verified Transcript Cache Protocol is the portable contract;
dnris the reference implementation that proves it works and gives harnesses an optional hook today. - Original files stay untouched by default. The default write path is
.dnr.db; in-file records require explicit--embed. - Not a general knowledge format. dnr stores faithful transcripts tied to original files. Curated concepts, runbooks, summaries, and knowledge-base pages belong in higher-level docs; dnr can feed those systems, but it is not trying to replace them.
- dnr is the deterministic substrate; the agent is the intelligence. dnr does verifiable primitives (hash, sign, full-text/structured query); it never infers metadata (dates, parties, topics) or does fuzzy semantic search — that's the agent's job. Set metadata explicitly with
dnr tag/dnr date. - File = truth, index = regenerable cache. Delete
.dnr.dband rebuild it from the files anytime. - Transcriber-agnostic. dnr ships a contract (the verbatim guide) + a trust layer, not a model. Fidelity is the transcriber's; provenance is recorded so a consumer can apply its own quality policy (
trusted ≠ faithful).
Status & honest limits
v0.2 early release. Published on PyPI as donotreadagain; the recommended path is pipx install donotreadagain. uvx remains a one-off/fallback path, but it still requires uv and can be slower than a normal install for repeated use. Standalone binaries remain a future packaging option for Python-less environments. Works today for repeat-access corpora; validated by real-corpus dogfooding. Known limits we're explicit about:
- Adoption is the real lever. The value compounds when agents know dnr (a skill, eventually native support) — not from the tool alone.
trusted ≠ faithful. A signature proves who made it + that it matches the file, not that the transcription is accurate. Low-quality/garbled transcripts are flagged (dnr status), not silently trusted.- Coverage is still growing. PDF/PNG/JPEG/HEIC/DOCX/XLSX and common audio containers are useful today; OOXML carriers, more video containers, pre-query auto-scan, and larger-corpus concurrency are still roadmap work.
- Benchmarks are early. The README numbers are illustrative dogfood timings; see BENCHMARKS.md and experiments/content-hash-invariance for the current proof/measurement status. A broader latency/token benchmark remains a release-readiness item.
- Python packaging is the product path. Use
pipxfor the cleanest install;uvxremains the one-off/fallback route.
See PROTOCOL.md (protocol contract) · spec/ (schema and vectors) · HARNESS.md (harness integration) · vision.md (design) · SECURITY.md (threat model) · qna.md (settled design decisions) · MILESTONES.md (roadmap).
Development
git clone https://github.com/melodysdreamj/donotreadagain
cd donotreadagain
python -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]"
pytest # the suite is green and fast
Contributions welcome — see CONTRIBUTING.md. Release automation is documented in RELEASING.md.
License
MIT © 2026 june lee
Metadata
Release files for donotreadagain 0.2.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| donotreadagain-0.2.3.tar.gz | 99.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| donotreadagain-0.2.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 149.6 kB
Release files / donotreadagain-0.2.3.tar.gz
| Download URL | donotreadagain-0.2.3.tar.gz |
|---|---|
| Size | 99.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7c90b0ff5db25a987edb84bb21e4cf5f6000779f6829a965da998b174ef5c243
|
|
BLAKE2b-256 checksum How to use checksums |
fd5d2ed0c9bb2862eaa9ecfa1a2fa47e7c044414c112e410255dbdb353b069d1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 21, 2026.
Transparency logRelease files / donotreadagain-0.2.3-py3-none-any.whl
| Download URL | donotreadagain-0.2.3-py3-none-any.whl |
|---|---|
| Size | 50.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
114fc24424ccee5354cbc39721f4080bead343ad802a61d4a661438c113c04d3
|
|
BLAKE2b-256 checksum How to use checksums |
c895bf7d45dd21fc0e713185e33c5d76f9ea2a412c7fa4d73b2b03efd6c1bb5a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 21, 2026.
Transparency log