Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .claude/board/EPIPHANIES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## 2026-07-07 — E-OCR-LINEFEED-1 — the typographic line feeding lands: `LSTMRecognizeWord`'s band transcoded, position invariance PROVEN — 3F₂'s boundary #2 is closed
**Status:** FINDING (falsifier green on the roomy stacked fixture; `tesseract-ocr`, tested)

**The transcode** (tesseract-rs `4eb73f9`): `recognize_page_makerow` now feeds each row exactly as `Tesseract::LSTMRecognizeWord` does (`linerec.cpp:239-246`) — the row's ink bounding box EXTENDED (never shrunk) to `[baseline + descdrop, baseline + xheight + ascrise]`, baseline evaluated at the box x-midpoint from the wave-2 parallel fit (straight case `m·x + parallel_c`), then `GetRectImage`'s `kImagePadding = 4` pad on ALL sides + clip to the image (`imagedata.h:39`), cropping x AND y. This replaces the raw `[min_y, max_y]` expand_rows band — E-OCR-LINEFINDER-1's documented boundary #2. Semantics note: in LSTM mode the real pipeline recognizes a whole TEXTLINE per `LSTMRecognizeWord` call (the row's words are merged first), so feeding the row box IS the real feeding — no per-word segmentation gap here.

**The falsifier (position invariance):** identical ink at different page positions must produce pixel-identical crops → identical text. First run on the legacy tight fixture FAILED the equality — and the debug bands showed exactly why: both rows carry IDENTICAL typographic parameters (xh 24.33 / asc 12.17 / desc −12.17, identical extensions relative to baseline), but the 24×88 layout clips the padded band at the image TOP for row A and the BOTTOM for row B (57 vs 45 tall) — which is *faithful* `GetRectImage` edge clipping, not a transcode defect. On a roomy re-layout (32 px margins / 64 px gap, same tile) both rows crop to 32×58 and recognize to IDENTICAL text. The E2E anchor asserts the equality (`stacked_page_finds_two_deterministic_rows`, roomy fixtures only).

**Transferable lesson:** a position-invariance falsifier needs a fixture whose typographic band + padding CLEARS the image edges — edge-tight fixtures test the clip path instead (worth keeping, separately). Generator banked (`tesseract-rs/.claude/harvest/oracles/gen_page_fixture.py`, tile embedded verbatim; its tight-layout arm byte-reproduces the original 24×88 fixture). Remaining documented approximations in the page path: blob source (island-in-hole, E-OCR-LINEFINDER-1 boundary #1) + straight-baseline (`row->base_line()` consults the quadratic spline where one exists). Gates: 79/79 lib tests, clippy both feature sets, `qLLiy,,` regression intact. Next: P6 golden corpus. Plan `tesseract-rs/.claude/plans/pdf-to-text-ocr-v1.md`. Branch `claude/happy-hamilton-0azlw4`.

## 2026-07-07 — E-OCR-LINEFINDER-1 — 3F₂ COMPLETE: the REAL makerow line finder replaces the projection approximation — CC pixel counts (no outline tracer needed) + filter_noise_blobs byte-parity 14/14 + the full composition wired
**Status:** FINDING (leaves byte-parity proven; composition functional with two DOCUMENTED boundaries; `tesseract-ocr`, tested)

Expand Down