diff --git a/.claude/board/EPIPHANIES.md b/.claude/board/EPIPHANIES.md index 2d2117f2..cb7512d7 100644 --- a/.claude/board/EPIPHANIES.md +++ b/.claude/board/EPIPHANIES.md @@ -1,3 +1,21 @@ +## 2026-07-07 — E-OCR-MAKEROW-3 — 3E wave 3: the x-height chain byte-parity 4/4 — the fixed ruff (#57) made the `Textord::` methods harvestable first-class, closing the make_rows textline stage +**Status:** FINDING (byte-parity proven vs source-compiled C++ x-height chain; `tesseract-ocr`, tested) + +The x-height stage — `Textord::compute_block_xheight` / `Textord::compute_row_xheight` (the two out-of-line class methods that were INVISIBLE to `walk_free_functions` until ruff #57 landed the class-qualified capture; the refreshed manifest `makerow-callgraph-v3.txt` shows their full dispatch edges) + `compute_xheight_from_modes`, `compute_row_descdrop`, `correct_row_xheight`, and the `makerow.h` inlines (`get_min_max_xheight`/`get_row_category`/`within_error_margin`) — lands on waves 1-2 (tesseract-rs `4faae42`). `ToRow` gains xheight/ascrise/descdrop/evidence/all_caps/rep_chars_marked; `ToBlockCtx` gains xheight. Per-subexpression precision transcribed (`median()`→f32 narrowing, asc_frac 0.5f, `kXHeightCapRatio` double). + +**Byte-parity 4/4** (2 seeds × clean/noise) vs the wave-2 oracle extended with the x-height chain transcribed VERBATIM against the real compiled `STATS`: the new STAGE7 (per-row xheight/ascrise/descdrop/category + block xheight) is byte-identical AND every wave-2 STAGE1-6 prefix line is unchanged (the additive-only bar held). PARITY PINs (per E-OCR-MAKEROW-2): `mark_repeated_chars` reduces to a documented no-op on the plain-tuple carrier; `joined_to_prev` always false. No new sort/nth_element → no new tie-order pin. 68/68 lib tests (5 new). **The ruff→port loop closed the circle:** the harvest gap fixed in ruff #57 was the exact prerequisite for this wave — the Textord:: methods it exposed ARE this wave's port targets. + +**The make_rows textline formation is now COMPLETE through x-height** (waves 1+2+3: STATS/DetLineFit/occupation math → row assignment + cleanup → x-height). Remaining before the parity line finder replaces `seg-approx`: the straight-baseline hookup (`textord_straight_baselines` path — the parallel fit already computed) + the make_rows→line-box wiring (3F₁ PSM_SINGLE_LINE, 3F₂ PSM_SINGLE_BLOCK). Then P6 golden corpus. Note: run INLINE on the main thread (both delegated wave-3 agents were stopped mid-run). Plan `tesseract-rs/.claude/plans/pdf-to-text-ocr-v1.md`. Branch `claude/happy-hamilton-0azlw4`. + +## 2026-07-07 — E-OCR-MAKEROW-2 — 3E wave 2: the makerow row-assignment + cleanup chain byte-parity 4/4 — and the TIE-ORDER finding (unspecified in real Tesseract, pinned in the probe) +**Status:** FINDING (byte-parity proven vs source-compiled C++ leaves; `tesseract-ocr`, tested) + +The chain `assign_blobs_to_rows`/`most_overlapping_row` (pass semantics, skew interpolation, the merge branch's iterator bookkeeping mapped to indices) → `fit_parallel_rows`/`fit_parallel_lms` (wave-1 ConstrainedFit) → `delete_non_dropout_rows` (the proven occupation leaves wired into the real prune decision) → `expand_rows`/`adjust_row_limits`/`compute_row_stats` → `make_rows` + REAL `compute_page_skew` lands on the wave-1 leaves (tesseract-rs `ad71e01`), with `ToRow`/`ToBlockCtx` as documented working-set carriers (TO_ROW ctor/add_blob/set_limits verbatim, `blobbox.cpp:685-766`). **Byte-parity 4/4** (2 seeds × clean/noise, per-stage f32-hex dumps) vs an oracle compiling `statistc.cpp`/`detlinefit.cpp` from source. + +**The transferable finding:** real Tesseract's `blob_x_order` sort and `row_spacing_order` `nth_element` leave TIE ORDER UNSPECIFIED (qsort/introselect semantics) — and `TO_ROW::add_blob`'s expansion is ORDER-DEPENDENT, so two faithful shells can diverge on equal-key inputs while both being "correct". The probe pins identical total orders on BOTH sides (full box tuple; spacing→intercept→min_y), documented in-code as PARITY PINs. Any future textord leaf with a sort/nth_element must get the same treatment up front. (Wave note: the porting agent was stopped mid-run; the orchestrator finished from its working tree — state was 90% complete and correct, the last 10% was exactly this tie-order class.) + +Next: 3E wave 3 (the xheight chain — `compute_block_xheight`/`compute_row_xheight`/`correct_row_xheight` + straight-baseline fallback), now harvestable FIRST-CLASS: ruff #57 (merged) made the out-of-line `Textord::` methods visible with class-qualified dispatch edges. Then the parity line finder replaces `seg-approx`, then P6. Plan `tesseract-rs/.claude/plans/pdf-to-text-ocr-v1.md`. Branch `claude/happy-hamilton-0azlw4`. + ## 2026-07-07 — E-HOTPLUG-MIGRATION-1 — the generic hot-plug pattern is the migration target for ALL consumers; migration doc is board discipline **Status:** RULING (operator, 2026-07-07; shipped OGAR #174/#175 + lance-graph #658 + tesseract-rs #13/#14)