The problem
Title work runs on scanned public records: deeds, mortgages, liens, plats, closing letters. The text has to be verbatim, and the numbers most of all. A recording number, a bearing in a metes-and-bounds description, or a book/page reference that is one digit off is worse than useless.
Design premise
LLM vision (Claude, GPT) is good at prose, structure and reading order, but unreliable on numbers. It normalises,
rounds and "fixes" digits that have no linguistic context to constrain them. Pixel OCR (Tesseract, AWS Textract)
is worse at layout, but it doesn't invent numbers. So: prose and structure from the LLMs, numeric fields from
the deterministic engines, and a reconcile step over the disagreements.
Pipeline
RenderPDF page → high-DPI PNG (poppler)
ExtractTesseract · Textract · Claude · GPT, cached by content hash
AlignToken alignment to the cleanest engine, with moved-block repair
VoteMajority over normalised keys, with ID-aware glyph folding
VerifyDomain checks catch what voting can't
Details that matter
- Moved-block repair. Engines linearise a 2-D page differently. Two-column headers and marginal stamps land in different places. Plain alignment turns a moved run into local noise. A repair pass then refills gaps from tokens the engine did read, just somewhere else on the page.
-
Glyph folding only where it's safe. Identifier-shaped tokens fold ambiguous glyphs, so
1-2009-002893andI-2009-002893vote together. Plain words are only case- and punctuation-folded. "Section" must never become "5ect10n". - Domain verifiers. Pure functions over the transcription: instrument-number grammars, section/township/range calls that must be possible, and years that must agree with their own recording date. Metes-and-bounds closure and transfer-tax ratios are on the list. The rules are state-specific, starting with Oklahoma.
- Repeatable runs. LLM APIs aren't bit-reproducible even at temperature 0. A content-addressed cache makes a run repeatable, so reconcile logic can be tuned without spending tokens.
Output
One clean text file per document, plus a .review.txt listing exactly where a human should look:
weak votes and verifier findings. The goal isn't to replace review. It's to point the reviewer at the few places that need it.