Refines the OCR line-item in the v2 umbrella (#13) with a concrete path now that the artifact infrastructure (commit e2b7342) is in place.
The gap
Scanned PDFs have no extractable text. PyMuPDF returns empty pages → zero chunks → invisible to both keyword and chunk-level semantic search. Only the item-level SPECTER2 embedding (title + abstract) surfaces them at all, and that relies on Crossref/GROBID having given us an abstract — which usually fails for scans.
Plan
- New CLI: `grimoire artifacts build --kind ocr_text [--since YYYY-MM-DD] [-j N]`.
- Walks items where:
- `primary` artifact exists, and
- `extract.pdf.has_extractable_text()` returns False (body is empty/degenerate), and
- no `ocr_text` artifact yet.
- Each worker thread:
- Pulls the primary CAS blob.
- Runs ocrmypdf or pure Tesseract over it — the plan chose `ocrmypdf` (plan §4 tech-stack row).
- Stores the plain-text result as the `ocr_text` artifact (source: `tesseract-` or `ocrmypdf-`).
- Extend `index.py` so when chunking a PDF item:
- Prefer `ocr_text` artifact over raw PyMuPDF extraction when the latter is empty.
- Reuse the existing chunker; no schema change (page numbers become approximate/synthetic for scans).
- Bonus: add a soft `metadata_confidence` reduction when the source is OCR so the dedup tier-4 is more cautious.
Acceptance
Notes
- The `ocrmypdf` dependency is heavy (pulls in Tesseract, poppler). Keep it in an optional extra (`[ocr]`) so it's not mandatory for users who don't need it.
- Processing cost is bounded per-scan and embarrassingly parallel — user has explicitly said processing isn't a concern.
- This closes the "invariant 7 (paper + DOI ⇒ venue)" soft-failure path for a lot of items where OCR could have provided a first-page abstract for Crossref backfill — worth measuring on the real library once landed.
Once this ships, update the corresponding checkbox in #13.
Refines the OCR line-item in the v2 umbrella (#13) with a concrete path now that the artifact infrastructure (commit e2b7342) is in place.
The gap
Scanned PDFs have no extractable text. PyMuPDF returns empty pages → zero chunks → invisible to both keyword and chunk-level semantic search. Only the item-level SPECTER2 embedding (title + abstract) surfaces them at all, and that relies on Crossref/GROBID having given us an abstract — which usually fails for scans.
Plan
Acceptance
Notes
Once this ships, update the corresponding checkbox in #13.