diff --git a/phase-ends/CURRENT_PHASE.md b/phase-ends/CURRENT_PHASE.md index fecff85675..b35ffc0607 100644 --- a/phase-ends/CURRENT_PHASE.md +++ b/phase-ends/CURRENT_PHASE.md @@ -3386,3 +3386,40 @@ conditional) ยท main-EXE/B9 + GLM/B6 + resident's 14 walls (P30) ยท behemoths B7 **Test: revert the 4 decl lines, re-gate. If it still banks, `recover_integration` should probe whether a stage is NEEDED before applying it** โ€” an unrequested tier escalation is exactly the class R32โ€“R35 exist to catch. + +- **๐Ÿšจ 2026-07-24 (SESSION-18) โ€” THE PROPAGATION "TYPE CAP" IS A MISLABEL. Measured 7/7 CARRY-FIXABLE, + 0/7 actual type problems. This is why a fix Phase 21 already specified was never built.** + `dedup_propagate.compiles_standalone()` returned a bare `False` and the caller filed EVERY failure + under `"overlay-local TYPE (the real cap)"`. Reproducing the compile by hand shows the real cc1 + errors are **undeclared file-scope externs** โ€” the body references `extern` decls that live OUTSIDE + the extracted def block. For `func_80174CB0`: 22 carried externs make it compile **clean** (verified: + cc1 rc=0). It is not a type problem at all; it is the exact gap Phase-27's + `family_remap._carry_macros` closed for file-scope `#define`s, one level over โ€” **extern decls**. + **FIXED (safe, read-only classification):** `compiles_standalone` now returns `(ok, stderr)` and the + skip is classified by ACTUAL cause โ€” `missing file-scope extern (CARRY-FIXABLE): ` vs + `overlay-local TYPE (the real cap)`. R32/R33/R34: a skip that discards its own diagnosis is invisible + work; one that ASSERTS the wrong cause is worse โ€” it redirects every later session. + **FLEET SIZING (`--auto-from ov_SC01_077 --check-only`, touches nothing): 7 skipped, ALL 7 + CARRY-FIXABLE, ZERO genuine type-cap.** + | addr | missing externs | + |---|---| + | 0x8016A73C | ApplyMatrixSV, D_800AE620, RotMatrixYXZ, func_80048EAC | + | 0x80155800 | D_8011F730, func_8001382C, func_80146DB8, func_80146E98 | + | 0x80167540 | func_80146A6C, func_80146C3C, func_801670E4, rand | + | 0x801535F4 | func_8014CC28, func_8014ED28, func_8014FA04 | + | 0x8016F0AC | D_80126B58, func_80165770 | + | 0x80142B2C | func_80142C84, func_80143994 | + | 0x8014FE60 | D_801152A8 | + **โš ๏ธ THE HISTORY MATTERS:** `0x80142B2C`, `0x801535F4`, `0x80155800` are on the **Phase-21 backlog's + "7 callee/data-plumbing capped fns"** list, whose note already read *"a macro-extern-injection (or + canonical-callee-sig embed) frees them ร—134 (~+0.3%)"*. **Phase 21 diagnosed it correctly and it was + never built** โ€” and in the meantime the mislabel told every subsequent session these were the type + wall. A wrong diagnostic label cost this project ~4 phases of a known, mechanical win. + **VALUE LOCKED BEHIND THE CARRY FIX:** these 7 (Phase-21 estimated ~+0.3pp) **plus `func_80174CB0` + itself** (123 ins ร— 138 = 16,974 ins โ‰ˆ **+0.13pp**), so โ‰ˆ **+0.4pp mechanical, ~0 agent tokens**. + **NEXT (spec, deliberately NOT built in this long session โ€” it writes 138 overlay files, the ยง63 + disaster class):** add `_carry_externs` to `dedup_propagate` mirroring `family_remap._carry_macros` โ€” + collect the file-scope `extern` lines matching the identifiers the body references, emit them INSIDE + the lifted `DEFINE_func_*` body (existing macros already carry externs, e.g. `DEFINE_func_80174C60`, + so the shape is established), dedupe against decls the target TU already has, then `--check-only` โ†’ + one gate โ†’ **R22 mandatory**. `func_80174CB0` is banked ร—1 today and is the ready-made test case. diff --git a/src/ov_SC07_006/ov_SC07_006_jr_8015C32C.c b/src/ov_SC07_006/ov_SC07_006_jr_8015C32C.c index c19099729c..2132418ba2 100644 --- a/src/ov_SC07_006/ov_SC07_006_jr_8015C32C.c +++ b/src/ov_SC07_006/ov_SC07_006_jr_8015C32C.c @@ -8728,7 +8728,7 @@ DEFINE_func_80174C80() /* dedup: shared engine-core @0x80174c80 (src/shared) */ // `((s16 (*)(s32,s32,s32))f)(...)` func-ptr cast idiom already used by func_801749C8, // so the canonical s32 prototypes are kept and NEVER redeclared. // * D_80126940/42/44 are already `extern s16` at TU:160-162 โ€” drop the three externs below. -// * Mtx_80174CB0 / Svec_80174CB0 are locally-unique names (== MATRIX / SVECTOR layouts) so +// * MATRIX / SVECTOR are locally-unique names (== MATRIX / SVECTOR layouts) so // they cannot collide with engine_types.h; they may be kept as-is or swapped for // MATRIX / SVECTOR when banking. // * THE OWN-SIGNATURE BLOCKER (the layer under the func_80012ABC one): the TU expands @@ -8745,8 +8745,6 @@ DEFINE_func_80174C80() /* dedup: shared engine-core @0x80174c80 (src/shared) */ #include "common.h" /* --- standalone-only scaffolding (bank-safe: names are unique to this function) --- */ -typedef struct { short m[3][3]; long t[3]; } Mtx_80174CB0; /* == MATRIX, 0x20 bytes */ -typedef struct { short vx, vy, vz, pad; } Svec_80174CB0; /* == SVECTOR, 0x08 bytes */ extern s16 D_80126940; extern s16 D_80126942; @@ -8764,9 +8762,9 @@ extern void func_8012F14C(s32 a0, s32 a1, s32 a2); s32 func_80174CB0(s32 param_1, s32 param_2) { s16 *pv = &D_80126940; - Mtx_80174CB0 mtx; - Svec_80174CB0 vec; - Svec_80174CB0 out; + MATRIX mtx; + SVECTOR vec; + SVECTOR out; *(s32 *)(param_1 + 8) = (s16)((s16 (*)(s32, s32, s32))func_80012C6C)((s32)*(s16 *)(param_1 + 8), (s32)*(s16 *)(param_1 + 0xc), 4); *(s32 *)(param_1 + 0x10) = (s16)((s16 (*)(s32, s32, s32))func_80012C6C)((s32)*(s16 *)(param_1 + 0x10), (s32)*(s16 *)(param_1 + 0x14), 4); diff --git a/tools/dedup_propagate.py b/tools/dedup_propagate.py index 542ce10578..579ee93463 100644 --- a/tools/dedup_propagate.py +++ b/tools/dedup_propagate.py @@ -345,11 +345,11 @@ def compiles_standalone(body_lines): "-fno-builtin", "-Dmips", "-D__GNUC__=2", "-D__OPTIMIZE__", "-Dpsx", "-D_PSYQ", "-D_MIPSEL", "-D_LANGUAGE_C", str(f)], capture_output=True, text=True) if cpp.returncode != 0: - return False + return False, (cpp.stderr or "cpp failed") cc1 = subprocess.run([str(CC1), "-quiet", "-O2", "-G0", "-mips1", "-mcpu=3000", "-mgas", "-msoft-float", "-fgnu-linker", "-o", "/dev/null"], input=cpp.stdout, capture_output=True, text=True) - return cc1.returncode == 0 + return cc1.returncode == 0, (cc1.stderr or "") # ---------------------------------------------------------------- main @@ -462,8 +462,20 @@ def main(): # then rejects any body using an overlay-local type NOT yet promoted to the header. if re.search(r'(\b(struct|union)\s+\w+\s*\{)|(\btypedef\b)', "\n".join(body)): n_local += 1; skipped["inline type def in body"].append(addr); continue - if not compiles_standalone(body): # uses overlay-local types -> can't lift mechanically - n_local += 1; skipped["overlay-local TYPE (the real cap)"].append(addr); continue + ok, why = compiles_standalone(body) + if not ok: + # SESSION-18: this bucket asserted "overlay-local TYPE" for EVERY failure, which is a + # mislabel โ€” the dominant real cause is that the body references file-scope `extern` + # decls that live OUTSIDE the extracted block (func_80174CB0: 22 of them), exactly the + # gap Phase-27's family_remap._carry_macros closed for file-scope #defines. Name the + # causes apart so the queue can be sized honestly (R32/R33). + undecl = sorted(set(re.findall(r"`([A-Za-z_]\w*)' undeclared", why))) + if undecl: + n_local += 1 + skipped["missing file-scope extern (CARRY-FIXABLE): " + ",".join(undecl[:4])].append(addr) + else: + n_local += 1; skipped["overlay-local TYPE (the real cap)"].append(addr) + continue plan.append(dict(addr=addr, src=src, hash=h, body=body, members=members)) if n_local or n_nondef or n_lowreach: