Commit Graph

612 Commits

Author SHA1 Message Date
Drew T d2b48b7680 feat(phase-30): tools/o0_subsplit.py — the T2 carve-within-a-carve driver; +3 banked in ov_SC03_015
Promotes the proven probe (commit:1266) into a real tool, and validates it FIRST-TRY on a
fresh overlay.

tools/o0_subsplit.py <ov> --lo <vram> --hi <vram>:
  - derives the range's contents from the SOURCE ANCHORS (overlay_src_split.parse_overlay_c:
    `asm` = unmatched stub, `define`/`def`/`nonmatch` = already matched), NEVER from an asm
    scan -- a matched fn emits no .s, which is exactly the blindness that made the range look
    like a clean contiguous run (SS126 / SS124's shape);
  - computes the -O0 bound as (address range MINUS already-matched bodies) and emits ONE
    sub-region per maximal run of unmatched anchors (K matched islands => K+1 regions);
  - names each `<ov>_o0<letter>` picking free suffixes, so the widened Makefile glob selects
    them; refuses loudly if it runs out or if the range spans >1 object or is already -O0;
  - honours the one-carve-per-region law (forces a cut at every already-banked jr in the
    object) and reuses jr_isolate_all's plan/build_new_config/ascending-unique validation
    verbatim, so carve-repoint + source-repartition stay on the proven path;
  - warns (does not refuse) when a stub in an -O0 run lacks the frame-pointer prologue --
    the byte-gate is the arbiter, not the heuristic.

VALIDATION on ov_SC03_015 (untouched by the manual probe): the tool independently derived the
SAME structure found by hand on ov_SC03_014 -- 2 matched -O2 islands (func_80184440,
func_801848E4), 2 -O0 regions (8 + 7 fns), same 5 cuts. Sub-split -> BYTE-IDENTICAL. Then 3
drafts, each global DERIVED FROM THAT OVERLAY'S OWN ASM (%hi operand) rather than copied:
3/3 match_one --o0 MATCH (22 ins), 3/3 through the whole-binary gate.

BANKED this commit: func_801846E4 / func_8018473C / func_80184794 in ov_SC03_015 (6 across
the two overlays now). The other 24 stubs in the region are undrafted -- the route makes them
DRAFTABLE (they were un-bankable at any effort before); drafting them is crack-wave work.

R22 CLEAN-FLEET: extract-all 139/139 (+main); check-all 140 passed, 0 failed of 140.
cookbook SS126 (the address-range-is-not-an-optimization-region law + the probe ladder).
2026-07-31 08:41:54 -06:00
Drew T 45d26cc413 feat(phase-30): T2 carve-within-a-carve PROVEN end-to-end; Arm-A does not bite; 3 -O0 fns banked
T2's central unknown is resolved, and it is NOT what the phase plan predicted. The plan
named the Arm-A splat `%lo +0x20` defect as T2's real substance. Four probes, each
isolating ONE variable, SHA vs config/check from a clean tree (SS125 rules):

  1. sub-split the jr object at ARBITRARY addresses, pure -O2  -> BYTE-IDENTICAL
     ** the re-carve is NEUTRAL; Arm-A does not bite here **
  2. same split, middle region routed to -O0                   -> DIVERGED (2 vars at once)
  3. same NAME as probe 1, only the -O0 flag added              -> DIVERGED
     ** therefore the FLAG, not the subseg name **
  4. -O0 regions cut to EXCLUDE the matched bodies             -> BYTE-IDENTICAL
     ** route PROVEN end-to-end **

THE REAL OBSTACLE: an address range is not an optimization region. Interleaved among the
15 -O0 stubs at 0x80183CF0..0x80184920 are TWO already-MATCHED functions (func_80184440,
func_801848E4) that expand from engine_core.h and compile at -O2. Flipping the FILE to -O0
recompiles them too. Cut around them and it is byte-clean.

MY EARLIER "15 contiguous -O0 fns, clean cut" WAS AN UNDER-COUNT (R14 on myself): I derived
it by scanning asm/**/*.s for the frame-pointer prologue, and a MATCHED function emits no
.s -- so the scan was structurally blind to exactly the bodies that break the flip. Same
shape as SS124. Any T2 driver must derive -O0 bounds as (address range MINUS already-matched
bodies), never from an asm scan.

BANKED (3, whole-binary gate the sole arbiter): func_801846E4 + siblings func_8018473C /
func_80184794. Each global DERIVED FROM THE ASM (%hi/%lo operands), not taken from the
draft's comment; 3/3 match_one --o0 MATCH (22 ins) with a -O2 control showing the mismatch;
3/3 verified through harvest_verify; bank truth read from the SOURCE (SS55b trap 4).

MAKEFILE: the -O0 glob widened `ov_*_o0b.c` -> `ov_*_o0?.c` so ANY lettered -O0 sub-split is
covered by one rule. A MISSED rule is silent -- the region would compile -O2 and every
residual it produced would be a pure artifact (SS116). corpus.o0_sources() re-verified: 137
sources, resolves `?` via glob, both pre-existing rules intact.

CONFIG: ov_SC03_014_jr_8017EB7C sub-split into 5 regions (pre / _o0c / matched-O2 /
_o0d / post), reusing jr_isolate_all's plan+build_new_config+validation verbatim so the
carve-repoint and source-repartition semantics are the proven ones.

R22 CLEAN-FLEET: extract-all 139/139 (+main) ; check-all 140 passed, 0 failed of 140.
2026-07-31 08:36:42 -06:00
Drew T 8451f349c0 feat(phase-30): jr behemoth func_80181CDC (769 ins) banked via the SS81 carve chain; 2 byte-refused
The 3 jr behemoths carried from SESSION-27 (staged .run/beh-gate/), each run through
the SS81 3-step chain SERIALLY under tools/treelock.sh (every step calls `make extract`).
Re-derived the stub set on a QUIESCENT tree first: 4 of the 7 staged fns were already
banked in S27 and the staging dir still held all 7.

BANKED (1):
  ov_SC05_010 func_80181CDC (769 ins) — jr_isolate_all --only -> BYTE-IDENTICAL,
  jtbl_carve --func -> BYTE-IDENTICAL, then harvest_verify --chunk 1. Bank truth read
  from the SOURCE (INCLUDE_ASM absence), never the gate report (SS55b trap 4).

BYTE-REFUSED (2) — to the wall ledger WITH EVIDENCE, not forced, not labelled walls:
  ov_SC01_009 func_8018057C  — jr_isolate_all reported success (2 jr in 1 -O2 object,
    2 region .c) but the post-isolate build was NOT byte-identical. Aborted at step 1.
  ov_SC06_018 func_80191C50  — isolate clean; jtbl_carve reported success (48-piece
    carve set, 22 tail pieces) but the post-carve build was NOT byte-identical.
    Aborted at step 2.
  Both TOOLS claimed success; the whole-binary gate refused (G3/P9 doing its job).
  Neither is diagnosed, so neither is called a compiler wall — on this project that
  guess has been wrong four times running (R35). Drafts + logs preserved under .run/.

R22 CLEAN-FLEET (config changed => T2 blast radius => mandatory):
  extract-all: 139 extracted, 0 failed of 139 (+ main, serial)
  check-all:   140 passed,  0 failed of 140      <- BYTE-IDENTICAL

DRIVER DEFECT FIXED (mine, SS105/SS61): v1 of .run/s28_beh.sh `continue`d past a failed
gate WITHOUT reverting, leaving two half-carved overlays in the tree; only a full
`git checkout -- src/ config/` recovered it. Nothing was ever committed, so the cost was
build cycles and zero work. v2 reverts that target's config+src on EVERY failure path.
2026-07-31 08:03:08 -06:00
Drew T 9a30466de4 feat(phase-30): the "137 no matched unit" family banked 137/137 (func_8016191C x137)
The skip class that the SESSION-27 checkpoint carried as "~137 members, a cheap
sweep-routing gap" is closed: ONE exemplar, ALL 137 same-address members banked,
0 failed, in a single --only sweep after the extract_unit alias fix (commit:1260).

- family_sweep --hseq --only 0x8016191C --band all -j 8, under tools/treelock.sh
  (the campaign-wide mutex, not a pgrep poll).
- BANKED 137 member-matches / 0 failed across 137 overlays; skipped {}.
- 24 ins x 137 = 3,288 instructions that were sitting behind a tool lookup miss.
- R37 probe before the sweep: rtu_match MATCH (24 ins) on 3 members in the REAL
  TU (ov_SC01_000 / _001 / _004) before spending 137 gate cycles.

R22 CLEAN-FLEET: make clean && make extract-all && make check-all ->
  extract-all: 139 extracted, 0 failed of 139 (+ main, serial)
  check-all:   140 passed,  0 failed of 140      <- BYTE-IDENTICAL
0 NON_MATCHING in any default build (G4). The whole-binary byte-gate was the sole
arbiter for every one of the 137 (G3/P9).

Note --band: the sweep defaults to band=substantial and this family is band=mid,
so the first invocation returned "0 matched-exemplar families" — a silent-looking
zero that is a FILTER, not a wall. --band all is required for mid/tiny families.
2026-07-31 07:52:37 -06:00
Drew T 0130fb340a feat(phase-30): wave-4 resumed 10/10 MATCH banked + h_exact leg (14 propagated); R22 140/140
The 12 agents killed by the usage-limit pause were resumed and ALL returned MATCH (2 had already
banked from their partial drafts, so 10 ran). h_exact propagation leg completed over all 112 banked
exemplars: 14 propagated, 42 benign skips (h_seq tier, correctly routed away per §123), 0 failures
— the 0x801466F0 'halt' was a third benign-refusal phrase, not a partial write.

fn-count 92.61 -> 92.67% | instr 88.2 -> 88.3% | distinct 70,581 -> 70,590 unique fns.
2026-07-31 07:25:47 -06:00
Drew T 29cd4d4c39 feat(phase-30): T3 wave-4 — 60/68 drafts banked across 14 binaries (parallel gate); R22 140/140
Wave 4 launched 70 agents / 14 binaries; 58 returned before the pause (all match_one MATCH) and
their drafts + 10 partials gated to 60 banks. fn-count 92.59 -> 92.61%, distinct 70,506 -> 70,581.
R22 clean-fleet 140 passed / 0 failed under the campaign lock. Propagation deliberately deferred
(--no-propagate) — it runs per-function, routed by tier (§123).
2026-07-31 00:49:40 -06:00
Drew T 471314da54 feat(phase-30): T3 waves 2+3 + 4 behemoths — 52 cores banked, 911 members propagated; R22 140/140
WAVE 3 (48 agents / 8 binaries, dealt across binaries so BANKING fans out): 48/48 match_one MATCH,
48/48 banked through 8 PARALLEL per-binary gates. WAVE 2: 15/19. BEHEMOTHS: 4 non-jr confirmed
(func_8017E120 884ins x14, func_8017FA5C 728, func_8017CAD4 755, func_8017E35C 719).
Tier-routed propagation (§123): family_sweep --hseq banked 911 members across 137 overlays.

fn-count 92.32 -> 92.59% | instr 87.9 -> 88.2% | distinct 78.3 -> 78.7% (70,506 unique fns)
R22 clean-fleet 140 passed / 0 failed, under one campaign lock (treelock.sh).

CORRECTION (R14): the 'per-binary bank-rate cliff' I reported from the pre-incident gate run
(SC03_014 1/6, SC04_018 1/6, SC06_018 2/6) was an ARTIFACT — those gates ran against a tree
propagation was concurrently rewriting. Re-gated clean: 6/6 everywhere. A measurement taken during
corruption is not a measurement; I should not have theorised a cause before re-running it.
2026-07-30 22:22:35 -06:00
Drew T 5d4167bb3c feat(phase-30): T3 wave-1 h_seq sweep — 548 members banked across 4 families; R22 140/140 (fn-count 92.16 -> 92.32%, distinct 78.0 -> 78.3%)
The 4 cores dedup_propagate refused (h_exact tier) templated cleanly via family_sweep --hseq once
the family map was regenerated post-bank (a bank invalidates the map: sig-overlays + family_hseq
must run BEFORE the sweep — the standing wave-loop order). 548/686 banked, 138 failed (one
consistent per-overlay slice, diagnose next). Wave-1 total: 8 cores -> 1,121 instances.
instr 87.5 -> 87.9%, distinct 69,828 -> 70,094 unique fns.
2026-07-30 20:07:41 -06:00
Drew T 159317d3fe feat(phase-30): T3 wave-1 — 8 cores banked + 4 propagated fleet-wide; R22 140/140 (fn-count 92.00 -> 92.16%)
Ultracode wave of 14 agents over fresh reach-138 cores: 14/14 match_one MATCH, 8 accepted by the
whole-binary gate (the §52b law reproduced exactly). Propagated per-function (the incident fix):
0x8012E014, 0x80151C54, 0x8012F49C, 0x80151B98 -> +573 instances. R22 clean-fleet 140/140;
instr 87.5 -> 87.7%, fn-count 92.00 -> 92.16%, distinct 69,828 -> 69,836.

The other 4 banked cores are h_seq (PURE/IMM) families: dedup_propagate is h_exact-only, so its
'reach<2' / 'not self-contained' refusals were statements about the TOOL's tier, not the functions
-> cookbook §123 (the §53 carve-law generalized to the propagation-tier axis) + a routing table.
They bank via family_sweep --hseq next.
2026-07-30 19:57:54 -06:00
Drew T 2bfb8d4f52 feat(decomp): t6-recover gate — +1 fns x0 propagated (fleet None%) 2026-07-30 17:36:03 -06:00
Drew T 52b37da189 feat(decomp): t6-recover gate — +1 fns x0 propagated (fleet None%) 2026-07-30 17:33:05 -06:00
Drew T 03359b85b7 feat(decomp): t6-recover gate — +1 fns x0 propagated (fleet None%) 2026-07-30 17:30:47 -06:00
Drew T 1754aa7e55 feat(decomp): t6-recover gate — +1 fns x0 propagated (fleet None%) 2026-07-30 17:29:57 -06:00
Drew T ec19886be4 feat(decomp): t6-recover gate — +1 fns x0 propagated (fleet None%) 2026-07-30 17:28:08 -06:00
Drew T fb6e5266ba feat(decomp): t6-recover gate — +1 fns x0 propagated (fleet None%) 2026-07-30 17:26:18 -06:00
Drew T d750cef221 feat(decomp): t6-recover gate — +1 fns x0 propagated (fleet None%) 2026-07-30 17:25:31 -06:00
Drew T 6e9cd5e449 feat(decomp): t6-recover gate — +1 fns x0 propagated (fleet None%) 2026-07-30 17:24:43 -06:00
Drew T 9713f1ede0 feat(decomp): t6-recover gate — +1 fns x0 propagated (fleet None%) 2026-07-30 17:23:54 -06:00
Drew T 11da706745 feat(decomp): t6-recover gate — +1 fns x0 propagated (fleet None%) 2026-07-30 17:22:36 -06:00
Drew T 9398f3b5cf feat(decomp): t6-recover gate — +1 fns x0 propagated (fleet None%) 2026-07-30 17:21:47 -06:00
Drew T e277701267 feat(decomp): t6-recover gate — +1 fns x0 propagated (fleet None%) 2026-07-30 17:20:17 -06:00
Drew T a74e21631d feat(decomp): t6-recover gate — +2 fns x0 propagated (fleet None%) 2026-07-30 17:16:21 -06:00
Drew T ab467e2196 feat(decomp): t6-recover gate — +1 fns x0 propagated (fleet None%) 2026-07-30 17:15:24 -06:00
Drew T b4b298278e feat(decomp): t6-recover gate — +2 fns x0 propagated (fleet None%) 2026-07-30 17:12:31 -06:00
Drew T cb0d3c185b feat(decomp): t6-recover gate — +1 fns x0 propagated (fleet None%) 2026-07-30 17:10:09 -06:00
Drew T 407ff8f85c fix(phase-30): T0e-1 — the 21-file absolute-include portability defect: /home/musashi paths -> ../shared/ relative (R22 140/140) 2026-07-30 16:42:03 -06:00
Drew T ceae8bb4cd feat(phase-29): T97 — func_80151944 138/138; the "three-edit job" was ONE edit
- The last big NAMED blocker, costed across four checkpoints as §112 header + §20 call-site cast +
  a scripted §99 pass over 2,022 overlay-local decls. Probing first showed two of the three were
  unnecessary: the conflict is entirely between DEFINE_func_80151924()'s own forward-decl
  (extern s32 func_80151944(void)) and the byte-true definition (void f(void *a0)), four lines
  apart in the assembled TU. The 2,022 decls live in OTHER TUs and never entered it.
- ONE 4-line edit in engine_core.h: decl -> byte-true, call site -> ((s32 (*)(void))f)() so the
  caller's codegen is unchanged. rtu_match: conflicting types -> MATCH (15 ins). Sweep 138/138.
- Family 0x80131eec fully closed: 149 (T87) + 138 (T97) + 1 immediate-refusal = all 288 members.
- SHARED-HEADER RISK VERIFIED, NOT ARGUED: engine_core.h is included by all 138 overlays, so §20
  cast-folding is a hypothesis. Per-binary gates 138/138 are necessary but not sufficient; the
  fleet check is the one that counts. R22 clean-fleet 140/140 + tools-health RC=0 (corpus 0
  PHANTOM/0 TRUNCATED, cdecl, audit-binaries, dedup 1886/0, C1 239604/239604).
- METRICS: fn-count 91.96 -> 92.00% (+138, exact) · instr 87.4 -> 87.5% (+2,070) · distinct +72.
- COSTING LESSON: the estimate came from reading the symptom (2,022 decls of this name exist)
  instead of probing the failure (which decl actually conflicts). Probe before COSTING, not just
  before scaling.
2026-07-30 13:44:22 -06:00
Drew T 7e32da8f64 feat(phase-29): T95/T96 — func_80142B2C 136/136 (§121); all 3 byte-identical stragglers closed
- The draft calls ((void(*)(void))func_80142C84)() but nothing declares that symbol above the
  splice: it is DEFINED by DEFINE_func_80142C84() in engine_core.h, so gather_externs has no
  extern line to harvest, and the member TU instantiates the macro BELOW our function.
- The wrong guess was the useful step: a no-prototype `extern s32 func_80142C84();` turned
  `undeclared` into `conflicting types` — a DIFFERENT error, proving the diagnosis right and the
  type wrong. Synthesised from the macro's own definition head -> MATCH (34 ins) -> 136/136.
- NEW macro_def_sig_map() (1,878 signatures): the complement of header_sig_map(), which reads the
  externs a macro emits FOR ITS CALLEES; this reads the signature a macro DEFINES. Cookbook §121.
- ALL THREE byte-identical stragglers carried since SESSION-24 are now closed: func_80146750
  137/137 (T84), func_801759D8 137/137 (T93), func_80142B2C 136/136 (T95) = 410 members, and not
  one was a compiler wall (a signedness-wrong header decl, a type-name collision, a missing extern).
- Blast radius 0 (74 further families re-swept). FOUR data points now: only §117 (wrong LOGIC)
  generalised at 1,209 members; §118/§120/§121 are path-reachability gaps worth ~one family each.
- GATES: R22 clean-fleet 140/140; dedup 1886/0; 0 NON_MATCHING (G4).
- METRICS: fn-count 91.88 -> 91.96% (+273, exact) · instr 87.3 -> 87.4% (+12,296) · distinct +0
  (both byte-identical families — §111 predicted exactly that).
2026-07-30 13:13:06 -06:00
Drew T 9a1507462f feat(phase-29): T93/T94 — func_801759D8 137/137 via type-uniquify (§120) + two T92 corrections
- CORRECTION 1 (R14/P9): T92's "strip-if-ambient" recipe was WRONG. Stripping the draft's duplicate
  typedef breaks the extern that USES it (the TU's own copy sits below the spliced function), so the
  "second stacked blocker" T92 recorded (D_800AF634 used prior to declaration) was my own fix
  misfiring, not a real blocker. RENAME, don't remove: rtu_match CC1 FAIL -> MATCH (56 ins).
- CORRECTION 2: T91's wiring never RAN. family_sweep has THREE staging sites sharing the identical
  two lines (edit-remap / hseq / plain h_norm); I patched by rindex twice, which lands on the PLAIN
  site, so --hseq staged the draft unchanged and the lever looked ineffective. Re-anchored on the
  hseq site's unique write (func_{to_addr:08X}.c) and the draft came out renamed. T91's revert was
  right discipline on a false premise.
- RESULT: _uniquify_draft_types wired into the hseq path (byte-neutral — C type names never reach
  codegen). func_801759D8, one of the three long-standing byte-identical stragglers: 0 -> 137/137,
  0 failed. Blast radius 0 (74 further families re-swept, none moved) => TARGETED lever, like §118
  and unlike §117.
- Cookbook §120, incl. the law: before concluding a lever does not work, prove it RAN — diff the
  staged artifact for the change it is supposed to make.
- GATES: R22 clean-fleet 140/140; dedup 1886/0; 0 NON_MATCHING (G4).
- METRICS: fn-count 91.88 -> 91.92% (+137, exact) · instr 87.3 -> 87.4% (+7,672) · distinct +0
  (byte-identical family — §111 predicted exactly that).
2026-07-30 12:57:32 -06:00
Drew T f7c6d2eb2f feat(phase-29): T89/T90 — 0x80161c98 138/138 via the flag off-diagonal (§119) + a T84 correction
- CORRECTION (R14/P9): T84's '137 banked = all of 0x80161c98' is WRONG and committed wrong in
  commit:1193. The 137 were func_80146750 (a byte-identical straggler), banked 1-per-overlay in
  <ov>_after.c; 0x80161c98's members were still stubs. I assigned a count to the family I had
  been looking at without deriving it — third instance today of that error class. The
  --fix-def-sig-is-harmful finding itself stands (it unblocked func_80146750 x137).
- THE REAL BLOCKER was a flag OFF-DIAGONAL, not a defect. 0x80161c98's byte truth is (int,u32)
  -> sltiu; engine_core.h says (s32,s32); and an in-TU decl disagrees with the def. The levers
  pull opposite ways: --fix-def-sig bends the DEFINITION to the header; --normalize-self-decls
  bends the DECLARATIONS to the definition. both-on -> slti DIFF (T79). both-off -> correct
  sltiu but 'conflicting types' (T84/T88). NSD-only -> 138/138 (T89). Three sweeps across three
  sessions tested only the diagonal of the 2x2. Cookbook §119.
- T90 blast radius: 23 more (NSD-only) across the remaining still-zero families — targeted, not
  general; recorded so it is not over-projected.
- GATES: R22 clean-fleet 140/140; dedup 1886/0; 0 NON_MATCHING (G4).
- METRICS: fn-count 91.84 -> 91.88% (+161, exact) · distinct-code 69,593 -> 69,744 (+151).
2026-07-30 10:54:06 -06:00
Drew T bf71232d0b feat(phase-29): T87/T88 — ordinal immediate resolution (§118): 158 banked
- The T86 asm-ambiguous refusal was CORRECT (a by-value swap would corrupt the non-differing
  occurrence); the safety TEST was too strict. It compared the C literal's occurrences against
  EVERY asm use of that value, but gcc synthesises uses no C token names — e.g.
  D_80187044[*(u16 *)((s32)a0 + 0x2)]() has one C literal 0x2 and TWO asm uses of 2 (the
  per-member offset + a fixed sll ..,2 for the 4-byte stride). Unsatisfiable by construction.
- FIX (_ordinal_edits, §118): pair C occurrences to asm positions IN ORDER, accepting either
  len(spans)==len(asm_pos) (every use named) or len(spans)==len(diff_pos) (extras are implicit).
  Rewrite only occurrences whose instruction is in diff_idx. Order is a heuristic, so the
  whole-binary byte-gate stays the sole arbiter — a wrong pairing is rejected, never banked.
- T87: func_801599A4 0 -> 137 drafts, 137 banked; +12 singletons = 149 (family 0x80131eec).
- T88 blast radius: only 9 of the other 144 immediate-refusals converted (refusals 67 -> 34).
  A TARGETED lever, not a second §117 — recorded so it is not over-projected.
- GATES: R22 clean-fleet 140/140; dedup 1886/0; 0 NON_MATCHING (G4).
- METRICS: fn-count 91.79 -> 91.84% (+158, exact) · distinct-code 69,450 -> 69,593 (+143).
2026-07-30 10:26:26 -06:00
Drew T dcbeebaf49 feat(phase-29): T84/T85 — 0x80161c98 137/138 + func_801457A4 133/133 (+270 members)
- T84 (item 1): the top still-zero family's whole diff was ONE instruction — slti (signed) vs the
  target's sltiu. --fix-def-sig was conforming a byte-correct draft to engine_core.h's
  signedness-wrong decl (extern void func_80161D20(s32,s32)) while the exemplar's own def is
  (int, u32). Re-swept the 92 still-zero families WITHOUT the flag: 137 banked (all of
  0x80161c98), other 91 unmoved => family-specific, NOT a second §117. Recorded as such.
- T85 (item 2): rewrote tools/rollout_801457a4_o0.py as the two-file ATOMIC driver §116 called for
  (remapped body -> <ov>_o0b.c AND drop the INCLUDE_ASM from <ov>_after.c in one edit; build vs
  config/check.<ov>.sha; restore BOTH files on mismatch, §61). Validated on 3, then 130/130.
  No splat change — the Arm-A re-carve wall never touched.
- Item 4 PRICED AND DROPPED: STRUCT residue = 34 families / 166 members / 0.02pp.
- R14: my new_distinct estimator over-projects ~2x (priced 259, measured 125) — it counts classes
  unmatched at run time, so concurrent sweeps double-count. Ranks correctly, overstates absolutely.
- GATES: R22 clean-fleet 140/140; dedup 1886/0; 0 NON_MATCHING (G4).
- METRICS: fn-count 91.72 -> 91.79% (+270, exact) · instr 87.2 -> 87.3% (+16,946) ·
  distinct-code 69,325 -> 69,450 (+125).
2026-07-30 09:51:02 -06:00
Drew T 9d0ce20015 feat(phase-29): T83 — the §117 blast radius: 821 members, 138 families zero -> complete
- Re-swept the 229 eligible non-jr families (2,575 candidate members) that had never seen a
  correct target spelling. 821 banked / 1,538 failed; 138 families went zero -> COMPLETE (732
  members), 14 partial, 92 still zero. Top: 0x80172780 +135, 0x80128158 +31, 0x80187318 +28,
  0x8016f540 +27, 0x8017bef8 +20.
- Every one of those 138 families had been swept before and booked as a failure. None was a
  compiler problem — all were downstream of the one positional-map defect fixed in T82.
- GATES: R22 clean-fleet 140/140; dedup 1886/0; 0 NON_MATCHING (G4).
- METRICS: fn-count 91.48 -> 91.72% (+821, exact) · instr 86.9 -> 87.2% (+33,670) ·
  distinct-code 69,024 -> 69,325 unique fns (+301).
- The 92 still-zero families are the honest residue: swept with every lever this phase built
  (§114 callee, §115 named-symbol, §117 symbol-kind, def-sig, self-decl normalization), so no
  known harness defect applies to them. Correct starting population for the next diagnosis round.
2026-07-29 23:35:45 -06:00
Drew T 28dc3785f5 feat(phase-29): T82 — symbol-KIND fix in symbol_map: func_80174784 2/255 -> 251/251 (§117)
- CAUSE: family_remap.symbol_map zips exemplar/sibling reloc slots positionally and spelled the
  SIBLING's symbol from the EXEMPLAR's kind. Same-address families always agree, so it was
  invisible for 20+ phases; cross-address families need not agree — func_80174784's callback slot
  is the FUNCTION func_801747CC while member func_8017CFD4's same slot is the DATA symbol
  D_80182688. The map emitted func_80182688, the body materialized a name for an address that is
  not a function, and the fleet gate refused all 251 members.
- FIX: spell the target by what the target address IS in the SIBLING's overlay (func_ iff in that
  overlay's sig set — the same boundary oracle nins_of trusts, R33; memoized). Phase 26-A had
  already established this rule and applied it only to the exemplar side.
- WHY IT HID: rtu_match/match_one MASK HI16/LO16, so a wrong %hi/%lo symbol still reports a clean
  MATCH (measured: "MATCH (10 ins)" on a member the fleet gate rejected). masked-MATCH +
  whole-binary DIFF is the exact signature of a compiler wall. Cookbook §117 carries the law.
- Also refuted en route (cheaply): --normalize-self-decls was NOT the cause — re-swept without it,
  still 0/251.
- GATES: R22 clean-fleet 140/140; dedup 1886/0; 0 NON_MATCHING (G4).
- METRICS: fn-count 91.41 -> 91.48% (+251, exact) · distinct-code 68,782 -> 69,024 unique fns
  (+242, projected 246) · instr +2,510.
- BLAST RADIUS UNMEASURED: symbol_map serves every family sweep; 229 eligible non-jr families /
  2,575 members have never been swept with a correct target spelling, incl. the byte-identical
  families T76 measured at 0/682 (same failure shape).
2026-07-29 23:08:03 -06:00
Drew T 774592c452 feat(phase-29): T79 — byte-VARIANT re-sweep: 641 banked; T70's "1 of 10" was a pre-lever measurement
- VALIDATED FIRST, then batched: 0x80143d28 (T66's #1, T76's ApplyMatrixSV callee diagnosis)
  banked 136/136 under the §114 callee axis + §115 named-symbol widening. Batch of 8 followed:
  505/1039. Totals: 5 families outright + 1 partial of 9; 641 members ×N.
- Attribution DERIVED (R33), not parsed from the sweep log: live stubs recomputed per family from
  corpus.stubs before/after. Reconciles exactly against the metric (fn-count +641).
- §116 (NEW): optimization level is a property of the FILE, not the function. 0x801457a4 swept
  0/137 because its exemplar lives in ov_SC01_077_o0b.c (-O0 via WHALE_O0B_OBJS) while all 137
  members' stubs live in <ov>_after.c (-O2). The fix moves the STUB line, not the def: <ov>_o0b's
  .text ends exactly at 0x801457A4, so the relocation is byte-neutral by construction and needs no
  splat re-carve (which is the Arm-A +0x20 wall). 13th time a family-wide 0/N was the harness.
- R14 CORRECTION to the handoff arithmetic: the tier is 123 families / 3,100 distinct on fresh
  sigs, but 1,287 of that distinct is the -O0 cluster behind the Arm-A splat wall. Honest
  addressable tier = 113 families / 85,360 ins / 1,813 distinct. Billing the walled 1,287 as sweep
  yield would have repeated the T76 error.
- 0x80131eec (214 distinct, the biggest item left) diagnosed precisely: header macro decl +
  §20 call-site cast + a scripted §99 pass over 2,022 overlay-local decls; param is void*, so the
  T75 narrow-param refusal does not apply.
- GATES: R22 clean-fleet 140/140 from make clean + extract-all + check-all; tools-health RC=0
  (corpus 0 PHANTOM/0 TRUNCATED, cdecl, audit-binaries, dedup 1886/0, C1 239604/239604);
  report RC=0; 0 NON_MATCHING (G4).
- METRICS: instr 86.7 -> 86.9% (+28,205 ins) · distinct-code 76.9 -> 77.4% (68,196 -> 68,782
  unique fns) · fn-count 91.23 -> 91.41% (+641). The distinct-code move is the point of this tier.
2026-07-29 22:36:09 -06:00
Drew T 611622c9e7 feat(phase-29): T78 — PsyQ-symbol widening: func_8012F40C 0/137 -> 137/137 (three places, not one)
I called this "a one-line predicate widening". It was THREE, and fixing the first two changed nothing
— the sweep still reported 0/547 (cookbook §115):

  1. canonical_map     : re.fullmatch(r'func_[0-9A-Fa-f]{8}') + keyed by parsed ADDRESS
  2. DECL_LINE_RE      : (func_[0-9A-Fa-f]+) as the name group
  3. split_sig_string  : \bfunc_[0-9A-Fa-f]+\s*\(

Each is a SILENT SKIP indistinguishable from "no conflict found". With 1+2 done the symbol reached 3
and died there; only tracing transform's internals (`callees cast: 0` while the canonical map plainly
held `s32 RotTransPers(s32, s32, s32*, s32*)`) located it. THE TRAP WORTH REMEMBERING: a partial fix
to a name-form assumption produces the exact symptom of no fix at all, so a correct hypothesis looks
refuted. Curated naming increases as RE quality improves, so any func_-only predicate is
rot-by-design — the same shape as stub_map's (Phase 26-A).

RESULT: func_8012F40C 0/137 -> 137/137. The other three families (801759D8, 80146750, 80142B2C) still
fail on different causes.

GATES: R22 clean-fleet 140 passed, 0 failed of 140; tools-health OK; dedup 1886/0; 0 NON_MATCHING.
METRICS: instr 86.7% (+4,932 ins); fn-count 91.19% -> 91.23% (+137); distinct +0 (byte-identical).

NEXT: the byte-VARIANT tier is worth re-sweeping — T70 banked 1/10 BEFORE the callee axis existed, and
26 families remain unswept by the two levers added since.
2026-07-29 20:57:11 -06:00
Drew T 970559423d feat(phase-29): T77 — wire the callee-decl lever into family_sweep; func_80173A60 0/135 -> 135/135
Item 1. The T76 diagnosis was right and the fix was a lever we already owned. cast_call_sites
(§17a-1/§20) handles the callee-conflict class and lived ONLY in gate_stage, which the family sweep
deliberately does not use — the THIRD instance this session of a lever unreachable from the path that
needs it (T56 data-decl unreachable, T57 function-decl off-by-default, now T77 callee).

  the 5 byte-identical families : 0/682 -> 135/682
  func_80173A60 specifically    : 0/135 -> 135/135

Wired after scope_data_fix (orthogonal axes: data vs callee), default ON with --no-cast-callees. Two
details that matter: the canonical map is built from the TARGET sibling's TU via cpp
(canonical_map(ov, src_file=tu) -> cdecl.tu_scope) so it sees MACRO-INJECTED declarations — a
raw-text scan returns nothing for exactly the callees that conflict (§51g LAW 7) — and it is read
AFTER any tu-scope edit is on disk.

THE OTHER FOUR STILL FAIL, different causes. And the next finding is already visible:
func_8012F40C's blocker is RotTransPers, a PsyQ LIBRARY symbol — a callee conflict the cast should
have handled. It did not, because cast_call_sites' canonical map keys on
re.fullmatch(r'func_[0-9A-Fa-f]{8}'), so NAMED PsyQ callees are structurally invisible to it. That is
a one-line predicate widening with ~270 members behind it (RotTransPers + ApplyMatrixSV families).

GATES: R22 clean-fleet 140 passed, 0 failed of 140; tools-health OK; dedup 1886/0; 0 NON_MATCHING.

METRICS: instr 86.6% -> 86.7% (+7,965 ins); fn-count 91.15% -> 91.19% (+135); distinct +0
(byte-identical — §111 predicted it).

cookbook §114 — the three decl axes, and "conflicting types for X: READ X".
2026-07-29 20:34:09 -06:00
Drew T 14bc520c96 fix(phase-29): engine_core.h — §99 no-prototype for func_80147364 (sidesteps a 4,021-site conform)
Item 3, and the cheap route won. conform_decls' dry run priced the direct fix and warned it off:

  byte-true def : void func_80147364(u16 param_1, u16 param_2)
  4,021 decl sites: 2,030 (u16,s32) + 1,983 (u16 a0,s32 a1) + 4 byte-true + 4 (u16,u16)
  ⚠ SCALAR-NARROWING (s32 -> u16) — NOT caller-neutral; argument promotion changes at every call
    site, so callers emit different code (byte-proven on func_80175DA8)

So conforming 4,021 sites would likely trade a PLUMBING failure for a BYTE failure. The §99
no-prototype form on the HEADER is compatible with both the byte-true definition and the existing
(u16, s32) prototypes, and touches 9 sites instead of 4,021:

  extern void func_80147364(u16, s32);  ->  extern void func_80147364();

Verified: header change ALONE, no src change, R22 clean-fleet 140 passed, 0 failed of 140.

This is the T67 failure resolved — that batch failed 2/140 with  because it corrected the header's TYPES while 272 TUs disagreed. Dropping the
prototype instead disagrees with nobody.
2026-07-29 00:47:01 -06:00
Drew T 86c315ec08 fix(phase-29): engine_core.h — §99 no-prototype for the three CALLED ARITY functions
Item 1's payoff. §113's call-vs-address re-check found func_80144B14 was the ONLY address-taken one
(already fully retyped, T72); func_8013BD34 / func_8014358C / func_8017D808 are genuinely CALLED, so
their arity IS constrained by the macro's own call site and the full retype is unavailable.

§99 no-prototype is the fix: `extern void func_X();` accepts the macro's fixed-arity call AND the
definition's differing arity, and a no-prototype call passing the same arguments generates the same
code.

  extern void func_8013BD34(void);  ->  extern void func_8013BD34();   (def takes s32 a0)
  extern void func_8014358C(void);  ->  extern void func_8014358C();   (def takes s32 param_1)
  extern void func_8017D808(s32, s32); -> extern void func_8017D808(); (def takes void *a0)

Verified in one step per the T48 discipline: the header change ALONE, no src change, R22 clean-fleet
140 passed, 0 failed of 140. Batched three because the technique was the variable, not the targets —
a bisect over three is cheap if it fails.
2026-07-29 00:39:22 -06:00
Drew T ed95cad428 feat(phase-29): T72 — ARITY probe banks 137/137; most of the class was never an arity problem (§113)
Probe target switched from func_8013BD34 on measured evidence (its def is in ov_SC07_010_o0.c and
_o0 families sweep ~1/137 — a poor test of an unproven technique). func_80144B14: same class, 137
stubs, not -O0, real 34x137 family, tests both axes (void(void) -> int(int)).

THE PROBE FOUND THE PRECONDITION OVER-FIRING. The ARITY blocker exists because the macro's own CALL
SITE passes the header's arity. But DEFINE_func_* does not call func_80144B14 — it takes its ADDRESS:
    *(s32 *)((s32)a0 + 0xDC) = (s32)&func_80144B14;
No call site => no arity constraint => the FULL correction is available, not the §99 no-prototype
workaround. Applied `extern int func_80144B14(int param_1);`.

RESULT: header change ALONE -> R22 clean-fleet 140 passed, 0 failed of 140 (byte-neutral); family
sweep -> 137/137, 0 failed.

METRICS: instr 86.6% (+4,658 ins); fn-count 91.12% -> 91.15% (+137); distinct-code +0 (byte-identical
family — §111 predicted it).

THE REFINEMENT (cookbook §113): the precondition must ask what the macro DOES with the symbol — a
call constrains arity, an address-taken or unused decl does not. Blocking on "both names appear"
over-fires, and it had 137 members behind it. The remaining ARITY findings should each be re-checked
for call-vs-address before assuming §99 is needed.

GATES: R22 140/140 twice; tools-health OK; dedup 1886/0; 0 NON_MATCHING (G4).
2026-07-29 00:34:12 -06:00
Drew T df86fcce50 fix(phase-29): engine_core.h — func_80144B14 declared int(int), not void(void)
The ARITY blocker did not apply: DEFINE_func_* does not CALL func_80144B14, it takes its ADDRESS
(`*(s32 *)((s32)a0 + 0xDC) = (s32)&func_80144B14;`). There is no call site to break, so the FULL
correction is available rather than the §99 no-prototype workaround.

That is a refinement the audit needs: the ARITY precondition asks whether the macro's own call site
would break, but an address-taken use has no call site. Over-fires on that shape.

§85: 0 consumers, so the void->int return widening is byte-neutral.

Verified in two steps (T48 discipline): header change ALONE, no src change, R22 clean-fleet 140
passed, 0 failed of 140. Fleet-shared (§61/§63), R22 mandatory.

Probe target switched from func_8013BD34 on measured evidence: that one's definition lives in
ov_SC07_010_o0.c, and _o0 families sweep ~1/137, making it a poor test of an unproven technique.
func_80144B14 is the same class, 137 stubs, not -O0, with a real 34x137 family.
2026-07-29 00:23:14 -06:00
Drew T 283937ed8e feat(phase-29): T70 — byte-variant families sweep 1 of 10 (138 banked, +130 distinct)
Item 5, first batch. Swept 10 byte-VARIANT non-jr non-O0 families (42,235 ins / 1,552 distinct
projected): 138 BANKED / 1,346 failed — ONE family of ten (func_801627E8 137/137), plus 152 members
skipped as "unresolved immediates (T2a)".

THE FINDING: that is a ~10x worse rate than the byte-IDENTICAL families, which banked 137/137 apiece
all session. It follows from what §111 established — a byte-variant member differs in more than
relocations, so the template must adapt immediates too, and family_remap's T2a engine refuses what it
cannot resolve. The distinct-code lever is real but it is NOT the same cheap sweep, and the projected
"2,962 distinct across 36 families" should be discounted until the immediate-resolution rate is
measured. That measurement is now item 1 of the next list, ahead of sweeping the other 26.

§111 PASSED A SECOND PREDICTIVE TEST: projected +129 distinct for func_801627E8; observed +130 (the
extra from an unrelated 2-member bank).

GATES: R22 clean-fleet 140 passed, 0 failed of 140; tools-health OK; 0 NON_MATCHING (G4).

METRICS: instr 86.5% -> 86.6% (+2,618 ins); fn-count 91.08% -> 91.12% (+138); distinct-code
68,066 -> 68,196 = +130 — the first real distinct-code movement of the session.
2026-07-28 23:47:22 -06:00
Drew T f59ae302b8 feat(phase-29): T68 — 6 header corrections sweep 685 members (+33,565 ins); fleet 86.5% instr
The audit was the right precondition: THREE of the six corrected functions were families already
queued for the item-3 sweep, and each would have failed 0/137 exactly the way five families did
earlier today.

SWEEP: 6 corrected functions, all non-jr families with 137 live stubs -> 685 BANKED / 137 failed.
Five families landed 137/137; func_80146750 failed on its own residual (undiagnosed).

GATES: R22 clean-fleet 140 passed, 0 failed of 140 — after the header batch alone AND after the
banks; tools-health OK (corpus 0 PHANTOM + 0 TRUNCATED, cdecl, audit-binaries, dedup 1886/0);
0 NON_MATCHING (G4).

METRICS: instr 86.3% -> 86.5% (11338739 -> 11372304 = +33,565 ins); fn-count 90.88% -> 91.08%
(321472 -> 322157 = +685); distinct-code 76.9% -> 76.9% (+0).

§111 GOT ITS FIRST PREDICTIVE TEST AND PASSED: all six families have a single h_exact class, so the
model predicted +0 distinct BEFORE the sweep ran, and +0 is what happened. The metric is modelled,
not mysterious.
2026-07-28 23:16:08 -06:00
Drew T 0c5df25faf feat(phase-29): T67 — audit_header_sigs.py; 61 header decls contradict byte truth, 6 corrected
THE TOOL (tools/audit_header_sigs.py, cookbook §112). A DEFINE_func_*() macro forward-declares the
functions its body calls, and that decl is visible in EVERY overlay instantiating the macro — so when
it disagrees with the byte-true definition the whole family becomes untemplatable and the failure
wears a compiler wall's clothes. Three such were found ONE AT A TIME earlier this phase
(func_80156044, func_8016163C, func_8014D610), each worth ~137 members, each costing a
diagnose/fix/re-sweep cycle. This audits all of them in one pass: parse every `extern func_X(...)` in
src/shared/*.h, find every DEFINITION in src/**/*.c (via §110's _def_head_at, not "ends in ;"),
compare with cdecl, and report only where NO definition agrees — one overlay disagreeing is loose
typing (§16/T49), all of them disagreeing means the header is the outlier.

RESULT: 3,043 decls across 1,023 functions; 265 have definitions; 61 contradict every one. The top 10
are full-fleet families (137/136/134 live stubs, 1,366 total), all with an unambiguous byte truth.

APPLIED: 6 functions / 11 decl sites, R22 clean-fleet 140 passed, 0 failed of 140 —
func_80138DE0, func_80146750, func_80161374, func_80161774, func_80161888, func_801778A8.

TWO PRECONDITIONS THE AUDIT DOES NOT YET CHECK, both found by gating rather than by reasoning:
 1. ARITY. func_80144B14 / func_8013BD34 / func_8014358C declare (void) but are DEFINED with one
    parameter. Correcting the header would break the macro's OWN call site (too few arguments), so
    they need the §99 no-prototype treatment instead. Excluded before the batch, by measurement.
 2. OTHER IN-SCOPE DECLS. The first batch of 7 FAILED the gate 2/140 with `conflicting types for
    func_80147364` — the overlays' own TUs declare it the old way (9 header sites rewritten, but
    src/ov_*/…:347 disagrees). A header correction is only safe when no other in-scope declaration
    disagrees; that one additionally needs a conform_decls pass. Excluded; the other 6 then gated
    140/140 clean.

The gate caught the bad batch immediately and the culprit was found by reading one object's real cc1
output rather than by a 7-way bisect (7 fleet gates = ~2.5h; one serial compile = seconds).
2026-07-28 23:00:55 -06:00
Drew T ec34c31b68 feat(phase-29): T65 — extract_unit definition-detection fixed; func_80156044 137/137 (+10,138 ins)
Item 3, and it banked the third family. extract_unit located a definition with "the line matches
<type> func_<addr>( and does not end in `;`" — wrong whenever ONE LINE holds both a declaration and a
definition, which the handwritten inline-asm wrappers do:

    extern void func_80156044(int, int); int func_80155FF8(int, int) { __asm__ … }

The line does not end in `;`, so func_80156044 — appearing there only in the DECLARATION — was taken
as a definition head. extract_unit lifted the neighbouring WRAPPER instead of the real definition
seven lines below; every sibling already defines that wrapper via its shared DEFINE_ macro, so all
137 failed with `redefinition of func_80155FF8` and it read as a compiler wall.

FIX: ask what follows the PARAMETER LIST, not what ends the line (`_def_head_at`) — `;` is a
declaration, `{` or end-of-line is a definition. Plus the R32 assertion: a unit that defines a
function other than its target cannot template, so refuse LOUDLY (`_foreign_defs`).

TWO TRAPS HIT WHILE WRITING THAT ASSERTION, both caught by regression-checking against families known
to bank: (1) _def_head_at ALONE over-fires — a call whose args wrap has nothing after the `(` on its
line, which "end of line => definition" reads as a definition; it refused THREE families that had
just banked 137/137. (2) The type-prefix test ALONE under-fires — it is what missed the wrapper
originally. The predicate needs both: split the prefix on its last `;`, require the remainder to look
like a return type, then check what follows the parameter list. All five known-banking families
extract byte-identically before and after.

RESULT: func_80156044 0/137 -> 137/137, 0 failed.

GATES: R22 clean-fleet 140 passed, 0 failed of 140; tools-health OK (corpus 0 PHANTOM + 0 TRUNCATED,
cdecl, audit-binaries, dedup 1886/0); 0 NON_MATCHING (G4).

METRICS: instr 86.2% -> 86.3% (11328601 -> 11338739 = +10,138 ins); fn-count 90.84% -> 90.88%
(321335 -> 321472 = +137); distinct-code 76.7% -> 76.9% (67937 -> 68066 = +129).

cookbook §110.
2026-07-28 22:29:56 -06:00
Drew T 60f9ac40f3 feat(phase-29): T64 — func_8014D610 swept 137/137 after the header correction (+10,138 ins)
Item 2, and the same story as item 1: the header correction WAS the fix. With engine_core.h
declaring the byte truth, the family swept 137/137 with zero failures — no draft change.

  before (header wrong)  0/137  `conflicting types` / a param-retyped body that could not compile
  after  (header right)  137/137, 0 failed

GATES: R22 clean-fleet 140 passed, 0 failed of 140; tools-health OK (corpus 0 PHANTOM + 0 TRUNCATED,
cdecl, audit-binaries, dedup 1886/0); 0 NON_MATCHING (G4).

METRICS: instr 86.1% -> 86.2% (11318463 -> 11328601 = +10,138 ins); fn-count 90.81% -> 90.84%
(321198 -> 321335 = +137); distinct-code 76.7% -> 76.7% (+0 — a SIXTH data point for the anomaly).
2026-07-28 22:10:10 -06:00
Drew T 3c380fec83 fix(phase-29): engine_core.h — func_8014D610 declared s32(s32,s32,u16*), not void(s32,void*,void*)
Same class as func_80156044 and func_8016163C: the shared header contradicted the byte truth. The
exemplar's banked definition is `s32 func_8014D610(s32 param_1, s32 param_2, u16 *param_3)`
(ov_SC07_006_jr_80140608.c:4576); DEFINE_func_8014D438 declared
`void func_8014D610(s32 a0, void *a1, void *a2)`.

That mismatch is what made --fix-def-sig retype param_3 to `void *` while the body does
`param_3[0]` -> `void value not ignored as it ought to be` (T61's param-use guard now refuses it,
naming the header as the real fix — this is that fix).

§85 sized first: 0 callers consume the return. The macro's call site passes `s16 buf1[4]`/`buf2`
into the s32/u16* params — same 4-byte values in $a1/$a2, so the retype is a warning, not a codegen
change.

Verified in two steps (T48 discipline): the header change ALONE, no src change, R22 clean-fleet ->
140 passed, 0 failed of 140. Fleet-shared (§61/§63), so R22 was mandatory.

NOTE: ov_SC07_006_jr_80140608.c:4529 records an earlier, DIFFERENT resolution of the same conflict —
a per-overlay de-macroized local decl ("do NOT re-macroize"). That remains correct and untouched;
this fixes the shared decl the other 137 overlays see.
2026-07-28 21:52:38 -06:00
Drew T a850255572 feat(phase-29): T63 — func_8016163C swept 137/137 after the header correction (+10,686 ins)
Item 1. The header flip (commit:1163's sibling, committed just before) was the whole blocker: with
engine_core.h declaring the byte truth, the family swept 137/137 with ZERO failures — no draft
change, no new lever.

  before (header wrong)  0/137  `conflicting types` / a --fix-def-sig-truncated draft
  after  (header right)  137/137, 0 failed

GATES: R22 clean-fleet 140 passed, 0 failed of 140; tools-health OK (corpus 0 PHANTOM + 0 TRUNCATED,
cdecl, audit-binaries, dedup 1886/0); 0 NON_MATCHING (G4).

METRICS: instr 86.0% -> 86.1% (11307777 -> 11318463 = +10,686 ins, exactly 137 x 78);
fn-count 90.77% -> 90.81% (321061 -> 321198 = +137); distinct-code 76.7% -> 76.7% (+0).

The distinct-code anomaly now has FIVE data points (T52 +125, T57 +125, T56 +0, T58 +0, T63 +0) and
still no identified variable. Unchanged as the queued probe.
2026-07-28 21:50:19 -06:00
Drew T 2d91ed54fb fix(phase-29): engine_core.h — func_8016163C declared s32(s32,u32), not void(void*,s32)
The shared header contradicted the byte truth. The exemplar's banked definition is
`s32 func_8016163C(s32 arg0, u32 arg1)`; both DEFINE_ macro decl sites said
`void func_8016163C(void *a0, s32 a1)`.

That mismatch is why the family could not template, and it is what made --fix-def-sig DEMOTE the
return to void — gcc then deleted the computation feeding it and the draft compiled to 58
instructions against a 78-instruction target (T62's self-inflicted SIZE-MISMATCH).

§85 sized first: conform_decls.consumers(func_8016163C) = 0 — both macro call sites discard the
return (`func_8016163C(a0, func_801615C4(a0, 0));`), so the return-axis flip is byte-neutral.

Verified in two steps (T48 discipline): the header change ALONE, no src change, R22 clean-fleet
`make clean && extract-all && check-all` -> 140 passed, 0 failed of 140. Fleet-shared edit
(engine_core.h reaches all 138 overlays), so R22 was mandatory (§61/§63).
2026-07-28 21:37:58 -06:00
Drew T 51bac9f3e6 fix(phase-29): engine_core.h — DEFINE_func_80155FF8 declares func_80156044 void, not int
The exemplar's own @stuck note asked for this (ov_SC01_077_jr_80154C24.c L1349-1350): the
handwritten func_80155FF8 wrapper calls func_80156044 via inline-asm `jal`, so nothing consumes
the return, and ov_SC01_077 already declares it `void` inline — the MACRO was the outlier.

§85 precondition measured before touching it: conform_decls.consumers(func_80156044) = 0 callers
consume the return, so the return-axis flip is byte-neutral.

Verified in two steps (T48 discipline): the header change ALONE, with no src change, R22 clean-fleet
`make clean && extract-all && check-all` -> 140 passed, 0 failed of 140. Fleet-shared edit
(engine_core.h reaches all 138 overlays), so R22 was mandatory (§61/§63).
2026-07-28 21:30:41 -06:00