Commit Graph

169 Commits

Author SHA1 Message Date
Drew T 2cc49d0310 feat(phase-29): SESSION-21 — func_8012AAAC banked via the §81 carve chain (R22 140/140)
The first jtbl-routed bank of the session, and it validates the whole chain end-to-end:
 1. jtbl_carve SPLIT-TABLE repair (this session): jtbl_801D7FB0 28 -> 50 words (112 -> 200 B),
    authorized by func_8012AAAC's own `sltiu 0x32`.
 2. NEW FIX — SINGLE-TABLE PREDECESSOR: adding a second table to a subseg whose existing carve was
    single-table lost the FIRST table's start entirely (new_offs has only the new one;
    overlay_jtbl_addrs cannot see the old one because its owner is banked and extract PRUNED the
    stub .s; and single-table carves persist no tables= to rebase). The span then failed its own
    validator with "first must equal the span start" — the invariant naming the missing entry.
    A single-table carve spans exactly its one table, so ITS SPAN START *IS* THAT TABLE'S START:
    inference, not persistence, so it also works for spans carved before tables= existed. This is
    the RECOVERABLE half of the documented func_8013F350 lesson (that one was a pre-§8e merged
    DOUBLE — two tables, no record, genuinely unrecoverable).
    Result: ov_SC01_077_a JTBL_PADS := 0,0 tables=+0x0,+0x14. Carve alone byte-gated BYTE-IDENTICAL
    BEFORE the bank was attempted (§81 step 2).
 3. ARITY axis, all-or-nothing: 1,244 decl sites / 1,240 files `(void)` -> `()` + an R32 completion
    assertion (old-form remaining: 0).
 4. ONE call-site cast: the definition lands at line 811 and a 0-arg call sits at 822, so gcc sees
    the prototype and rejects it — `((void (*)(void))func_8012AAAC)()` (§17a-1; gcc folds the cast
    of a known symbol to a direct jal). Only 1 of the 1,386 fleet-wide 0-arg call sites needed it:
    the others see only the `extern ()` decl, which permits a 0-arg call.

DIAGNOSIS NOTE: the failure read CC1-FAIL with only a warning visible under make. Running the
pipeline stage-by-stage (cpp | cc1 | maspsx | jtbl_rodata_pads | as) put it on cc1 rc=33, and cc1's
own stderr named it exactly: "too few arguments to function func_8012AAAC" at line 994. Isolating
the stage was what turned an opaque Error 33 into a one-line fix.

R22 clean-fleet: extract-all 139/139, check-all 140 passed / 0 failed.
family_sweep correctly REFUSED this exemplar (§53: a jr-family must route through
jtbl_family_bank.py; "a 0% from this path would be a TOOL artifact, not a wall") — the ×137 member
sweep is the next step and needs a clean tree, which this commit provides.
2026-07-27 10:38:10 -06:00
Drew T 2ce6c5fade feat(phase-29): SESSION-21 — 3 family exemplars banked + the §85 return-axis widen (R22 140/140)
BANKED (whole-binary byte-gate, the sole arbiter): func_8014D2A0 (80 ins ×138) · func_80158638
(87 ×138) · func_8016B6BC (94 ×138). Stubs in ov_SC01_077: 150 -> 147, 0 new stubs.
R22 CLEAN-FLEET: extract-all 139/139, check-all 140 passed / 0 failed. dedup 1886/0,
0 NON_MATCHING (G4). Fleet 81.7% instr / 69.3% distinct-code / 89.52% fn-count.

- WAVE STOPPED at Drew's request with 15/24 agents returned, ALL 15 status=match. Only the
  completed drafts were gated; in-flight ones are still being written (§90d).
- PRE-GATE, both oracles, all 15: match_one MATCH + reloc_verify ALL RESOLVED. Routed 7 plain /
  8 to the §81 jtbl carve chain.
- THE BLOCKER, MEASURED: 7 of 7 plain drafts failed PLUMBING, 0 DIFF, 0 compiler walls — the same
  shape as SESSION-20's T0.2. §58b applies: the draft sig is byte-TRUTH (it MATCHed), the header
  decl is the stale stub-era guess, so conform the DECLS.
- §85 RETURN-AXIS WIDEN, all-or-nothing: 3,471 decl sites / 1,736 files, precondition verified
  (ZERO callers consume the return => byte-neutral by construction) + an R32 completion assertion
  (old-form decls remaining: 0). func_8014D820's s32 return is load-bearing — forcing `void` costs
  2 instructions (302 vs 304), so the decls had to move, not the draft.

TWO HONESTY ITEMS:
 1. I REPORTED "0 of 7 banked"; the true number was already 2. My diagnostic pass printed only
    lines starting with "- func_" (the failures) and hid its own successes while I read it for
    error text. A script that prints only failures cannot tell you it succeeded — the R32
    silent-skip shape aimed at my own instrumentation. Ground truth is the stub count (§55b(3)).
 2. A REAL FINDING fell out of that mistake: same drafts, same tree, minutes apart — gate_stage's
    full ladder banked 0/7 while bare harvest_verify banked 2/7. The LADDER REGRESSED two drafts
    the bare gate accepts (§19's "sig_unify regresses already-canonical drafts", one level up, and
    the exact mirror of SESSION-20's missing-ladder false 33%). Neither "always ladder" nor "never
    ladder" is right — run both, let the byte-gate arbitrate. One build per draft.

OPEN: func_8014D820 still a stub — after the widen its error moved from `conflicting types` to an
assembler-stage failure, not finished diagnosing. Recorded as open, NOT as a wall.
2026-07-27 09:58:17 -06:00
Drew T 09b1993059 feat(phase-29): T0.7 sweep (104 members) + BEHEMOTH func_8017D2DC banked (1,586 ins)
T0.7 — the §86 one-member probe applied to the remaining FREE families: 9 LIVE / 6 DEAD / 5 unstaged.
The three highest-value families by raw size (18,084 / 11,234 / 10,880 ins) all probed DEAD — the
probe skipped them instead of burning ~400 gate cycles rediscovering it. Swept the 9 live: 104 banked,
8 of 9 families fully cleared (func_8017BEF8 has 8 stragglers).

BEHEMOTH 2 of 3: func_8017D2DC (1,586 ins, ov_SC01_001) MATCHED and BANKED — closed in ONE agent
round, pin-free. Verified independently (R14): match_one MATCH (1586 ins).
  §81 carve chain: the agent predicted step 1 unnecessary; jtbl_carve REFUSED (the subseg already
  hosts a .rodata carve and the new table's start != span start). The refusal was RIGHT and is the
  instruction to run step 1 — jr_isolate_all --only (2 fns/1 object) -> BYTE-IDENTICAL, then
  jtbl_carve -> BYTE-IDENTICAL, then the ladder banked it.

R22 clean-fleet 140/140 BYTE-IDENTICAL; tools-health OK; dedup 1886/0; 0 NON_MATCHING (G4).
Fleet: instr 81.5 -> 81.6% · distinct-code 69.0 -> 69.1% · fn-count 89.49 -> 89.52%.
2026-07-26 22:02:37 -06:00
Drew T 772b5c4e02 feat(phase-29): the RETURN-axis fleet widen — 2 more families unlocked (cookbook §85); 140/140
Continues the "see why and try again" chain. Diagnosed all 4 T0.2 failures to 4 DISTINCT causes:
  func_8013D53C  240x123  §84 derived-offset remap bug        -> BANKED (previous commit)
  func_8012CC88  105x137  §73/§30#2 RETURN-axis conflict      -> BANKED here
  func_8014D12C   93x137  §73/§30#2 RETURN-axis conflict      -> BANKED here
  func_80144090  154x136  LENGTH-DRIFT (+13 B, ~3 ins long)   -> genuine codegen, real work

THE FAILURE THAT TAUGHT THE FIX: widening only src/shared/engine_core.h banked the member in the
TARGET overlay and BROKE ov_SC01_077 (R22 139/140) — the source overlay carries its OWN local
`extern void func_X(...)` decls, so a shared-header-only widen puts them in direct conflict. The
per-binary gate passed while breaking a binary it never built (§63/§61: a T2 write set is only
provable by R22). A half-done axis is a guaranteed break, not a smaller win.

THE FIX: do the WHOLE axis — 3,668 `extern void` decl sites across 2,688 files widened to `s32`,
0 remaining (R32 completion assertion). Precondition verified first: 0 callers consume the return
value, so the widen is byte-neutral by construction. R22 clean-fleet 140/140 BYTE-IDENTICAL;
tools-health OK; dedup 1886/0; 0 NON_MATCHING (G4).

MY OWN ERROR, recorded (§85 trap): I first spot-checked ov_SC01_077 with
`make build | grep | head; echo rc=$?` and read rc=0 as success — that is the exit status of `head`,
not make, and the output had no BYTE-IDENTICAL line. I reported a false BYTE-IDENTICAL in the
interim. Assert on the SUCCESS STRING, never on $? after a pipe.

Fleet: instr 80.6% (10,589,503) · distinct-code 68.3% (3,846,656) · fn-count 89.19%.
2026-07-26 15:22:21 -06:00
Drew T 398e653c92 fix(phase-29): §75a class-B remedy is the FULL §17a-1 pair — decl AND call-site cast
- The K&R-decl-only probe was HALF the fix, and cc1 said so exactly:
    ov_SC01_001_jr_801734BC.c:2616: too many arguments to function `func_8012F14C'
  `()` dissolves the DECLARATION conflict (the failure class moved PLUMBING -> CC1-FAIL), but the
  composite type after the TU's earlier `void func_8012F14C(s32);` prototype is still 1-param, so
  the macro's 3-arg CALL is a hard error. Reproduced by hand-splicing the macro into
  ov_SC01_001 and reading real cc1 stderr rather than trusting the classifier's `Error 33`.
- FIX = the other half of §17a-1 (what cast_call_sites.py does, and what §20 established): cast
  the call site so it does not depend on the TU's prototype at all —
    ((void (*)(s32, s32, s32))func_8012F14C)((s32)&mtx, (s32)&vec, (s32)&out)
  gcc-2.7.2 folds a cast of a KNOWN function symbol back to a direct `jal`, so the bytes are
  unchanged. Decl stays `()` so it cannot conflict in either declaration order.
- BYTE-GATED on the full existing radius: ov_SC07_006 7ca772be · 007 b3b95547 · 011 9885af74 —
  all BYTE-IDENTICAL.
- LESSON for §75a class B: the remedy is the PAIR, never the decl alone. A decl-only change moves
  the error from `conflicting types` to `too many arguments` and looks like a new wall.
2026-07-25 13:34:53 -06:00
Drew T 8f63c1a8e0 probe(phase-29): §75a class-B — K&R () for the carried func_8012F14C decl (func_80174CB0)
- The class-B arity split (1944 `(s32)` vs 968 `(s32,s32,s32)`) blocked func_80174CB0 in 131 of
  134 overlays: the macro carried the 3-param prototype, the failing TU declares the 1-param one
  FIRST (ov_SC01_001: TU@328 vs instantiation@2616), so cc1 sees two prototypes of different
  arity and rejects.
- Per cdecl.compatible's MEASURED gcc-2.7.2 behaviour a no-prototype `()` is accepted in BOTH
  orders here: prototype-first + ()-second always; ()-first + prototype-second when no parameter
  is altered by default promotion -- and all three args are s32, which does not promote. So one
  K&R decl should satisfy both populations regardless of where each TU declares it.
- Call site UNCHANGED (`func_8012F14C((s32)&mtx, (s32)&vec, (s32)&out)`): with a K&R decl the
  args pass under default promotions, and s32 args are unaffected -> same codegen.
- BYTE-GATED on the full existing radius before extending: ov_SC07_006 7ca772be · 007 b3b95547 ·
  011 9885af74 -- all BYTE-IDENTICAL. The extend result is the real test of the prediction.
2026-07-25 13:19:20 -06:00
Drew T 364ddd7055 fix(phase-29): ENGINE_SHB — the carried-#define gap that capped func_80165CA0 at ×3
- CAUSE (measured, not guessed): the 132 extend failures were `undefined reference to 'SHB'` --
  a LINK error, not a type conflict. SHB is not a symbol; it is a file-scope
  `#define SHB(x) __asm__(...)` sign-extension barrier. A body's preamble can carry `#define`s
  as well as `extern`s, but extraction lifts only the externs -- so the `#define` was left behind
  in the source overlay. In ov_SC01_077 it sits literally BETWEEN the two carried externs and the
  instantiation:
      extern s32 D_8011D030;
      extern s32 D_80126728;
      #define SHB(x) __asm__ __volatile__("" : "=r"(x) : "0"(x))
      DEFINE_func_80165CA0()
  The other 132 overlays DO define SHB -- ~300 lines further down the file (stub @4462 vs
  #define @4781 in ov_SC01_001), i.e. BELOW the splice point, so the preprocessor never expands
  it and cc1 emits a call to an undeclared `SHB`. Pure ORDERING; nothing was missing.
- Also explains why the 3 current members are EXACTLY the 3 files carrying the __volatile__ SHB
  spelling: that define is the function's own preamble, still sitting above its instantiation.
- FIX: engine_core.h owns the barrier as ENGINE_SHB (distinct name, so the overlays' own SHB --
  which exists in BOTH a volatile and a non-volatile spelling -- can never collide), and
  DEFINE_func_80165CA0's 7 uses now call it. Volatile form: what the 3 banked members compile
  with today. The body is now self-contained wherever it is instantiated.
- BYTE-GATED the full existing blast radius: ov_SC01_077 d19c9580 · ov_SC01_000 9052dc0e ·
  ov_SC07_006 7ca772be -- all BYTE-IDENTICAL.
- This is the dedup_propagate counterpart of Phase-27's family_remap._carry_macros (§75b).
2026-07-25 13:04:15 -06:00
Drew T 2fcb8de6bf fix(phase-29): normalize func_8014F468 to the fleet-canonical s32 (unblocks the ×138 reach) + §75
- THE PROPAGATION CAP WAS A MINORITY-SPELLING SOURCE OVERLAY, byte-censused:
    extern s32 func_8014F468(void);   1710   |  s32 func_8014F468(void)  134   <- fleet canon
    extern void func_8014F468(void);    20   |  void func_8014F468(void)   4   <- the outlier
  and ALL 4 `void` definitions are ov_SC07_{006,007,010,011} — the overlay the F3E8 body was
  banked from. dedup_propagate carries the source overlay's file-scope externs into the shared
  macro VERBATIM, so the macro inherited `extern void` and the 134 overlays that define the
  symbol `s32` rejected it. Propagation landed on exactly that 4-overlay island.
- The exclusion message ("byte-diverge / irreconcilable") is provably the wrong cause: members
  are selected BY h_exact, so all 138 are byte-identical by construction. It is a COMPILE
  conflict, never a byte one (same defect family as §68's mislabel, same tool).
- NORMALIZED the 24 minority occurrences to s32 (4 definitions + 19 overlay externs + the 1
  line in the freshly-authored macro). func_8014F468 is a pure inline-asm $sp-switch trampoline
  — no C-level value flow — and 134 overlays already PROVED s32 is byte-correct for the
  identical function. Fleet is now uniform: 1730 extern s32 + 138 s32 defs, 0 `void`.
- BYTE-GATED the complete blast radius (the 4 instantiators of DEFINE_func_8014F3E8):
  ov_SC07_006 7ca772be · 007 b3b95547 · 010 d7b5875d · 011 9885af74 — all BYTE-IDENTICAL.
- cookbook §75: census the carried extern before believing an exclusion message; prefer a
  majority-spelling source overlay; always pass --recover; after normalizing use dedup_extend
  (the body is already a macro) not dedup_propagate --addr.
2026-07-25 12:45:11 -06:00
Drew T 10ea5ff653 feat(phase-29): propagate the widen batch — func_8014D4C0 ×138; func_8014F3E8 ×4 (cause measured)
- func_8014D4C0 (84 ins) PROPAGATED ×138: all 138 overlays rebuilt byte-identical, group
  E_func_8014D4C0 registered. 84×138 = 11,592 ins.
- func_8014F3E8 (32 ins) propagated ×4 only (the ov_SC07_{006,007,010,011} island), 134
  overlays excluded one at a time.
- TWO FINDINGS, both measured:
  (1) THE FIRST RUN'S "drop" WAS A FLAG OMISSION, NOT A WALL. Without --recover,
      dedup_propagate takes the historical all-or-nothing path on the first culprit overlay,
      so ONE divergent member cost the whole group (×0). With --recover, Part A excludes just
      the culprit -> ×4 instead of dropped. Always pass --recover on a targeted --addr run.
  (2) THE EXCLUSION CAUSE IS A MINORITY-SPELLING SOURCE OVERLAY, not byte divergence. The
      sigs prove all 138 members share ONE h_exact (2ccf344d), so nothing diverges in bytes.
      The macro carries the source overlay's `extern void func_8014F468(void);` while the
      fleet census is 1,710 `extern s32` + 134 `s32` definitions vs 20 `extern void` + 4
      `void` definitions -- and all 4 `void` definitions are ov_SC07_{006,007,010,011}, i.e.
      the source overlay I banked from is the OUTLIER. The macro inherited the minority
      spelling and silently capped its own reach at that island.
- => the fix is NORMALIZATION (24 occurrences), not a reconciliation engine; the follow-up
  commit flips the SC07 minority to the fleet-canonical s32 and re-propagates.
- R22 clean-fleet: make clean && extract-all && check-all -> 140 passed, 0 failed of 140.
2026-07-25 12:42:24 -06:00
Drew T 1c0d29d91d feat(phase-29): §30#2 widen batch — func_8014F3E8 + func_8014D4C0 banked; §73 (the two axes)
- FLEET WIDEN (T2, one edit): extern void -> extern s32 for func_8014F3E8 + func_8014D4C0
  across src/** (16 decls in engine_core.h + 5,079 in 3,459 overlay .c; 0 `extern void`
  left, 0 pre-existing `extern s32`). Scope re-verified against the tree first (R14/R35):
  the SESSION-18 counts reproduce exactly and no decl exists outside the `extern void <name>`
  shape in any .c/.h under src/.
- BYTE-NEUTRALITY OF THE WIDEN ISOLATED FIRST: ov_SC07_006 7ca772be + ov_SC01_000 9052dc0e
  BYTE-IDENTICAL before splicing any draft (ov_SC01_000 chosen because it instantiates the two
  return-CASTING macros — the only sites a decl's return type could touch codegen).
- BANKED into ov_SC07_006 (both ×1, both reach ×138 by sig: single h_exact across 138/138):
  func_8014F3E8 (32 ins) on gate 1; func_8014D4C0 (84 ins) on gate 2.
- FINDING -> cookbook §73: the widen fixed only HALF the conflict. A def-side self-decl
  conflict has TWO independent axes — RETURN (fleet macro-widen, T2, R22-mandatory) and
  PARAMS (canonical param types + casts at each USE, T0, no fleet edit). func_8014D4C0
  failed the first gate on the PARAM axis (canon `void*` vs draft `u16*`); the §17a-1 move
  applied to the def's own signature banked it with nothing outside the draft touched.
  Diagnose the axis before reaching for the expensive fix.
- R22 clean-fleet: make clean && extract-all && check-all -> 140 passed, 0 failed of 140.
  make report: dedup 1884 validated / 0 failed, C1 coverage 239039/239039, 0 NON_MATCHING (G4).
  Fleet 80.0% instr / 67.7% distinct / 89.02% fn-count (the ×138 propagation is the value).
2026-07-25 12:24:30 -06:00
Drew T ba35785ec4 feat(phase-29): bank func_801777BC (59 ins) x138 — the giv-init base-register lever (§70)
- MATCH (59 ins), real-TU verified by the agent before handing back (cc1 rc=0, 59/59, 0 diffs).
- Propagated x138 with ZERO exclusions -> confirms the ×3 cap on func_80174CB0 was purely the
  carried-extern collision: a body with no externs propagates clean.
- R22 clean-fleet 140/140, 0 failed. dedup-check 1884 validated / 0 failed, C1 coverage complete.
- FLEET CROSSES 80.0% instr-weighted (10,509,526 / 13,141,652); fn-count 89.02%; distinct 67.7%.
- THE LEVER (cookbook §70): residual was ONE instruction, addiu $t0,$t1,0xC vs $t0,$a0,0xC -- a giv
  based on a copy of the param. Reading gcc-2.7.2 loop.c/cse.c proved the natural form can never
  emit the target: cse.c:make_regs_eqv makes the copy canonical (it out-lives a0) and
  loop.c:update_reg_last_use won't extend a0's last-use (giv-init UID >= max_uid_for_loop). Fix:
  walk the PARAMETER itself, so record_initial sees the biv init as hard reg (reg:SI 4),
  valid_initial_value_p accepts it (precondition: no calls), and emit_iv_add_mult bases the giv on
  $a0 -- yielding both required instructions free.
- META: this compiler-source reasoning was done by an ORDINARY Opus 5 drafting agent, unprompted --
  the tier Phase 23 reserved for Fable5. One data point, recorded as such; the cheap action is to
  give routine drafting agents the gcc source path.
2026-07-25 00:49:04 -06:00
Drew T e112eff601 fix(phase-29): find_site — a comment-only line halted the extern scan (§68); func_80174CB0 x1 -> x3
TWO mislabels in one tool, both found by making it print what the compiler actually said.

1) compiles_standalone() returned a bare False and the caller filed EVERY failure under
   "overlay-local TYPE (the real cap)". The dominant real cause is undeclared FILE-SCOPE EXTERNS.
   Now returns (ok, stderr) and the skip is classified by actual cc1 output.
2) find_site()'s backward walk over "preceding contiguous externs" skipped BLANK lines but not
   COMMENT-ONLY lines, so a full-line /* ---- */ between two extern groups dropped every extern
   above it. Comment lines are now skipped like blanks and filtered out of the emitted body so
   make_macro never meets a `//`.

RESULT, measured honestly: func_80174CB0 went from "not self-contained" to a 138-member PLAN, but
--recover banked only x3 (ov_SC07_006/007/011); 135 overlays excluded. Those exclusions are NOT
byte divergence (all 138 share h_exact) -- they are the CARRIED EXTERNS colliding with each target
overlay's own decls. The carry is necessary but not sufficient: it must reconcile per-target-TU
(cdecl.compatible(), the shape reconcile_tu already uses). Spec updated in CURRENT_PHASE.md.

- R22 clean-fleet 140/140, 0 failed. dedup-check 1883 validated / 0 failed, C1 coverage complete.
- fleet instr 79.9% (10,501,384 / 13,141,652); +246 ins from the x3.
- WHY THIS MATTERS beyond the numbers: the Phase-21 backlog already prescribed "macro-extern-
  injection frees them x134 (~+0.3%)" and it was never built, because the mislabel told every later
  session these were the known-hard type wall. A wrong diagnostic label cost ~4 phases.
- cookbook §68. NOTE the exclusion message is ALSO mislabelled ("byte-diverge / irreconcilable"
  conflates differing bytes with a non-compiling instantiation) -- logged to fix.
2026-07-25 00:17:08 -06:00
Drew T af59d8a630 feat(phase-29): bank func_80174CB0 (123 ins) — the §65g verdict was a wrong SIGNATURE
SESSION-17 filed this as §65g-class: "not 'run one more tool', but 'needs a transform that does
not exist yet'". Refuted. It needed the correct self-declaration.

- The TU expands DEFINE_func_80174C80() carrying `extern s32 func_80174CB0(s32, s32);`, while all
  ~100 prior drafts defined `void func_80174CB0(s32, s16)` — matches perfectly STANDALONE, dies in
  the real TU with `conflicting types`. Defining it `s32 (s32, s32)` and recovering param_2's
  s16-ness with an explicit (s16) cast at the func_80012558 use site is byte-identical.
- Drafted by an isolated agent (Opus 5 @ High, 65k tok) pointed at the NAMED blocker with the
  canonical callee sigs supplied — not asked to re-derive the C. It self-verified through the real
  cpp->cc1->maspsx->as chain (cc1 rc=0, 123/123 ins, 0 diffs) before reporting, so the bank was
  first-try clean.
- make check BINARY=ov_SC07_006 BYTE-IDENTICAL (7ca772be); R22 clean-fleet 140/140, 0 failed.
- Propagation ×138 follows as a separate targeted step (§55b: bank -> commit -> dedup_propagate --addr).
- FOLLOW-UP LOGGED: the recovery ladder also relaxed `extern s32 func_80174CB0(s32,s32)` -> `()` in
  src/shared/engine_core.h (+2 overlay files), escalating a binary-local bank to FLEET tier. The
  banked def AGREES with the original prototype, so that edit looks unnecessary — to be tested.
2026-07-24 23:43:15 -06:00
Drew T 25a02d6940 feat(phase-29): propagate 2 integration banks ×138 — fleet 79.7 -> 79.9% instr, R22 140/140
- func_8012B4B8 (84) + func_80169228 (105) propagated via targeted --addr (--check-only first,
  never --auto-from): 138 overlays byte-identical, 2 new dedup groups, ~+26,082 ins.
- R22 clean-fleet: check-all 140 passed, 0 failed of 140. Fleet fn-count 88.90 -> 88.98%.
- The 3 non-banks are diagnosed, not guessed (blocker_probe, both oracles agree): func_801463A0 is
  a real-cc1 MATCH in its own TU that the gate still rejects (§65c rtu-vs-gate divergence, link-level);
  func_80156670/func_80174CB0 carry "drop when banking" typedefs textually identical to the canonical
  ones. Blockers STACK — stripping the cc1-named typedef exposed the next (S8->B8; MATRIX->a callee
  conflict). Remedy named: strip ALL shared-provided typedefs, then run the DRIVER's ladder.
2026-07-24 20:01:31 -06:00
Drew T 32de37fff4 feat(phase-29): propagate func_80177940 x137 — 138 overlays byte-identical, R22 140/140
- Targeted `dedup_propagate --addr 0x80177940 --recover` (NEVER --auto-from; --check-only first
  confirmed the plan held exactly this one address, so the de-macroize hazard could not apply).
- 138 overlays rebuilt byte-identical; 0 stubs remain for the address; 1 new dedup group registered.
- R22 clean-fleet: check-all 140 passed, 0 failed of 140.
- Fleet: fn-count 88.86 -> 88.90%, instr-weighted 79.6 -> 79.7% (+13,938 ins = 101 x 138),
  distinct-code 64,874 -> 64,875 unique fns.
2026-07-24 16:41:44 -06:00
Drew T bf307f2827 feat(phase-29): s15 propagation (5 cores ×138) + crack-wave efficiency audit
- 5 of the 6 s15 fresh cores propagated ×138 (func_801483E8/8014680C/8017129C/80177AD4/801759D8;
  func_8014A51C §20-capped). R22 clean-fleet 140/140. fn-count 88.66->88.86%, instr 79.4->79.6%,
  distinct-code count 64854->64860, dedup 1879/0.
- EFFICIENCY AUDIT (decision-log): the 2 LLM waves ran 92% match_one MATCH but only ~27% whole-binary
  bank; 6 spot-checked non-banks are ALL match_one MATCH (byte-correct bodies). NOT a missing idiom —
  an INTEGRATION wall (def-side sig / data-extern / unshared struct). We strand ~16 paid-for correct
  functions per wave; a fleet-safe integration-recovery pass would ~3.7× yield for 0 new drafting
  tokens. Next investment = integration tooling, not more drafting. Waves held per Drew.
2026-07-24 11:17:05 -06:00
Drew T 6253238c43 feat(phase-29): s15 fresh-crack wave — 6 more reach-138 cores banked (R22 140/140)
wave_binary over 24 fresh reach-138 ov_SC07_006 families -> 22 match_one MATCH / 2 near.
Whole-binary byte-gate banked 6: func_8014A51C func_801483E8 func_8014680C func_8017129C
func_80177AD4 func_801759D8. R22 clean-fleet 140/140 (engine_core.h reconcile edits verified
fleet-wide, §61).

- The s15 drafter-prompt fix HELD AT SCALE: all 24 winners persisted to the canonical path
  (vs s14's 3/24, recovered from transcripts). match_one isolation (per-pid --work) confirmed.
- Consistent integration ceiling: ~22 match_one MATCH -> 6 whole-binary banks (27%), same as s14.
  The 16 nears are def-side plumbing / data-extern / struct-def reconcile the gate ladder doesn't
  clear; fix_header_decl is off-limits (fleet-blind, §63 UPDATE). Integration recovery is the lever
  to improve before the next batch, NOT the drafter prompt.
- 6 genuinely-unmatched cores -> distinct-code movers (propagation follows).
2026-07-24 11:07:11 -06:00
Drew T f1fd8993bf feat(phase-29): permuter overnight harvest — 29 fresh cores banked + distinct-code 64837->64854
The grinder ran the targeted permuter sweep to EXHAUSTION (all 75 permuter-shaped candidates;
correctly skipped 1575 redraft/structural/integration). It banked 29 distinct functions autonomously
(gate_stage commit=True, byte-gated, fail-closed, §55b un-propagated), 39% conversion.

- All 29 are LOW-REACH (1-5) overlay-unique code in the 0x8017-0x8018 range — confirming the map's
  finding that the permuter-admissible set is the low-leverage tail (the high-reach near-misses like
  func_8014F3E8 close=1 reach=134 are redraft/structural, NOT permuter-shaped).
- Propagation of the 22 reach>1 banks filled only 1 (0x80180710 ×2); the rest are genuinely
  overlay-unique (siblings byte-diverge) — as predicted.
- R22 clean-fleet 140/140 (the 27 overnight per-binary-gated commits verified fleet-wide, §61).
- distinct-code 64837 -> 64854 (+17 unique fns); session total +22 unique (wave +5, permuter +17) —
  the first real distinct-code progress in many sessions. instr 79.4%, fn-count 88.66%, dedup 1874/0.
2026-07-24 09:39:07 -06:00
Drew T 8ea5202135 feat(phase-29): propagate 1 fresh core ×138 + the session's FIRST distinct-code gain
Of the 6 s14 fresh cracks, func_80136F3C propagated ×138 (func_801749C8 dropped as an
ov_SC07_006 straggler; 4 are §20 local-type-capped — future uniquify fodder, low-value
de-duplication per the SESSION-14 finding).

THE POINT (byte-verified): distinct-code UNIQUE count rose 64832 -> 64837 (+5) — the FIRST
distinct-code movement all session. Every other lever today (154-type lift, 6 uniquify cores,
MATRIX rename) was de-duplication and moved distinct-code by 0. These 6 are genuinely UNMATCHED
cores, so banking them ×1 is real new coverage. Percentage is flat (67.6%, denom 87459) but the
direction and the count are the validation the pivot to fresh cracks was correct.

Fleet: instr 79.3 -> 79.4% | fn-count 88.61 -> 88.65% | distinct-code count +5 | dedup 1873/0.
R22 clean-fleet 140/140 BYTE-IDENTICAL.
2026-07-23 22:58:47 -06:00
Drew T e9c950a30c feat(phase-29): fresh-crack wave s14 — 6 reach-138 cores banked ×1 in ov_SC07_006 (R22 140/140)
Ultracode wave_binary over 24 FRESH (unmatched, live=138) ov_SC07_006 families -> 20 self-reported
match_one MATCH. The whole-binary byte-gate (sole arbiter, R14/G3) banked 6:
  func_8014C6F4 func_801463A0 func_8012B77C func_80136F3C func_80156670 func_801749C8
The gap (20 claimed -> 6 banked) is the integration wall the drafters named: §63 header-decl
(void->s32), data-extern reconcile, struct-guard — a recovery pass follows. R22 clean-fleet 140/140
(the gate_stage ladder's engine_core.h reconcile edits verified fleet-wide, not just per-binary).

These are GENUINELY UNMATCHED cores (unlike the session's earlier propagation work), so once
propagated ×138 they move distinct-code — the metric that sat flat at 67.6% all session.

⚠️ WORKFLOW RECOVERY: the 24 drafters reported MATCH but wrote winners under scratch filenames;
only 3 func_<name>.c persisted. All 24 were recovered from the per-agent transcripts (Write calls
+ Bash heredocs) -> .run/drafts-s14r/. wave_binary.js drafter prompt hardened to force a copy-back
+ existence check as the mandatory final step so a future wave can't lose its winners this way.
2026-07-23 22:44:58 -06:00
Drew T d1a1d756e0 fix(phase-29): PsyQ MATRIX name hazard — the true 32B layout now owns the canonical name (R22 140/140)
Oracle (G1, Ghidra types get, /LIBGTE.H, psyq400.gdt): MATRIX = 32 bytes (short m[3][3] @+0x00,
long t[3] @+0x14, 2B pad after m); SVECTOR = 8B; VECTOR = 16B (long vx,vy,vz,pad).

- HAZARD CONFIRMED: the fleet-wide name `MATRIX` held {s32 m[3][3]; s32 t[3]} = 48 BYTES, not a PsyQ
  type at all, while THREE other names (MATRIX_c1, MATRIX_c2, MATRIX2) held the true 32B layout. The
  canonical name carried an invention; any future reader assuming PsyQ semantics would be misled.
- FIXED by pure consistent rename across 205 files: 48B invention -> MATRIX_L48 (KEPT — ~131 files are
  byte-correct against it, and "fixing" it to 32B would change sizeof/array stride hence codegen);
  the true 32B layout now owns MATRIX. R22 clean-fleet 140/140 BYTE-IDENTICAL.
- VECTOR left UNCHANGED on purpose: ours is 12B vs PsyQ 16B (missing trailing pad). I first called it
  dead — wrong, it has 1 live use (engine_core.h gte_ldlv0((VECTOR*)sp)). Offsets already agree so a
  fix is likely byte-neutral, but it is a LAYOUT change and bundling it with a rename would make an
  R22 failure ambiguous. Own R22-gated commit, later.
- engine_types.h gains an oracle-sourced GROUND-TRUTH block: real PsyQ layouts, which of our names are
  true vs invented, why MATRIX_L48 must not be "corrected", and the draft-time rule (address-suffix
  anything you invent — 7 of the 8 collisions this fleet accumulated were bare generic names).
- SCOPE HELD: renamed + documented; did NOT force existing code onto real PsyQ definitions.
2026-07-23 21:35:07 -06:00
Drew T 22af9ab2c5 feat(phase-29): 3 Vec8-freed cores ×138, R22 140/140 — and the honest ROI verdict on the cap
- Propagated 0x8012A464 / 0x8014FFDC / 0x801502EC -> 138/138 byte-identical, 0 stragglers, 3 new
  groups. R22 clean-fleet 140/140; dedup 1872/0; C1 237654/237654.
- FINDING (R14/R31): the §20 propagation cap was gating source-level DE-DUPLICATION, not coverage.
  The whole uniquify campaign (Buf+MATRIX+Vec8, 223 files renamed, ~1559 copies stripped, 5
  propagations, 4 R22 cycles) moved the fleet by +6 functions / +558 ins / -6 stubs and 0.00pp on
  all three headline metrics. The freed cores' members were ALREADY matched individually;
  propagation just consolidated them into shared macros. "Unblocked" != "unmatched".
- SESSION ATTRIBUTION: of -837 stubs / +0.3pp instr / +0.23pp fn-count, -831 stubs came from the
  FIRST batch (broad lift -> 13 cores). The uniquify campaign contributed -6.
- Roadmap B4 re-labelled: a maintainability item, not a coverage lever. Remaining camps
  (Handler/Blk8/V8/Prim/Prim_8016E7C8) are small and now known low-yield — opportunistic only.
- distinct-code sat at EXACTLY 3811442/5634875 = 67.6% at open and close. Fresh cracks are the sole
  mover of that number; point the next session there.
2026-07-23 21:25:39 -06:00
Drew T 23b9b57505 feat(phase-29): uniquify+lift Vec8 camps + propagate 0x8012E778 ×138; blocked queue 10 -> 7
Two units, committed together because they touch overlapping overlay .c files.

- PROPAGATE: 0x8012E778 (freed by the MATRIX uniquify) -> 138/138 byte-identical, 0 stragglers,
  1 new dedup group.
- Vec8 UNIQUIFY+LIFT: camp1 {s16 unk0,unk2,unk4,unk6} (8 bytes) x139 files -> Vec8_c1; the 180-file
  {s32 w[8]} (32 bytes) majority keeps the name. These are two genuinely DIFFERENT types that had
  been sharing one identifier across TUs of the same overlay — the case §64a exists for; reconciling
  them to one layout would have merged a 32-byte and an 8-byte struct. Both camps lifted, 319 local
  copies stripped.
- Pre-filtered on an overlay from each camp, then R22 clean-fleet 140/140 BYTE-IDENTICAL.
- Blocked core queue 10 -> 7 (0x8012a464, 0x8014ffdc, 0x801502ec freed). Session arc 13 -> 7 via
  uniquify (Buf -> MATRIX -> Vec8). Remaining camps all small: Handler, Blk8, V8, Prim, Prim_8016E7C8.
2026-07-23 21:15:58 -06:00
Drew T e393c320e6 feat(phase-29): VARIANT camps -> UNIQUIFY (not reconcile); validated on Buf, R22 140/140 (§64a)
MEASUREMENT CORRECTED THE PLAN. The checkpoint called for a "per-camp field-access reconcile";
measuring the camps refutes that: Vec8 = {s32 w[8]} (32B) in 180 files AND {s16 unk0..} (8B) in
139 files; MATRIX 48B/32B/32B; Buf 16B / 0x20+ / DrawEnv. These are DIFFERENT types sharing an
identifier across TUs of the same overlay — reconciling to a canonical layout MERGES them, the
same failure that broke 103 binaries on Prim. The right op is UNIQUIFY: rename the non-majority
camp (byte-neutral — a type name emits no code; TU-local by construction), which makes every camp
single-def and liftable by the existing lift_types rules.

- NEW tools/uniquify_type.py: deterministic camp ordering (file-count desc, then normalized text,
  so re-runs assign the same suffixes); majority keeps the name, camp n -> <T>_c<n>; rewrites ONLY
  files that DEFINE that camp (a file that merely USES the name gets it elsewhere and is untouched);
  \bT\b word boundaries so `Buf` never matches `Buf80153978`.
- VALIDATED on Buf (578/6/1 files): 11 identifiers across 7 files -> 3 camps LIFTABLE -> lifted
  (585 local copies stripped) -> R22 140/140 -> blocked core queue 13 -> 11 (0x8012ea90, 0x801749c8
  freed). Propagated 0x8012EA90 ×138; 0x801749C8 dropped (straggler in ov_SC07_006).
- YIELD, HONESTLY (P9): ZERO new matched functions. fn-count 88.61% / instr 79.3% / stubs 40281 all
  UNCHANGED; dedup 1867->1868, C1 +138. 0x8012EA90's members were ALREADY matched in all 138
  overlays — the propagation consolidated duplication into one shared macro (DRY), not coverage.
  The value is the PROVEN RECIPE + the queue moving 13->11, not the numbers.
- dedup_propagate (R32): the skip line printed a COUNT and no names, and aggregated three unrelated
  causes into n_local — a body skipped merely for a `//` comment (macro-unsafe, 1-line fix) read
  identically to one genuinely using an overlay-local type. Now named and split by cause.
- cookbook §64a (uniquify-vs-reconcile + the validated recipe + remaining camps by cost).
2026-07-23 20:51:42 -06:00
Drew T 3642b5458a feat(phase-29): the type-lift's payoff — 13 cores propagated ×138, −831 stubs, R22 140/140
With the §20 local-type cap lifted (commit:0863), dedup_propagate --auto-from planned 17
self-contained cores that were previously skipped "not self-contained (local types)".

- BANKED: 12 cores via --auto-from + func_80175308 (propagated separately, 138/138) = 13 ×138.
  func_80175308 is the PROVABLE unblock — the core the SESSION-13 checkpoint named as
  local-type-blocked. No claim is made that all 17 were unblocked by the lift; measuring that
  needs a pre-lift re-scan I did not run (P9).
- 5 correctly DROPPED as cross-overlay stragglers (0x8012A018, 0x80172C50, 0x80173A60,
  0x80144090 in ov_SC01_000; 0x801495C4 in ov_SC07_006): h_exact sharing is all-or-nothing and
  those overlays' bytes diverge. --recover NOT used (the documented quadratic thrash hazard).
- GATES: R22 clean-fleet 140/140 BYTE-IDENTICAL (2nd full cycle this session); make report green;
  dedup-check 1854 -> 1867 validated / 0 failed, C1 236964/236964; 0 NON_MATCHING (G4).
- FLEET: instr 79.0 -> 79.3% | fn-count 88.38 -> 88.61% | INCLUDE_ASM stubs 41112 -> 40281 (-831).
  distinct-code stays 67.6% — correct: propagation replicates already-distinct-matched code;
  only a fresh crack moves that number.
- STILL BLOCKED: 13 cores "not self-contained (local types)", blocked by exactly the 8 deferred
  VARIANT entities (MATRIX 3-def, Buf 3-def, Vec8, Prim, Handler, Blk8, V8, Prim_8016E7C8).
  Next lever = a per-camp FIELD-ACCESS RECONCILE, not a lift (lifting them blindly is what broke
  103 overlays earlier this session).
2026-07-23 20:18:50 -06:00
Drew T b3597c08e0 feat(phase-29): 2 §20-unblocked cores propagated x138 (+276) via the type-lift
func_8012B4B8 + func_8012E138 — freed by the Mat32/Cam8012E138 fleet lift
(commit:0859) — propagated x138 (live 138->0 each, +276 stubs). R22 clean-fleet
140/140. No --recover needed (clean h_exact).

decision-log: the §20 type-lift is safely executable when SCOPED to clean types
(lift_types.py + R22); classify-first, lift the 1-def/copy-only-variant types now,
defer the fleet-split variants (MATRIX/Vec8/Buf/M8) to a per-camp reconcile pass.
2026-07-23 18:04:44 -06:00
Drew T 1dd80e9287 feat(phase-29): ov_SC07_006 fresh-138 — 2 cores propagated x138 (+274) + integration-wall finding
Propagation of the 7 fresh-138 cores banked in commit:0855. Only the 2 self-contained
ones cleared all three integration walls:
- func_80130C08 x138, func_80137178 x138 (+274 stubs). R22 clean-fleet 140/140.

The other 5 are blocked, each by a different integration wall (drafting was solved —
all 7 bodies byte-matched; INTEGRATION is the bottleneck):
- func_8012B4B8/func_80175308/func_8012E138/func_8012A1BC: §20 local-type
  propagation cap ("not self-contained") — need build_engine_types type-lift to
  propagate x138 (roadmap B4; ~+552 stubs when unblocked). Stay x1.
- func_80169228: per-member divergence (whole SC03 cluster byte-diverges) — a
  genuine partial family; --recover thrashes it (killed + reverted). Stays x1.

decision-log: fix_header_decl fragility correction (shared multi-caller decls break;
gate_stage's call-site-cast is the integration spine, not header-decl rewriting).
2026-07-23 17:07:29 -06:00
Drew T 3c8fd8a0b0 feat(phase-29): ov_SC07_006 fresh-138 wave — 7 x1 core banks (gate_stage reconcile)
Crack wave w9lidyi5b (24 fresh LIVE=138 families): 20 self-assessed MATCH, 3 near.
Banked x1 (R22 clean-fleet 140/140):
- 2 self-contained via plain harvest_verify: func_8012B4B8 (§52b-wall crack),
  func_80169228.
- 5 via gate_stage's reconcile ladder (cast_call_sites in the draft's own TU):
  func_80175308, func_8012E138, func_80130C08, func_8012A1BC, func_80137178.

Correction (decision-log follow-up): fix_header_decl v1/v2 is FRAGILE for shared
multi-caller decls — rewriting an engine_core.h decl breaks callers that use the
return differently (CC1-FAIL). func_8014CD80 was a lucky single-caller/ignored-return
case. gate_stage's call-site-cast is the right tool for multi-caller plumbing (banked
5 where fix_header_decl broke the build). Remaining ~13 near/deeper-plumbing drafts
staged in .run/drafts-sc07006-fresh/. Propagation x138 next.
2026-07-23 13:55:29 -06:00
Drew T 7f18dbad2f feat(phase-29): func_8014CD80 x138 — the fresh-138 def-side blocker is RECOVERABLE (R35 reversal)
Bounded probe (SESSION-13, token-free) that REVERSED the same-session "fresh
reach-138 well is spent" verdict. Target func_8014CD80: 138 live, 0 matched, NO
DEFINE macro, a universal body (only universal callees + param offsets, zero
overlay-local D_* refs), clean MATCH draft from batch-1.

- Blocker was a def-side header decl: engine_core.h DEFINE_func_8014CD0C()
  forward-declares it `void func_8014CD80(s32,void*,void*)` while the byte-true
  def is `int func_8014CD80(s32,u16*,u16*)`. gate_stage's arity pre-pass is
  param-COUNT-only (misses return/ptr-type); §54 reconcile_def_sig fixes the
  wrong direction.
- One byte-neutral header edit (void->int, void*->u16*; call site passes u16[3]
  arrays + ignores the return -> codegen unchanged) -> harvest_verify banked x1
  BYTE-IDENTICAL -> dedup_propagate --addr propagated 138/138 overlays
  byte-identical (live 138->0) -> R22 clean-fleet 140/140.
- Fleet 78.7->78.8% instr, 88.22->88.26% fn-count from this one family;
  tools-health green (dedup 1851/0).

Quantified market (decision-log 2026-07-23): of the 75 fresh (>=100-live)
families, 46 carry an engine_core.h caller forward-decl, 38 SIMPLIFIED = the
func_8014CD80 pattern -> each a candidate x138 (~+1.5-2.8pp instr). NEXT: build
tools/fix_header_decl.py + a fresh-family wave. func_80165CA0's 0/135 was a
non-universal BODY (different failure mode), not this blocker.
2026-07-23 12:06:26 -06:00
Drew T 57ef4ebcb5 feat(phase-29): ov_SC07_006 reach-138 batch-1 propagation + live-count re-scope (SESSION-13)
Propagation of the 6 batch-1 x1 banks (§55b: banks committed first in commit:0848,
then targeted propagate as a standalone step):

- dedup_propagate --addr: func_801325B8 -> +3 onboarded-tail siblings
  (ov_SC07_007/010/011). func_8014A048/func_801678F0 byte-diverge in the SC07
  cluster (kept x1); func_8014FE60/func_80167540 local-type-blocked §20 (x1).
- func_80165CA0: consolidated its h_exact subgroup (dedup group registered, +0
  new), then family_sweep --hseq 0/135 — a PER-MEMBER WALL (cf func_80133AB0
  0/136). The x135 "fresh family" prize does not exist here.
- Net batch-1 yield ~9 newly-matched functions; fleet 78.6->78.7% instr, distinct
  flat; ov_SC07_006 84.6->84.8%. R22 clean-fleet 140/140; tools-health 1850/0.

The finding (R14/R35, decision-log 2026-07-23): nins*reach leverage over-counts —
rank by LIVE-siblings. build_wave_args.py --rank live now ranks by the true lever
and reports the fresh(76)/onboarded-tail(44) split. The reach-138 family well is
largely SPENT via wave+gate; the fresh families are the hard tail (def-side
plumbing/DIFF/per-member walls), not free x138 fuel.
2026-07-23 11:43:28 -06:00
Drew T b76ad85157 feat(phase-29): ov_SC07_006 reach-138 crack-wave batch-1 — 6 x1 banks
Option (b) from the SESSION-12 checkpoint: fresh-exemplar crack-wave on the
P27-onboarded ov_SC07_006 (84.6% -> 84.8%). New reusable builder
tools/build_wave_args.py emits wave_binary.js args from a fuel manifest.

- Drafting wave (wave_binary.js, 24 xHigh drafters over the top-24 reach-138
  WAVE families by leverage): 16 self-assessed MATCH, 8 hit the session usage
  limit (redraft later).
- Byte-gate: plain harvest_verify banked 2 (func_801325B8, func_80165CA0);
  gate_stage reconcile ladder (arity pre-pass + cast/sig_unify) banked +4
  (func_8014FE60, func_8014A048, func_801678F0, func_80167540). 7 near, 6
  reconcile-fail, 2 CC1-FAIL, 2 DIFF (the incomplete session-limit drafts).
- R14/R35 leverage reality-check: nins*reach over-counts. 5 of 6 are already
  matched in ~135 overlays (only the onboarded SC07 tail ov_SC07_007/010/011
  is live, +2-3 each). func_80165CA0 is a TRUE fresh family (135 live) — the
  x135 sweep prize, propagated next.
- R22 clean-fleet 140/140 (engine_core.h arity edit fleet-safe); tools-health
  green (dedup 1849/0). Propagation is the next commit (§55b: banks first).
2026-07-23 10:51:36 -06:00
Drew T 11a22b5c77 feat(phase-29): func_80167714 propagated ×134 (h_exact; 4 SC07 byte-diverge, kept ×1) 2026-07-22 15:18:58 -06:00
Drew T 64bfe59bc0 fix(phase-29): gate_stage gated EVERY non-077 binary against ov_SC01_077's SHA — one-line default, one month
THE BUG (tools/gate_stage.py main(), introduced commit:0181, 2026-06-21, Phase 21 T3):

    good_sha=a.good_sha or DEF_SHA,      # DEF_SHA = ov_SC01_077's locked hash

DEF_SHA is TRUTHY, so it beat run_gate's per-binary lookup
(`good_sha or _check_sha(binary) or DEF_SHA`) and made that lookup DEAD CODE on
every CLI invocation. gate_stage therefore BUILT one binary and compared it to a
DIFFERENT binary's hash: it can never match, every draft reports as "near", and
NOTHING COULD EVER BANK outside ov_SC01_077 from the CLI. A "near" is
indistinguishable from a genuine codegen residual, so the failure looked like a
compiler wall for a month.

WHY IT HID: the programmatic callers take a different path and were all correct —
grinder/idiom_hunt pass good_sha=None (per-binary lookup), lora_grind/bulk_harvest
pass an explicit per-binary sha, orchestrator is 077-only where DEF_SHA is right.
That is exactly why the grinder banked func_80181F78 in ov_SC03_014 (Task 13B)
while my CLI ladder banked 0/10 on the same tree. Two paths disagreed for a month
and nothing compared them (R34's lesson, from the inside).

BLAST RADIUS, MEASURED (not assumed): 0 of 6,708 backlog records come from the
affected path — by source: worker 2724 / bulk-harvest 2275 / lora-grind 766 /
grinder 522, all correct. THE BACKLOG NEEDS NO RE-RUN. The void verdicts are the
manual CLI gates on non-077 binaries, i.e. exactly the Task-5 wave's "the gate
banked ZERO" on 12 preserved cracks — never a codegen finding at all.

FIXED: pass a.good_sha through; run_gate reads config/check.<bin>.sha (R33).
VALIDATED end-to-end: the raw draft that produced {banked:0, near:1} now gives
{banked:1}.

RE-RUN RESULT — 7 of the 12 preserved t5wave cracks are now banked:
  func_8018F694 (478) · func_8019059C (673) · func_80135A4C (181) ·
  func_80135888 (113) · func_80135D20 (100) · func_801749C8 (105) ·
  func_801299C8 (158, was filed "PLUMBING: prototype declaration")
STILL BLOCKED (5, believed genuine): func_8012AAAC, func_80135260, func_801365B8,
func_80165CA0, func_80191C50.

⚠️ SUPERSEDES the earlier retraction: the "0/10 ladder" was not vague interference
— it was the gate comparing against the wrong binary's hash. Task 14 stages 2-3
were priced against a number that could only ever have been zero.

- R22 clean-fleet 140/140 BYTE-IDENTICAL; all 6 verified stub-free
2026-07-22 14:12:32 -06:00
Drew T 1074f2f202 feat(phase-29 Task-14 stage 1): the ARITY pre-pass — and the shared-state constraint it cost
DIAGNOSED, not assumed. The 12-draft integration probe banked 1/12 and reported the SAME
label for 10 of the 11 failures: `conflicting types for built-in function 'memcpy'` — the
§58 red-herring (a WARNING, from an unrelated TU position). Splicing three top-reach
failures individually and reading real cc1 stderr gave the actual causes:
  conflicting types for `func_XXXX'     3/3   <- loose-typing ARITY conflict
  redefinition of `struct V8'                 <- a SECOND class (type-lift), stage 2

A banked shared caller macro in engine_core.h declares the function with FEWER params than
its byte-true definition takes (the original calls K&R-style with fewer args than the callee
reads); a C89 prototype makes that a hard error. tools/fix_arity_callers.py --any-proto
already fixes it and was simply NEVER WIRED into gate_stage's ladder (only family_sweep
carried §57). Now wired as a TU-side pre-pass.

MEASURED: 2 of 7 top integration candidates banked (func_8016EFC8, func_80164418, both
reach-138) vs the 1/12 old-ladder baseline. R22 140/140; tools-health OK (dedup 1848/0).

INCIDENT — this stage BROKE 138/140 AND R22 CAUGHT IT (nothing was ever committed):
pairing `--apply --any-proto` with `--revert` for the unbanked drafts corrupted declarations
fleet-wide. `--revert` rewrites ()->(void), which inverts a PLAIN apply but NOT --any-proto,
so an unbanked fn whose real decl was `extern void func_801708B0(void *a0)` came back as
`(void)` — in engine_core.h (included by all 138 overlays) and 6 sites in ov_SC01_077's own
sources. harvest_verify --binary ov_SC01_077 reported BYTE-IDENTICAL and was RIGHT about that
binary; the other 137 were structurally invisible to it. Repaired to the exact lines.

ROOT CAUSE FIXED: the ladder now snapshots every file the pre-pass touches and undoes by
RESTORE + re-apply-for-the-banked-set-only — exact by construction, cannot invent a signature.

NEW HARD CONSTRAINT (cookbook §61): any ladder stage mutating SHARED state must be undone by
snapshot restore, never an inverse transform, and validated FLEET-WIDE (R22) rather than by
the per-binary gate that authorised it. §55b's propagation law, one level down. The planned
type-lift stage edits engine_types.h and inherits it by default.

ALSO FIXED: the first wiring passed only --drafts (the narrow-param FILTER) without the
required --funcs, so the stage exited `no funcs given` as a SILENT NO-OP and the gate reported
0/6 as though diagnosed. sh() does not raise on non-zero exit -> explicit rc check added.
2026-07-21 18:19:04 -06:00
Drew T 5c894c1e62 feat(phase-29 Task-13B): func_80141B90 x138 + the reach repricing + the length profile
PROPAGATION (§55b, its own targeted batch): dedup_propagate --addr 0x80141B90 --recover
-> "138 overlays byte-identical after propagation"; 117 remaining stubs -> 0; 1 new
dedup group. This was the ONLY one of the 21 directed-run banks worth propagating.

THE REPRICING (R14 — measure a bucket's VALUE, not just its conversion rate):
the directed run converted 27% (21/77) but moved the fleet ~0.03pp, because h_exact
reach of the 21 is: func_80141B90=138, TEN at reach-1 (nothing to propagate), rest 2-10.
Instruction-weighted, the ENTIRE permuter bucket is worth ~0.36pp at 100% conversion.
The mechanism is validated; the fuel was small. Priced frontier (ins-weighted / 13.08M):
  LENGTH-DRIFT |d|<=2   472,178  ~3.6pp  (339 fns)   <- the real permuter-adjacent lever
  integration           419,162  ~3.2pp  (305 fns)   <- Task 14's ladder
  WIDTH                  71,593  ~0.55pp (45)
  permuter (current)     46,571  ~0.36pp (74)
  BRANCH-POLARITY         9,462  ~0.07pp (22)
So WIDTH/BRANCH-POLARITY are NOT worth prioritizing; my earlier "~200 candidates"
framing undersold LENGTH-DRIFT 10x and oversold WIDTH.

NEW: permuter_weights._LENGTH profile (perm_temp_for_expr/perm_expand_expr are the only
passes that change instruction COUNT; the reorder/decl-order levers that dominate the
regalloc+schedule profiles cannot, so they are down-weighted here) + residual_class
._drift_route (|d|<=2 -> permuter/`length`, larger stays structural — same class,
opposite tool) + classify() accepts a PROFILE NAME directly (the measured profile beats
re-parsing a free-text label). 17 unit tests green.

grinder: --profile filter (probe ONE residual class's conversion) + a PERSISTENT attempt
ledger. `tried` was in-process only, so every fresh --once run re-permuted the previous
run's losers — the permuter is deterministic given (base.c, target.o), so that CPU can
never produce a new win. Measured: a 20-target probe drew 19 already-tried targets.
Keyed by draft_sig so an improved draft legitimately re-opens the function.
2026-07-21 15:05:56 -06:00
Drew T bffbb8b9b7 feat(phase-29 crack-wave3): func_8016B234 + func_8016C998 banked ×1 in ov_SC01_077
- func_8016B234: §58b self-def — engine_core.h func_8016B234 (void)->() no-proto
  (byte-neutral: only 0-arg callers fleet-wide); typedef preamble stripped.
- func_8016C998: §59(1) local struct rename Slot/Blk32->Slot_998/Blk32_998
  (collide with TU's Slot) + D_801D9CA0 extern moved to block scope (TU's other
  decls of it are all block-scope; a file-scope one collided).
R22 clean-fleet pending (engine_core.h touched).
2026-07-19 11:47:54 -06:00
Drew T 2605f206d3 feat(phase-29 crack-wave): func_80150170 ×138 dedup-propagate (+137, 138/138)
The hexR=138 dedup core (banked ×1 in commit:0716) -> dedup_propagate --addr
0x80150170 --source-overlay ov_SC01_077 --recover: 138 overlays rebuilt
byte-identical, 1 new group registered in config/dedup.us.yaml (0 stubs left).
~+13k ins (95 ins × 137 new members). (First attempt SIGTERM'd mid-gate at the
2-min timeout -> reverted the half-gated state, re-ran clean fail-closed.)
2026-07-18 23:15:06 -06:00
Drew T c9e12a079b feat(phase-29 crack-wave): +6 cores banked ×1 in ov_SC01_077 (R22 140/140)
Ultracode 11-core crack-wave over the freshly-regenerated draftable structural
frontier (R35: the Jul-14 manifest still listed already-banked families). 9
match_one MATCH / 2 near; 6 of 9 banked whole-binary byte-identical.

Banked (ov_SC01_077, ×1 — ×138 sweep deferred, Drew paused after the bank):
- func_80150170 (95, hexR=138 dedup core) — engine_core void->s32 narrow
- func_8016D1D8 (148) — data-label + typedef-scope
- func_8016D688 (60)  — data-label (D_801D9C20)
- func_80165240 (63)  — normalize_self_decls (caller-decl -> void(void*x3))
- func_80164E40 (25)  — engine_core void->s32 narrow
- func_801457A4 (79)  — -O0 (relocated into _o0b object)

- engine_core.h: 3 decls narrowed void->s32 (byte-neutral fleet-wide; callers
  ignore the return) — R22 clean-fleet 140/140 confirms neutrality.
- config/symbols.ov_SC01_077.txt: D_801D9C20/60 u8 data-label mirror so a
  re-extract re-emits the labels the D1D8/D688 banks reference (R22 corollary;
  fixed a type:data->type:u8 splat-format bug that broke ov_SC01_077 extract).
- 3 NOT banked (801549F8, 8013BD74, 8013C0F8): all match standalone, blocked
  ONLY by the §8 jtbl-rodata carve (NOT codegen; C0F8 was NOT a real DIFF).
- .run/giants: 2 near (8014D820 close-11 intrinsic-sched, 8012E364 close-22)
  + the 3 jtbl-blocked drafts preserved (R20).

R22 clean-fleet: 140/140 byte-identical; tools-health OK (dedup 1846/0,
C1 234205/234205); 0 NON_MATCHING linked (G4). Fleet 75.2/60.6/87.04 (flat —
×1 banks; the ×138 sweep is the deferred fleet-mover).

cookbook §58 (R30): match_one MATCH != bank — it compiles standalone so it is
blind to (a) Ghidra symbol names, (b) def-sig conflicts vs the fleet, (c)
callee-decl conflicts, (d) -O0-vs-O2; crack-wave drafts need a reconcile pass.
2026-07-18 22:58:15 -06:00
Drew T 1cb018bc00 feat(phase-29 §8e): bank giant func_8013F350 (490) x1 — the 4-table [0,0,4,0] span + tables= persistence
- jtbl_carve §8e hardening (the F350 lesson): a pre-§8e Phase-26 merged-double span had NO
  recoverable structure — spec derivation now uses the payload ZERO-WORD rule over persisted
  table starts (tables= comment on the JTBL_PADS line), with source priority
  {untouched+line=reuse verbatim | untouched+no-line=skip | touched=union of .s refs,
  line tables=, --span-tables override, --like exemplar role-transfer}; spec_from_starts
  replaces interval-carry; None-tolerant legacy comments; --like/--span-tables CLI.
- F350 carve: tables 8860(8e)+8880(5e,trimmed) fused BEFORE the existing 8898/88B8 double via
  the zero-checked 4-gap -> ov_SC01_077.o JTBL_PADS := 0,0,4,0 (tables= persisted).
- splice reconciles (§56, byte-neutral): §30#2 def-side widen void->s32 (TU extern +
  engine_core discarding-caller macro extern); D_80115158/D_8011515C macro-canonical redecls
  + §18 width-preserving store casts (sh under u8[]/u8); func_801416D4 canonical (s16) redecl
  + §17a-1 fn-ptr (s32) call cast; D_80187BD0 block-scalar decl dropped (file array covers).
- whole-binary gate [ OK ] sha1 d19c9580 == check. 3 of 4 giants now banked x1.
2026-07-18 02:55:34 -06:00
Drew T d6db1343b8 feat(phase-29 T4): type-lift + propagate 2 local-type cores x138 (func_8014E284, func_80137DD4)
The 2 Task-3 cores banked x1 but skipped by dedup_propagate ("not self-contained: local types").
Lifted EntSC01077 (func_8014E284) + P_TAG_80137DD4 (func_80137DD4) into src/shared/engine_types.h
(fleet-included via engine_core.h), and inlined func_80137DD4's file-local `#define OTE` into the body
(byte-neutral macro expansion, re-evaluated per use to preserve codegen). Both now self-contained ->
dedup_propagate --recover = 138 overlays byte-identical, 0 stragglers, 2 new dedup groups.

~+32.7k ins (108+129 x138). R22 clean-fleet 140/140 byte-identical; tools-health OK; dedup 1846->1852;
C1 coverage 234205. §55c local-type propagation cap lifted for these 2.

SESSION-2 close: this session banked ~94k ins across 4 fns x~137 overlays (2 non-jtbl giants fully
propagated + this 2-core type-lift); fleet 71.4->72.1% instr (+0.7pp), 140/140 throughout. The 4 jtbl
giants remain deferred on the byte-proven 8-align jtbl-carve gap (root cause half-pinned: cc1+maspsx
both emit .align 2, so the +4B pad is a downstream as/ld_interleave artifact) -> teed up as the next task.
2026-07-17 18:37:00 -06:00
Drew T c7fedced10 feat(phase-29 T4): propagate giant func_8014F4C0 (141) x134 + bank x1
Task-4 giant-bank #2. func_8014F4C0 (141 ins) banked x1 in ov_SC01_077_after.c (its earlier
"gate reject" was pure §55b propagate-damage — gated clean on the healthy tree, no fleet change).
h_exact family -> dedup_propagate --addr 0x8014F4C0 --recover: ov_SC01_000 was a cross-overlay
straggler (all-or-nothing h_exact), --recover reconciled the conflicting caller externs and kept
it -> 134 overlays byte-identical after propagation, +1 dedup group in config/dedup.us.yaml.

R22 clean-fleet 140/140 byte-identical; tools-health OK; ~+19k ins.

GIANT TAXONOMY (session finding, cookbook §56 + CURRENT_PHASE): the 12 preserved giants split into
- NON-jtbl (func_8013FAF8, func_8014F4C0): bank clean on a healthy tree, propagate x137 via macro/h_seq.
- jtbl (func_80131340/func_80159C84/func_8013C414/func_8013F350): each needs a per-overlay jtbl carve
  x137 AND hits an 8-align gap -> func_80131340 DEFERRED (byte-proven: gcc emits a non-first jump
  table .align 3 while the original packs it 4-aligned -> +4B padding shifts the whole data island,
  +5B/3077-diff image-wide %lo breakage). A jtbl_carve 8-align/isolation fix unlocks ~4 giants x137.
2026-07-17 17:40:54 -06:00
Drew T def16c8b18 feat(phase-29 T4): bank giant func_8013FAF8 (312) x1 + cookbook §56 (giant-splice reconciliation)
Task-4 giant-bank #1 of the 12 preserved p29t3 drafts. func_8013FAF8 (312 ins, a
menu/HUD prim builder stubbed in 138 overlays) BANKED x1 in ov_SC01_077, whole-binary
byte-identical; R22 clean-fleet 140/140; tools-health OK (dedup 1843/0, audit-binaries OK).

The README billed it "pure def-sig plumbing" but it was a 5-conflict multi-symbol
reconciliation (~5 gate iterations), all byte-neutral + gate-arbitrated (G3/P9):
- def-sig s16/s16 vs canonical s32/s32 -> NARROWED the extern fleet-wide (404 decls/265
  files). NOT --fix-def-sig: the s32 variant diverges at insn 22 (match_one, R35). Neutral
  because every fleet caller passes (s16)-cast or small-const args (verified).
- 3 data-symbol conflicts (D_80115128 lh / D_800B9A02 lhu / D_80187AC0 s32[]) declared
  BEFORE the splice (block-scope §55a-blocked) -> the TU's §18 cast-at-use-site convention
  (*(s16*)&, *(u16*)&, ((s32*)&sym)[i]) forces the load width regardless of decl signedness,
  keeps the TU decl untouched, propagation-safe. No CSE-hoist across 5 uses.
- 2 fn-extern conflicts (func_8013FFD8 s16 arg0, func_80141100 int(int)) -> reconciled the
  draft decl to the TU def + byte-neutral call-site cast. Still MATCH 312/312.

Stubs 138->137, 1 def, 0 NON_MATCHING (G4). Fleet holds 71.4/53.3/86.42 (the ×1 exemplar is
negligible until propagation ×137, batched per §55b). Technique -> cookbook §56.
2026-07-17 12:50:11 -06:00
Drew T fd564a2cf7 feat(phase-29 T3): propagate the 3 self-contained cores ×137 (+410 instances; fleet 71.0->71.4% instr)
- targeted dedup_propagate --addr per core (NOT --auto-from), --recover for stragglers:
    0x8014ADE0 -> 138 overlays byte-identical
    0x801325B8 -> 134 (ov_SC07_011 byte-diverges -> auto-excluded, kept x1 — what --recover is for)
    0x801387B8 -> 138 overlays byte-identical
  = ~410 member-instances; 3 new dedup groups (1840 -> 1843), C1 coverage 233795/233795.
- 2 of the 5 banked cores (func_8014E284, func_80137DD4) stay ×1: "not self-contained (local types)"
  -> blocked on the build_engine_types type-lift (the §19/§20 propagation cap). Carried.
- R22 clean-fleet 140/140 BYTE-IDENTICAL; audit-binaries OK; dedup 1843/0; 0 NON_MATCHING (G4).
  Fleet instr 71.0 -> 71.4% / fn-count 86.30 -> 86.42% / distinct-code 53.3%.

- SELF-CORRECTION (R14/R35), now fixed in cookbook §55c + CURRENT_PHASE: my earlier claim that this
  propagate "needs ~2h+" was WRONG. That timing was taken while the tree still carried the partial
  damage of a killed --auto-from (90/140 overlays broken), so every member-gate was failing/retrying.
  On a HEALTHY tree a targeted --addr propagate is ~233s/core (all 3 = ~27 min) — ~20x faster. Only
  --auto-from is genuinely fleet-slow. A timing taken on a broken tree measures the breakage, not the
  tool — recover the tree FIRST, then measure.
- cookbook §55: the wave's new byte-proven levers (§49-variant birthing-boost suppression via
  reg_n_sets 1->2; sched1 birthing/LUID + "cc1 -dL" movable introspection; switch-tree vs jtbl
  CASE_VALUES_THRESHOLD=5; block-scope-extern beats *(T*)&sym) + the GATE-ORCHESTRATION law
  (--no-propagate per group then ONE targeted --addr; commit banks BEFORE propagating; a reverted src
  needs a re-extract; gate_stage's default harvest_verified.txt accumulates -> phantom banks).
2026-07-17 02:04:38 -06:00
Drew T 2f38e31e76 feat(phase-26a): A3h — propagate 14 fleet-wide byte-exact stubs ×134 (Bucket P)
The standing-lead harvest (A3f/A3g continuation), measured precisely first (R14). Of the
~1,060 still-open byte-exact functions in the backlog:

  - Bucket G (67 open in ov_SC01_077): re-gated through the A3e-fixed gate_stage
    --no-propagate -> 0 banked. HONEST: A3f already took the bankable 33; the residual is
    the known hard classes (jtbl-rodata / register-pins / struct-collision) + stale backlog
    rows whose LATEST state is a WAVE mismatch. Correct G3/P9 rejection.

  - Bucket P (88 matched in ov077, open in siblings): the clean lead. dedup_propagate --addr
    (A3g primitive) skipped 70 as h_exact reach<2 (per-location byte VARIANTS -> family_sweep
    territory, not plain propagation) and propagated the 14 genuine PURE fleet families:
      5 top (func_80129C40/8012A6D0/80130A18/80131D68/80136DFC) + 9 more; 2 stragglers
      dropped all-or-nothing (0x80173A60, 0x8014C568 -> --recover candidates).

Each propagated x~133 (dedup_propagate internal gate: 134 overlays byte-identical).
R22 CLEAN-FLEET (make clean + extract-all + check-all): 136 passed, 0 failed of 136.
dedup-check: 1826 -> 1840 validated, 0 failed | C1 227211/227211.

DELTA:
  instr-weighted  66.8% -> 67.4%  (+~1,862 member instantiations shipped from C)
  distinct-code   46.8% -> 46.8%  (flat: propagation adds MEMBERS, not new distinct code)
  673 files (671 overlay .c instantiations + engine_core.h) + dedup.us.yaml + progress.fleet.md

Remaining standing lead: the ~72 variant Bucket-P + ~905 Bucket-X (absent from ov077) fns,
all latest-row closeness==0 -> route through family_sweep --hseq (per-sibling remap), next.
2026-07-14 17:41:24 -06:00
Drew T 60e26e07f8 feat(phase-26a): A3g — propagate the 3 fleet-wide banks ×134 (bounded, gated, R22-clean)
The 3 of A3f's 33 banks that are shared fleet-wide, stamped across all 134 overlays. Done the way
the earlier run should have been: TARGETED (--addr, not --auto-from), dry-run-sized first
(3 functions × 134 members = ~400 gates, not an unbounded fleet sweep), on a clean tree at HEAD.

  func_80130650 (31 ins) · func_80149450 (13 ins) · func_80174684 (9 ins) — each ×134.

  dedup_propagate internal gate : 134 overlays byte-identical, 3 groups registered
  R22 CLEAN-FLEET (the real proof, not the tool's incremental check that lied during the crash):
      make clean + extract-all + check-all -> 136 passed, 0 failed of 136
  dedup-check: 1823 -> 1826 validated, 0 failed | C1 coverage 225335/225335

DELTA (reconciles exactly):
    functions byte-identical  284,559 -> 284,958   (+399 = 3 fns × 133 other overlays)
    instr-weighted            66.7% -> 66.8%   (+13,167 shipped .text instructions)
    distinct-code             46.8% -> 46.8%   (flat: propagation adds MEMBERS, not new distinct
                                                code — the 3 bodies were counted at A3f)
    403 src files (3 ×134 instantiations + engine_core.h) + config/dedup.us.yaml

The other 30 of A3f's 33 are overlay-unique (×1) and need no propagation. The larger prize remains
the ~310 byte-exact stubs in the OTHER overlays (A3e), not yet attempted.
2026-07-14 16:47:42 -06:00
Drew T 82d79e7a32 fix(phase-26a): A6/A7 — the family engine could not see half its corpus; 17 fns banked x134 free
R22: check-all 136 PASSED / 0 FAILED. dedup-check 1823 validated / 0 failed (C1 coverage 224,933/224,933).
Fleet instr-weighted 66.5% -> 66.7%.

=== dedup_propagate: it was blind to HALF the corpus ===
overlay_files() used a hardcoded suffix allowlist ("_a","_o0","_o0b","_after") that predated the
Phase-26 jr carves -> 404 of the fleet's 811 overlay .c. The 407-file gap held 36,135 INCLUDE_ASM stubs
and ~32,000 inline defs, and overlay_files gates ALL of dedup_propagate (source_text / find_site /
apply_plan / struct_check / reconcile_caller_extern). Now a GLOB — never an allowlist, because the NEXT
split family would re-open it. The asm_subdir is always the file stem, an invariant the old four entries
already satisfied.

find_site's def-detector required the signature line to END in ')' and the next non-blank line to START
with '{'. It therefore silently dropped THREE shapes: K&R definitions (`s32 f(arg0)` / `s32 arg0;` / `{`),
multi-line signatures, and single-line bodies. K&R is the project's house style for exactly the biggest,
highest-reach functions — func_8015AE2C (562 ins), func_80166994, func_80133CD4, func_8015A3C8 — and they
live in the _jr_* files overlay_files could not even open. Fixing either alone would have been useless:
the glob exposes the files, and find_site would still drop their biggest prizes. Both fixed together.
  * The signature's closing paren is now found by a real paren-walk, not line.count() or split(')')[-1]:
    a single-line body containing a call (`void f(int a){ g(a); }`) has balanced parens of its own, so
    both shortcuts land on the WRONG paren and then misread the body's ';' as a prototype terminator.
  * AGREEMENT ASSERTION (the audit's): find_site vs family_remap.extract_unit -> 701 agree / 0 disagree.
    Negative controls hold (a prototype+call is rejected; a 1-line body with a call is a def).

=== THE HARVEST (free work, byte-gated) ===
--auto-from ov_SC01_077 now nominates what it could never see: 20 planned, 17 propagated x134, 3 dropped
as cross-overlay stragglers. 134 overlays rebuilt BYTE-IDENTICAL; 17 new dedup groups.
Includes ALL FOUR functions A1 caught the registry lying about (func_80128ED8 / 8012C098 / 8012C0EC /
8012C750): 0 stubs remaining, real shared macros. THE LOOP CLOSES — A1 found the lie, and THIS is the
bug that had made it true (3 of the 4 are defined in ov_SC01_077_jr_8012ACE0.c, which the allowlist could
not open, so the propagation never ran and dedup_integrate greenlit the result).

=== family_remap: 96 PHANTOM exemplars -> 0 ===
extract_unit globbed only src/<ov>/<ov>*.c, so a function matched via a SHARED body had no source form
and read as NOT MATCHED. 93-96 of 218 h_seq "matched" exemplars were phantom, carrying 2,157 candidate
members of which 1,834 are still-stubbed, PURE/IMM-clean, symbol_map-clean and unpinned — staged and
gated today, dropped before the first build then. It is now TOTAL over BOTH shared-body mechanisms:
  (1) the DEFINE_func_<ADDR>() macro — reconstructed as the exact INVERSE of dedup_propagate.make_macro
      (derived from the generator, not re-guessed from the text);
  (2) a DIRECT definition in a shared header, #included per overlay — the whale (func_80144B9C, 770 ins,
      -O0), which the registry explicitly records as "NOT a DEFINE_ macro".
  CENSUS: 216 matched exemplars, 216 real, 0 PHANTOM.

symbol_map named the symbol by HOW IT WAS LOADED, not by WHAT IT IS: reloc_targets labels every lui/%lo
pair "data", and a FUNCTION's address taken via lui/%lo (an address-taken callback) is exactly that shape
(splat's own .s: %lo(func_8017E1D4), 7 occurrences). The map got a D_<ADDR> key while the C writes
func_<ADDR>, so the word-bounded substitution matched NOTHING and silently no-op'd — the sibling kept the
EXEMPLAR's function pointer and the loss was booked as a BYTE failure, indistinguishable from a compiler
wall. Now emits both keys (addresses are unique; the pass is simultaneous, so the extra key is free).

gather_externs was line-oriented, so a WRAPPED comma extern was invisible in both directions (the first
line has no ';', the continuation has no `extern`). ov_SC01_077.c:271-272 declares NINE symbols that way,
and the exemplar referencing them (func_8013D178) is a 133-member family — every sibling was staged with
NO declaration, failed to compile, and bisect-stormed its whole gate group. Now statement-oriented, and
an unresolved symbol is REPORTED, never silently dropped.

=== family_sweep.stub_map / build_engine_types ===
stub_map: func_-only -> a curated-name stub read as "already matched" -> phantom exemplar. Now corpus-derived.
build_engine_types hard-exited on 1,070 of 1,470 type-bearing overlay .c (73%; the audit measured 573/709
= 81% on its narrower set) because 1,929 TAGGED-struct typedefs tripped a guard whose own comment asserts
"our source has only ANONYMOUS-struct typedefs" — true in Phase 20, false since the harvest agents started
writing tagged structs. inject_capped_externs routes every type-bearing body HERE as the type-heavy tail's
ONLY sanctioned unblocker, so the tail's unblocker could not run on the corpus the tail lives in.
A contained def (the typedef's span encloses the body) is liftable — it just must not be counted twice;
only a PARTIAL overlap is malformed. Verified on a file that used to hard-exit: 5 tagged typedefs folded +
forward-declared, 46 types written, exit 0.

  ** AND THE SHARPEST LESSON IN THE AUDIT: this one was never silent. It printed "[overlap] ... handle
     manually" every single time. But the message reads like a rare edge case rather than a four-fifths
     coverage failure, so nobody ever COUNTED it. A loud failure that nobody counts is exactly as
     invisible as a silent one. R32 must be "assert your coverage", not merely "fail loud". **

R14 self-catches, recorded because I hit both while fixing them: my first shared-header scan read a macro
body's `extern void f(void); \` as a DEFINITION (the trailing continuation means the line does not end in
';', so the decl guard never fired) — the exact bug fixed at commit:0552, reintroduced by me and caught only
because the whale resolved from the WRONG file. Column-0 anchoring fixes it by construction. And my
phantom census returned 0/0 twice because I guessed the manifest schema instead of reading it.
2026-07-14 10:34:06 -06:00
Drew T 9b93c254c2 feat(phase-26): func_8015AE2C (562 ins, x134) banked — Fable5 MATCH + 3 isolation bugs fixed
Exemplar banked byte-identical (d19c9580); R22 clean-fleet 136/136.
Fable5 crack: MATCH 562/562, pin-free, jump table verified.

THREE REAL BUGS the bank exposed in jr_isolate_all (each byte-proven; each would have
silently corrupted every future heavy-core bank):

1. --only filtered `banked` as well as the cut set, so already-banked jr went untracked
   and their carves were never followed. --only selects what to CUT; it must not erase
   the record of what is already banked.
2. carve ownership was read from splat .s — but splat emits NO .s for a MATCHED function
   (its .c holds real C), so the lookup found nothing. Now resolved from the extracted
   IMAGE via family_remap.reloc_targets (byte-exact: func_801734BC -> 0x801d8c68 etc).
3. THE STRUCTURAL ONE: a region may host at most ONE .rodata carve, because an object's
   .rodata is a single CONTIGUOUS section. Cutting at func_8015AE2C (jtbl 0x801D8B54)
   left the banked func_801734BC (jtbl 0x801D8C68) inside the same region, so the object
   emitted a 0x34 .rodata spanning BOTH tables (image +33 B). Every already-banked jr in
   a cut object is now cut too -> exactly one carve per object. Cookbook 8b's "bank
   same-subseg families ASCENDING" note warned about this; it is now enforced by
   construction instead of left to discipline.

Also required (per the crack's own analysis, all byte-verified):
- engine_core.h: DEFINE_func_8015BEC4's zero-arg thunk returns func_8015AE2C(), so the
  extern must drop its (void) prototype and the def must stay K&R/unprototyped.
  Byte-neutral across all 136 (R22 green).
- recovery chain: cast_call_sites (27 callees) + reconcile_decls (3 data syms). The raw
  body declares callees with types that conflict with their real engine_core.h defs; the
  original never redeclares them, it CASTS at the call site (cookbook 20).

Layout now exact: .rodata 0x801d8b54/0x1c (7 entries, pad trimmed) + 0x801d8c68/0x14 +
0x801d92a0/0x20 — one table per object, each at its true address.
2026-07-13 18:26:32 -06:00
Drew T c62fe7f7ea feat(phase-25): task A giant #1 — func_80166994 (369 ins) cracked ×134 via Fable5 + the K&R s16-param idiom (§43)
- Fable5 subagent cracked func_80166994 (trail/afterimage ring recorder, 369 ins) — FULLY
  STRUCTURAL, zero register pins -> swept ×134 CLEAN (exemplar + 133 siblings byte-identical).
  R22 clean-fleet 136/136; instr-weighted 56.8% -> 57.2%; distinct-code 27.3% -> 28.2%
- NEW IDIOM cookbook §43: a K&R s16-param DEFINITION dissolves the §17/§29 "narrow-param wall".
  On MIPS K&R promotes s16->int (ABI-identical to the canon-sig s32), body keeps the in-place
  sll aN,16 narrow/extend the (s16)cast form can't reproduce. void->s32 return-flip pair:
  split //@EDIT (self-fn, ov077-specific) + engine_core.h ec_edit ×5 (byte-neutral, callers discard)
- family_sweep --edit-remap: split-edits now OPTIONAL (apply where present, never skip; the
  whole-binary byte-gate is the sole arbiter, G3/P9) — a sibling lacking the ov077 canon-sig decl
  still banks via ec_edit + body. edit-absent tracked, not skipped
- R14: the prior wave's "@stuck: none — MATCH" note on func_80166994 was STALE/FALSE (re-ran DIFF
  366/369). Verify a MATCH claim vs the bytes, never a stale note
- structural cracks are the ×134-SAFE ones (contrast §42e pin-heavy families that cc1-SIGABRT in
  sibling TUs). Other 6 giants -> cheap-Opus applying §43+§31, Fable5 only on new-class evidence
2026-07-11 01:03:09 -06:00
Drew T 0241772225 fix(phase-25): canon_sig_reconcile def-finder (\n -> (?:^|\n)) unblocks crack propagation; recover func_8014FE60 x134; fleet 74.36->74.40%, R22 136/136
- R14 CORRECTION of the prior "family_remap limitation" call: it was a MISDIAGNOSIS. family_remap
  succeeds on all droppers; the "remap-fail" family_sweep reports was a mislabeled canon_sig_reconcile
  throw ("no definition of func_X found in draft") — the def-finder regex required a leading \n, so a
  //@EDIT-stripped raw draft with the fn definition on line 1 was not found.
- FIX: def-finder regex \n -> (?:^|\n) (also match a def at draft start; strictly additive, low-risk).
- Recovered func_8014FE60 fully: 133/133 siblings banked (fix + engine_core.h DEFINE_func_8014FDF4
  extern void->s32 global flip, byte-neutral fleet-wide; caller discards return).
- Residual (the genuine, small --edit-remap): func_8016DF5C/80136334/8013D9B0/80156044 reconcile but
  byte-drift per sibling (out-of-body fixes: pointer //@EDIT, no-proto, return-flip not carried per sibling).
- cookbook §42e (the two-layer diagnosis + the forward ×134-leverage-realism rule); decision-log corrected.
- R22 clean-fleet 136/136 BYTE-IDENTICAL from a fully clean tree; NON_MATCHING 7 (0 in default build, G4).
2026-07-10 21:05:25 -06:00
Drew T 6c0887b097 feat(phase-25): crack fan-out over the frontier map — wave 4, 24/26 MATCH + 1330 swept; fleet 73.97->74.36% (+1350 fns), R22 136/136
- Frontier map (docs/phase25-frontier-map.md, committed commit:0506): rtu_match-measured all 42 draftable
  families -> 37 crack targets; endgame = 42 draftable + 235 matched-free + 2481 absent.
- Crack fan-out wf_b54b5d98-380 (26 tractable-band exemplars): 24/26 MATCH -> 20 banked byte-identical,
  incl. func_8014FBC0 (22 ins x1996 inline-asm trampoline), func_80132144 (27 x539), func_8016CF04
  (engine_core.h void->short flip). Swept x134: 1330 siblings / 931 failed (//@EDIT/trampoline/engine_core
  families -> --edit-remap backlog). Batch = 20 exemplars + 1330 = 1350 fns.
- 5 durable levers -> cookbook §42d: return-type flip BOTH ways (void<->s32/short); address-recompute-vs-cache
  (the unifying read-global rule); the full-inline-asm trampoline idiom + family_remap-inside-asm; memcpy->
  struct-assign at scale; phantom-frame induction.
- Deferred (backlog, map tiers): func_8016D1D8/80165240 (M-linkwall), func_80164E40 (sig-reconcile),
  func_801457A4 (-O0), func_8012E364/801549F8 (permuter).
- R22 clean-fleet 136/136 BYTE-IDENTICAL from a fully clean tree; NON_MATCHING 7 (0 in default build, G4).
2026-07-10 19:49:39 -06:00