docs(phase-20): T6 batch-1 recovery — diagnose the loose-typing call-graph wall (gate cap)

- byte-verified: the 33 wave drafts that match_one-MATCH but fail the whole-binary gate are the
  loose-typing wall in the CALL GRAPH (a callee declared with conflicting types across overlay
  sites -> draft extern hits in-TU 'conflicting types'); match_one over-predicts (standalone +
  masks jal/hi/lo). All recovery levers fail (sig_unify/canon_draft_decls/fix_arity/no-proto/
  strip-externs); the only fix is per-site fn-ptr casts (SS17a) = Phase-21 recovery tooling
- diagnostic lesson: a failed in-TU build leaves a STALE .o (trust the whole-binary SHA, not objdump)
This commit is contained in:
Drew T
2026-06-21 01:12:18 -06:00
parent 9991e4d6be
commit dab6ccb96f
+1 -1
View File
@@ -22,7 +22,7 @@
- [ ] **T5 — Ghidra-C regen for fresh wave targets** · xHigh + **R23/R29**
Stop MCP → `DecompileFunctions.java` over fresh tractable reach-134 stubs → restart → **pause + prompt `/mcp`** → `get_binary_info` (G2).
- [~] **T6 — Enriched waves (batch 1 done)** · Ultracode
Wave on 48 cached reach-134 ≤90-ins targets → **41/48 match_one MATCH (85%)**. Whole-binary gate: **8/41 banked** (7 ×134 + 1 local), fleet **58.35%→58.63%** (+0.28%), dedup 1494→1501, check-all 136/136. **KEY FINDING (R14/P9): the match_one→gate gap is ~80% this batch — EXTERN-CODEGEN-COUPLING** (a callee's *declared* sig changes the call codegen, so match_one with the draft's externs ≠ the gate with the overlay's decls). The 33 lost are byte-correct vs the WRONG externs → recoverable by a **callee-extern-canonicalize pass (NOT def-sig — sig_unify regresses)** = Drew's backlog item 2, the real cap. **The 7 DIFFs gave gold gcc diagnoses (do T3c/T4 for free):** T3c store-vs-load `func_8014F2E0`/`func_80150528` CONFIRMED unsteerable (sched.c); §10 hoist-vs-remat `func_80149374`/`func_801493D0`; IV-combine `func_80177AD4`; hoisted-invariant order `func_80177F84`; `func_80161A90` = **-O1** (build-infra, needs an -O1 split like -O0).
Wave on 48 cached reach-134 ≤90-ins targets → **41/48 match_one MATCH (85%)**. Whole-binary gate: **8/41 banked** (7 ×134 + 1 local), fleet **58.35%→58.63%** (+0.28%), dedup 1494→1501, check-all 136/136. **KEY FINDING (byte-verified, R14/P9): the 33 lost are the LOOSE-TYPING WALL IN THE CALL GRAPH.** A callee (e.g. `func_80153C74`) is declared with CONFLICTING types at different overlay sites, so the draft's extern hits `conflicting types` in-TU (a COMPILE error, not a byte miss). match_one over-predicts because it compiles STANDALONE (draft's own externs) and masks jal/%hi/%lo. **ALL recovery levers fail:** `sig_unify`/`canon_draft_decls` impose a single "canonical" that's wrong for some sites; `fix_arity_callers` (0, not arity); no-proto externs (0, incompatible with the overlay's narrow decls); strip-externs (0, implicit-int ≠ target). **The ONLY fix is per-site function-pointer casts** (`((ret(*)(args))func_X)(…)`, §17a) = **Drew's backlog item 2 (auto call-site-cast recovery), the precisely-diagnosed Phase-21 cap.** Diagnostic lesson: a failed in-TU build leaves a STALE `.o` (objdump misleads — trust the whole-binary SHA, not the disasm). **The 7 DIFFs gave gold gcc diagnoses (do T3c/T4 for free):** T3c store-vs-load `func_8014F2E0`/`func_80150528` CONFIRMED unsteerable (sched.c); §10 hoist-vs-remat `func_80149374`/`func_801493D0`; IV-combine `func_80177AD4`; hoisted-invariant order `func_80177F84`; `func_80161A90` = **-O1** (build-infra, needs an -O1 split like -O0).
**Optional / conditional (decide live, else → Phase 21):** `-O0` ×134 rollout (only if T3a cracks `%lo`); the 28 giants (deferred to a focused Phase-21 deep session).