Read once, never again — self-describing files so AI agents stop re-parsing.
Project description
donotreadagain (dnr)
Read once, never again. Embed a faithful, signed AI transcript into each expensive-to-parse file's own metadata, so AI agents stop re-OCR/re-parsing the same PDF, image, scan, or audio every time.
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
dnr reads a file once, then writes a verbatim transcript + structured metadata into the file's own native metadata slot as a signed JSON record — the file becomes self-describing. 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.
The second view is the win:
| first view (re-parse) | second view (cached) | |
|---|---|---|
| born-digital PDF | ~1.4 s (pypdf) | ~60 ms — ~22× faster |
| 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."
Demo
$ dnr ingest contract.pdf # transcribe once → sign → embed in the file
ingested contract.pdf [in-file]
method=text-extract transcriber=pypdf
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 inside contract.pdf — move it, email it, hand it to another agent, and the cached transcript travels with it.
Quickstart
Requires Python 3.10+ (its stdlib includes the sqlite3 used to read the index — one dependency covers both).
# run with no persistent install:
uvx --from donotreadagain dnr <cmd>
# or install:
pipx install donotreadagain # or: pip install donotreadagain
dnr ingest report.pdf # transcribe once (local) → sign → embed in the file
dnr read report.pdf # print the cached transcript (verified), or fall back
dnr index ./case-folder # build .dnr.db
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 = derived, regenerable
┌────────────────────────────┐ harvest ┌────────────────────────────┐
│ signed dnr record │ ───────▶ │ fixed table + FTS5 search │
│ content_hash · transcript │ │ path · tags · transcript … │
│ provenance · fields · sig │ └────────────────────────────┘
└────────────────────────────┘ ▲ query via sqlite3 — no dnr install needed
▲ transcribe · sign · embed once (expensive)
Where the record lives (no sidecar files):
- In-file for formats with a metadata slot — PDF→XMP, MP3→ID3, PNG→iTXt, JPEG→APP segment. Pixels/bytes-of-content untouched (
content_hashinvariant), so the transcript travels with the file (move it, email it — it's still there). - db-only in the folder's
.dnr.dbfor formats with no slot yet (docx, …), or via--no-embedfor evidentiary originals you must not modify (file left byte-identical). - Nothing for already-readable text (
.txt/.md/.csv) — an agent just reads it.
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: pypdf / Whisper / python-docx) ordnr record(agent supplies a vision transcript). dnr owns no model — the transcript is an input from whoever's best placed. - Query a folder:
dnr query <folder>combines--match(FTS, Korean/CJK ok) ∩--tag a,b∩--since/--until∩--where; plus--any(OR sweep),--dedup,--context(KWIC),--format json. Save composed queries with--save/--use; accumulate labels withdnr tag. - Agents onboard once: point an agent at a dnr folder and it fetches SKILL.md once — then it knows dnr everywhere.
dnr initjust ensures a signing key; nothing is written into your folders.
Design principles
- 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.1, pre-release. 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.- Not yet published to PyPI; a standalone binary for Python-less environments is future work.
See vision.md (design) · spec/dnr-0.1.md (spec) · 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.
License
MIT © 2026 june lee
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file donotreadagain-0.1.0.tar.gz.
File metadata
- Download URL: donotreadagain-0.1.0.tar.gz
- Upload date:
- Size: 75.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
68d751129f3187c97a55917e52a215cd5e3dd70d6e81265631d78f0fdf0346c0
|
|
| MD5 |
a28361f6900b34e2ab11f6cdc84ad37f
|
|
| BLAKE2b-256 |
c785d5516199863e856cc189eb265303adce81a16c6a6e11119df6107918931e
|
File details
Details for the file donotreadagain-0.1.0-py3-none-any.whl.
File metadata
- Download URL: donotreadagain-0.1.0-py3-none-any.whl
- Upload date:
- Size: 40.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
822b3f31e6267d7ceeb28b52ea4fdb9ebf9b12cdcbcec9e637d45c7c7e1b2feb
|
|
| MD5 |
faa3936459733ce604d19d5ec876ce06
|
|
| BLAKE2b-256 |
47e66cd3ab6333b60b6f59408a1c67e22873a17fb4beb4722f1fb73d8582831c
|