mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-27 05:56:00 -04:00
a5e5ea45ef
ROOT CAUSE of the 0/3 (found by reading the tool's ACTUAL invocation, not by guessing): jtbl_family_bank calls `jtbl_carve <sibling> --func <fn> --like <exemplar_ov>`, and the role-transfer keys on the SUBSEG ROLE (`ov_SC01_077_a` -> `_a`). Its premise — "same family => same span structure" — silently breaks when the exemplar and the sibling host the function in subsegs with DIFFERENT roles, which happens whenever the exemplar has a split the sibling does not. MEASURED: func_8012AAAC lives in `ov_SC01_077_a` (role `_a`) in the exemplar but in the MAIN subseg (role ``) in every sibling. The transfer therefore looked up `ov_SC01_077` — an unrelated SEVEN-table span belonging to entirely different functions — and stamped those starts onto a sibling span holding one table. jtbl_rodata_pads then refused with `consumed 1 rodata .align(s) but 2 pad spec(s) given — table-count drift`, and jtbl_family_bank deliberately does NOT treat that error as isolate-fixable, so all 137 siblings returned a bare `gate-fail` with the cause discarded. THE FIX: transfer only when the exemplar's subseg for THIS FUNCTION has the sibling's role; otherwise derive the span from the sibling's own carve (which was already computing it correctly). Fail-open is not acceptable here — a wrong table set corrupts the image, so the guard defaults to local derivation. MEASURED RESULT: the 3-member probe goes 0/3 -> 3/3 BANKED. R22 clean-fleet: extract-all 139/139, check-all 140 passed / 0 failed. Two earlier hypotheses were tested and are recorded honestly in CURRENT_PHASE.md: the sibling call-site casts (real conflict, fixed, byte-neutral — but NOT the blocker) and my own carve-alone test (which fails by construction for this shape, because a stub object does not emit the table its 2-entry spec describes — the tool splices the body BEFORE building, so its path is the valid one).