How Nammu deals with a case: A 5-level processing pipeline
Every page of every legal document you upload is classified and routed to the most appropriate extraction engine — in parallel, without blocking your workflow. Here is how it works.
Inventum P5
Engineering · Galictis-Legal
July 10, 2026
7 min read
When a lawyer uploads a legal expediente to Nammu, something happens before any AI analysis runs: every single page is classified and routed to the extraction engine best suited to handle it. Not all pages go through the same process. Not all documents need the same treatment. This is the story of that classification system — the 5-level processing pipeline.
The problem with legal documents
Costa Rican legal expedientes are not clean. A single case file might contain a typed resolution from 2024 (clean digital text), a handwritten certified copy from 2018 (scanned image), a cadastral map or property diagram (a visual artifact entirely), and a notarized act photocopied three times over (degraded scan at varying DPIs). Each of these requires a fundamentally different extraction strategy.
The naive approach — run every page through the most powerful engine (AI vision) — is technically sound but economically and temporally absurd. A 140-page expediente processed entirely through Azure GPT-Vision would take minutes and cost orders of magnitude more than necessary. Most pages are perfectly readable with much simpler tools.
The Nammu pipeline solves this with a route-once classification: each page is inspected once, assigned a complexity level, and sent to exactly the right extractor.
The five levels
Before any text is extracted, a lightweight PyMuPDF pass examines every page — no rendering, no OCR — and measures four signals: word count, image area ratio, text block area, and the presence of legal visual trigger keywords (plano, croquis, mapa de desalojo). From these, each page is assigned one of five complexity levels.
L1
Digital text
Fast PyMuPDF pass
route
L2
Clean text
Legal boilerplate strip
route
L3
OCR 200 DPI
Tesseract standard
route
L4
OCR HD 300 DPI
Multi-PSM cascade
route
L5
Vision AI
Azure GPT-Vision
Each page is classified once and routed to exactly one level — not run sequentially through all five.
Embedded digital text
PyMuPDF · fitz_text
Pure digital PDF pages with ≥ 50 words. Court resolutions, typed motions, and modern filings land here.
Fastest path — no rendering, no OCR. Sub-second per page.
Clean digital text
fitz_clean · boilerplate strip
Mixed-layout pages with ≥ 30 words. Strips legal boilerplate, repeated headers, and footer noise from structured documents.
Early legal analysis fires after this level completes — while L3–L5 still run.
Standard OCR
Tesseract · 200 DPI render
Scanned pages with 10–29 words or mixed ratios. The workhorse for most physical documents.
Renders each page to 200 DPI PNG then runs Tesseract. Handles the majority of older expediente pages.
High-density OCR
Tesseract HD · 300 DPI · multi-PSM cascade
Heavy scans with < 10 words and ≥ 50% image area. Degraded photocopies, old certified copies, faxed documents.
Tries multiple Tesseract page segmentation modes in sequence. Optional local OCR fallback for paid tiers.
Vision AI
Azure GPT-Vision · ollama_vision fallback
Diagrams, cadastral maps, floor plans, and anything a trigger keyword identifies as a visual artifact.
Runs on a dedicated vision thread pool in parallel with L1–L4. Tier-gated and capped per document.
Route-once: why not a cascade?
A common alternative is a full cascade: try L1, if it fails try L2, then L3, then L4, then L5. This guarantees maximum coverage but at a steep cost — every page runs through up to five passes. For a 38-document expediente, this is the difference between a 3-minute processing time and a 20-minute one.
The route-once design works because the page classifier is accurate for the vast majority of pages. The signals — word count, image ratio — are strong predictors of which extractor will succeed. The only cases that need a second chance are deliberate edge cases, and for those, the pipeline uses targeted promotions.
Targeted promotions: smart fallbacks
When classification is wrong — it happens — the pipeline has four surgical fallback rules rather than a full retry cascade.
| Trigger | From | → To | When |
|---|---|---|---|
| L1 Blank → 0 words after extraction | L1 | L3 | Always |
| L5 vision disabled by tier or env | L5 classified | L4 | Tier fallback |
| Any L1–L4 page still at 0 words | Any | L5 | Paid tier + cap |
| L4 < 50 words extracted | L4 | Ollama OCR | Tier + env flag |
The most important of these is the L1 Blank → L3 promotion, added in June 2026. Some scans report near-zero image area to PyMuPDF (the metadata says the page is almost blank) while actually containing dense text. The classifier assigns them L1, the fast digital reader finds nothing, and they would silently fall through. The promotion rule catches these: any L1 page that still has zero words after extraction gets one OCR attempt at L3 before being flagged.
Parallelism: levels within a document
Within a single document, levels do not run sequentially. L5 vision pages are submitted to a dedicated thread pool immediately — they start while L1–L4 pages are still being processed. Within each level, all pages at that level run in parallel on a CPU pool sized to the host hardware.
The coordinator waits for each CPU level batch to complete before moving to the next (so L1-Blank promotions can be decided after L1 finishes), but L5 is fully non-blocking and may complete before, during, or after the CPU work.
What you see in the UI: progressive readiness
You do not wait for all five levels to finish before you can work. The UI updates as each level batch completes, following a readiness progression:
TEXT_READY
You can start asking questions on extracted text immediately
ENRICHED
Cleaned text available; early legal analysis begins in background
ENRICHED
First OCR pass complete; scanned pages coming in
OCR_DONE
High-density scans processed; all physical pages captured
COMPLETE
Diagrams, maps, and floor plans fully understood
This means that for a document with mostly digital text, you can be asking questions and running analysis within seconds of uploading — while the pipeline quietly handles the harder scanned pages in the background.
Tier policy and L5 access
L5 Vision AI is the most powerful and most expensive extractor. Access is gated by subscription tier with a per-document page cap:
| Tier | L5 Vision | L5 Promotion | Cap / doc |
|---|---|---|---|
| Beta | ✓ | ✓ | 20 pages |
| Pro | ✓ | ✓ | 20 pages |
| Advanced | ✓ | ✓ | 50 pages |
| Enterprise · Firm | ✓ | ✓ | 100 pages |
The cap prevents a single large document (some code compilations run to 400+ pages) from consuming an entire session budget on vision calls. Pages that exceed the cap are flagged in the document metadata as no_text_pages — they are never silently dropped.
Content-loss guarantee
Legal expedientes must not silently lose pages. If a page reaches the end of the pipeline with zero extracted words — after all applicable promotions — it is logged at WARNING level, recorded in the assembled document JSON, and surfaced in the UI. You will always know which pages could not be read and why.
What comes next
The pipeline was designed to be extended. The two most significant open items are:
- Auto-escalation from L3 to L4 for pages that pass OCR but produce low-confidence text — currently requires manual L4 designation.
- Structured extraction at L2 for highly templated documents (notarized acts, standard resolutions) where field-level parsing would add more value than raw text.
The 5-level pipeline is not the most technically glamorous part of a legal AI product. But it is the foundation everything else depends on. Get the extraction wrong and no amount of downstream intelligence fixes it. Get it right and the system reads documents the way a careful paralegal would: knowing which pages need a second look, and never pretending a hard page is an easy one.
Want to see this in action on your cases?
Request early access and we will walk you through a live processing session on real expedientes from your practice area.
Request a demo →