v2.22.0 — OCR engine → Tesseract + Harbor internal-path
Highlights
OCR engine → Tesseract (#1033)
The ingest force_full_page_ocr re-run converter (garbled/scanned docs) now defaults to Tesseract (deu+eng) instead of docling-EasyOcr. A 148-document eval over the flagged corpus showed it clearly better: 111/148 improved, only 8 regressed, quality-gate drop 0.68→0.30, no speed penalty. Switchable via RAG_OCR_ENGINE (tesseract|easyocr), and fail-safe — it verifies the tesseract runtime (CLI + deu/eng traineddata, or the tesserocr binding) and falls back to EasyOcr if absent, so ingest never crashes. Design/outcome: docs/design/ocr-engine-eval.md.
Infrastructure — Harbor push/pull from the home LAN (#1032)
Root-caused (WAN hairpin via the public IP, not MTU — confirmed by a 0-retransmit re-measurement) and fixed with a per-node /etc/hosts pin to the internal HAProxy path → ~72 → ~200 Mbit/s (100 MB push 11 s → 3 s). Idempotent Ansible playbook in private_k8s. Analysis: docs/TECHNICAL_DEBT.md I1 + public_k8s/docs/harbor-slow-from-home-lan.md.
Docs (#1034)
README, FEATURES, both changelogs, eval + worker-split docs swept.
Deployed to the household: backend:2026-07-23-ocr-tesseract-twin (verified: tesseract runtime present, twin plugin loaded).