Skip to main content

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.

tests license python · status: v0.1, pre-release


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_hash invariant), so the transcript travels with the file (move it, email it — it's still there).
  • db-only in the folder's .dnr.db for formats with no slot yet (docx, …), or via --no-embed for 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.db directly with ambient sqlite3 (the db's _dnr_readme table self-describes).
  • Transcribe (producer): dnr ingest (local: pypdf / Whisper / python-docx) or dnr 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 with dnr tag.
  • Agents onboard once: point an agent at a dnr folder and it fetches SKILL.md once — then it knows dnr everywhere. dnr init just 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.db and 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

donotreadagain-0.1.0.tar.gz (75.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

donotreadagain-0.1.0-py3-none-any.whl (40.8 kB view details)

Uploaded Python 3

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

Hashes for donotreadagain-0.1.0.tar.gz
Algorithm Hash digest
SHA256 68d751129f3187c97a55917e52a215cd5e3dd70d6e81265631d78f0fdf0346c0
MD5 a28361f6900b34e2ab11f6cdc84ad37f
BLAKE2b-256 c785d5516199863e856cc189eb265303adce81a16c6a6e11119df6107918931e

See more details on using hashes here.

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

Hashes for donotreadagain-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 822b3f31e6267d7ceeb28b52ea4fdb9ebf9b12cdcbcec9e637d45c7c7e1b2feb
MD5 faa3936459733ce604d19d5ec876ce06
BLAKE2b-256 47e66cd3ab6333b60b6f59408a1c67e22873a17fb4beb4722f1fb73d8582831c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page