Skip to content

Architecture

Nine stages, each a file-to-file transform. You can stop after any of them, edit the intermediate JSON by hand, and resume — which matters because taste is involved and you will want to intervene.

graph TD
  A[PDF / EPUB / Markdown] --> B[1. ingest]
  B --> C[2. clean]
  C --> D[3. triage]
  D --> E[4. concepts]
  E --> F[5. verbalize]
  F --> G[6. elaborate<br/><i>the only model call</i>]
  G --> H[7. plan]
  H --> I[8. render]
  I --> J[9. lint]
  J --> K[audio.md · study.md<br/>cards.json · manifest.json]

The one decision that shapes everything

Stages 1 to 5 and 7 to 9 contain no model call at all. Numbers, names, structure, timing, spacing and retrieval placement are code, because they are the parts that can be tested. The model is confined to stage 6, and to the four things that are genuinely writing problems: explaining a term, finding a concrete image, saying why a claim follows, drawing an analogy.

The further the model is from the numbers, the fewer ways there are for it to quietly corrupt them. And what it does write is checked: every number in a generated sentence must appear in the sentences it was written from.

This is also why the project is usable with no API key at all. --local runs everything except stage 6 and reports what each task degraded to.

Ground rules

These hold across the codebase and are worth knowing before reading it.

Every artefact is re-derivable, and every ID is a content hash. No counters, no UUIDs. The same input produces the same block IDs and the same beat IDs, so caches hit, diffs are readable, and mimem explain can point at a beat from last week's run.

Nothing vanishes silently. Every dropped block is in the drop report with the rule that authorised it. Every beat the duration budget cut is in manifest.json and in study.md's appendix. Over-deletion is the failure mode that loses content invisibly, and this is the defence against it.

A missing check never looks like a passed check. Concreteness scores say whether they came from measured norms or a morphological guess. Groundedness verdicts are None when unverified, never True. This rule has teeth: it is why several things in the codebase are more verbose than they would otherwise be.

Code names the rule it implements. A comment reading # SEG-01 points at a paragraph of the design rules, which points at a finding in the knowledge base. Grep for a rule ID to find everything that touches it.

The linter is the acceptance test. Ninety-odd rules, a third of them mechanically checked today, each with a passing and a failing fixture. mimem build exits non-zero on any error, so a bad script cannot be emitted quietly.

Layout

src/mimem/
  ir/          Block, Span, Concept, Beat, Script — the data model, pydantic throughout
  ingest/      one adapter per format; nothing downstream knows the source format
  clean/       dehyphenation, page furniture, reading order, sentences, sections
  triage/      keep / compress / transform / drop, with a reason for every decision
  concepts/    extraction, difficulty and importance scoring, the editable registry
  verbalize/   numbers, units, citations, symbols — everything that must not be a model
  llm/         transports, task prompts, schemas, cache, cost control
  verify/      the grounding gate: numbers, years, names, directions
  elaborate/   stage 6 orchestration and its degradation paths
  plan/        beats, segmentation, the spacing scheduler, the duration budget
  render/      audio.md, study.md, cards.json, manifest.json
  lint/        text rules and script rules, the acceptance test

Where the interesting problems are

If you are looking for something to work on, these are the parts with real depth rather than plumbing:

The spacing scheduler

plan/spacing.py. Place n exposures of k concepts on a fixed timeline so intervals are increasing, roughly geometric, never under three minutes, and near each concept's own material. Greedy with a repair pass, and property-tested with hypothesis.

Reading order

ingest/pdf.py. Two-column PDFs, headings that straddle the gutter, manuscripts with line numbers welded into words. Every fix here came from a real paper breaking.

Verbalization

verbalize/. "0.05 and 1.50 V" has to become speech without losing the "and" or the "1". Units, ranges, scientific notation, statistics, model designations, Greek.

The grounding gate

verify/grounding.py. The direction check is the interesting one: a claim that reverses the paper's sign reads perfectly and is the only failure you cannot catch by ear.

Next

What each stage does   Adding to it   The plan