Commit Graph

478 Commits

Author SHA1 Message Date
Drew T 4db79a2060 feat(phase-28 T1b): the B2 family swept — 102/115 banked (88.7%), fleet 67.0 -> 67.7% instr
The family the roadmap recorded as 0/8 ("~0%, structural families do not template" — the
number that rewrote P29's arithmetic to "(cores cracked) x (reach)") banks at 88.7% when
swept with the carve its own exemplar required. ~0 agent tokens.

- SWEEP: jtbl_family_bank.py over the remaining 107 members ->
  {'BANKED': 94, 'gate-fail': 7, 'remap-refuse': 6}. Family total 8 (T1) + 94 = 102/115.
  R22: make clean && extract-all && check-all -> 140 passed, 0 failed of 140, 0 FAIL lines.

- FLEET (measured, make report): instr-weighted 67.0 -> 67.7% (+0.7pp, +97,104 ins);
  distinct-code 47.8 -> 49.4% (+1.6pp); fn-count 82.16 -> 82.19%. 102 x 952 = 97,104 =
  the exact measured instruction delta — the arithmetic reconciles to the byte.

- THE 13-MEMBER TAIL is the predicted shape, and both halves are data for T3:
  * 6 remap-refuse = EXACTLY the family's 6 IMM members (cls_counts PURE 109 / IMM 6).
    imm_map_tier1 REFUSED rather than guessed: "unresolved immediates: [(512,
    'asm-ambiguous')]" — 512 also occurs at a non-differing position, so a blind swap could
    corrupt it. This is the concrete shape of T3's IMM stratum.
  * 7 gate-fail = genuine byte-DIFFs, correctly rejected. Verified to leave NO residue
    (all 7: split_file=none, cfg_refs=0) — no false-bank risk.

- HYGIENE: the 7 "git checkout ... did not match any file" errors are benign (revert of a
  never-tracked path). Verified 0 untracked splits belong to a non-banked member; 91 new
  splits + 3 banked into existing splits = 94.

- SCOPE (P9, unchanged): still n=1 family, and jr is the rarest class (3/163 matched-exemplar
  families). This demonstrates the mechanism at family scale; it does NOT give a rate for the
  PURE/IMM mass (98% of the population). T3 measures the swing number.
2026-07-15 22:34:45 -06:00
Drew T a4640e3a51 feat(phase-28 T1): B2 LIVES — 8/8 banked; the "families don't template" doctrine was a missing carve
The roadmap's decisive P28/P29 input (h_seq families bank at ~0%) is byte-refuted. Same
family, same era, through the carve path its own exemplar required: 8 of 8 BANKED.

- THE PROBE: jtbl_family_bank.py func_8017BEBC ov_SC01_000 0x8017bebc --raw
  .run/phase26-cracks/func_8017BEBC.c over 8 of 115 members (4 same-address + 4
  CROSS-address, exercising to_addr) -> {'BANKED': 8}.
  R22: make clean && extract-all && check-all -> 140 passed, 0 failed of 140.

- ROOT CAUSE of the P27 0/8, byte-verified: 0x8017BEBC is a jr/switch core. §47 banked its
  exemplar as "lazy isolation -> carve (9-piece interleave) -> splice -> BYTE-IDENTICAL" and
  called the fix "×N template-safe". family_sweep.hseq_sweep stages C and gates -- it has NO
  CARVE STEP -- so gcc's generated jump table is never placed at the sibling's address. The
  entire residual is TWO WORDS: classify_member -> PURE, ndiff=2 @ idx 343/345 =
  lui/lw %hi/%lo(jtbl_801EC44C). overlays.mk:112 carves ov_SC01_000_jr_8017BEBC.o for the
  exemplar; :134 has no such entry for the member. tools/jtbl_family_bank.py exists to do
  exactly this per sibling and had NEVER been run on this family.

- THREE COMPOUNDING FAILURES made the doctrine: (1) wrong tool for the class; (2) n=1 on the
  LEAST representative family -- has_mid_jr is 3 of 163 matched-exemplar families (120 of
  13,232 members) -- generalized to the whole frontier; (3) its corroborating Phase-26 probes
  (tiny-IMM 0/241, PURE 0/134, pinned 0/133) ALL predate _carry_macros (P27 T5, commit:0637).
  P27's decision-log calls its own re-probe "a FOURTH phantom exhaustion proof" -- naming the
  mechanism that would have faked the first three, and never re-running them. The ~0% doctrine
  has NO surviving post-fix evidence.

- SCOPE HONESTY (P9): this refutes the EVIDENCE for ~0%; it does NOT establish a general rate.
  n=1, and jr is the rarest class by construction. T3 measures the rate over the population
  that actually exists: 1418 matched-exemplar families / 21,889 members (PURE 78% / IMM 20% /
  STRUCT 1.8% -- note the roadmap sizes its swing number on STRUCT = 1.8% of the input).

- TWO SELF-CORRECTIONS (R14), both mine: (a) the approved plan's "add jtbl_ to symbol_map" was
  a WRONG FIX FROM A TRUE DIAGNOSIS -- a compiler-generated switch table is never named in C,
  so there is no token to substitute; the fix is PLACEMENT. No symbol_map change was made and
  T1 became a run, not a code change. (b) func_8017BEBC.md's header still says "close=2 of 952"
  (pre-§47-slider); the .c was updated, the .md was not -- templating from the header's premise
  would have produced zeros indistinguishable from a wall.

- DISTILLED IN-SESSION (R30/R16): cookbook §53 (sweep a family with the tool its exemplar
  needed: the carve law, the --raw rule, the symbol_map-jtbl trap, and the "before a 0%
  retires a lever" three-question test); calibration.md's decisive table REWRITTEN (the ~0%
  row marked an artifact, not a rate; the addressable pool tabulated); decision-log R31.

- Carried: the family's remaining 107 members (~101,864 ins, ~0 agent tokens) -> T1b.
2026-07-15 21:56:28 -06:00
Drew T 264fe6c115 feat(phase-27 T7): disc-completeness audit — onboard 4 hidden SC07 overlays (136->140) + the type sweep
The whole-binary byte-gate is structurally blind to code nobody onboarded (R34): check-all is
green over the onboarded set no matter what code sits unbuilt on the disc. This reconciles the
onboarded set against every code-bearing PAC payload.

- new_overlay.sh: optional [ENTRY] arg (default 0.4) reaches a non-0.4.dec payload. Onboarded
  ov_SC07_{006,007,010,011} from 1.4.dec (they put graphics at PAC entry 0, the code overlay at
  entry 1 — invisible to the 0.4 hardcode for a month). Each byte-identical (7ca772be / b3b95547 /
  d7b5875d / 9885af74). FLEET 136 -> 140; check-all 140/140 (T2's pass==N re-baselined cleanly).
  difficulty.py NOT in the insertion set anymore (it derives, T6) -> only 3 tool dicts touched.
- tools/disc_code_sweep.py: decode every payload (reusing sig_image.make_insn) and gate code on
  BOTH valid>=0.90 AND jr_$ra density>=0.01. The jr_$ra gate is decisive: isValid() alone flags
  389 false hits (type-0/2 structured data decodes ~100% valid but has ZERO returns); jr_$ra
  separates code (~2.9-3.4%) from data (0.000%), validated on positive+negative controls.
- FINDING (docs/disc-completeness.md): type-4 location overlays are COMPLETE (138/138). All other
  types are data EXCEPT type-1 = 40 code payloads, 1 onboarded (the resident), 39 HIDDEN
  resident-class modules (mostly MAIN.CD/FILE_XXX/1.1). They load at UNKNOWN addresses (not the
  shared overlay slot), so they are NOT mechanically onboardable — byte-verifying a build binary
  needs its load address (P9), knowable only by runtime RE (the Phase-3 method). Deferred with
  evidence, NOT force-onboarded at a guess.
- CONSEQUENCE: game-code TRUE 100% now spans 140 onboarded binaries PLUS ~39 type-1 modules
  pending load-address RE. The roadmap assumed 136 — this is a real re-baselining (the +4 overlays
  also add ~2.45 MB to the denominator; every family propagation is now x138). Flows to T10/T11.
- SETUP §6.3 tool inventory updated (R21).
2026-07-15 18:33:37 -06:00
Drew T 3509acf4b7 feat(phase-26a): A9b — func_8017A4AC banked ×134 (536-ins giant, wall re-test payoff)
The A10 re-test payoff. func_8017A4AC (536 ins, reach-134) — "blocked on plumbing" since
session 8 — banks now that the audit repaired the recover path (A3d reconcile_tu / A3e gate).
jtbl_family_bank --raw swept all 133 siblings (per-sibling isolate → jtbl carve → remap_hseq +
canon_sig_reconcile → whole-binary gate): 133/133 BANKED, 0 failed. 0 still-stub overlays.

R22 CLEAN-FLEET (make clean + extract-all + check-all): 136 passed, 0 failed of 136.
dedup-check 1840/0 (jtbl sweep banks are per-overlay src, not registry).

DELTA:
  instr-weighted  68.1% -> 68.6%  (+0.5%, ~71,824 shipped .text instructions)
  distinct-code   48.0% -> 49.2%  (+1.2% — the siblings are per-location byte-variants)

The audit thesis, demonstrated: a giant "wall" that stood for many phases was our TOOLING (the
recover path could not resolve its struct/fn-ptr conflicts), not an intrinsic compiler residual.
Once the oracle was fixed, the wall dissolved and banked ×134.
2026-07-14 20:38:10 -06:00
Drew T 97d86fae69 feat(phase-26a): A9b — bank func_8017A4AC exemplar ×1 (wall re-test payoff)
The 536-ins reach-134 giant listed "blocked on plumbing" since session 8. Re-tested through
bank_exemplar after the audit's recover-path fixes (A3d reconcile_tu wiring / A3e gate): BANKED
at the `recovered` stage (fb.recover / reconcile_tu resolves the D_80126B58 struct + D_801DA75C
fn-ptr conflicts the raw/scoped stages hit). Lazy-isolated into its own jr subseg + jtbl carve.

HONEST ATTRIBUTION (R14): this bank is the payoff of the A3 recover path, NOT A9a — it banked at
`recovered`, before the `reconciled` (canon_sig_reconcile) stage was reached. A9a's fn-ptr
classifier fix is a correctness fix that did NOT independently unblock a bank in the 7-candidate
re-test (the reconciled stage failed on func_8015B950's func-conflicts; the rest hit K&R /
scalar-typedef / non-ov077 / non-contiguous-carve blockers) — the same null-immediate-banking
pattern as A3c/A3d/A3e; its value is protecting all future dispatch-table banking.

R22 clean-fleet: 136 passed, 0 failed of 136. Exemplar ×1 (+536 ins); the ×134 family sweep follows.
2026-07-14 20:09:22 -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 af2f40d153 fix(phase-26a): A4/A5 — 193 unmatchable slices dissolved; the closeness oracle stops lying
R22 CLEAN-FLEET: make clean -> extract 136 -> build 136 -> check-all = 136 PASSED, 0 FAILED.
make audit-corpus: 0 PHANTOM + 0 TRUNCATED (was 193).

=== A4: a CORPUS defect the byte-gate could never have caught ===
config/symbols.us.txt:981 declared `listCdBuffer = 0x80180000` — a correct Phase-3 name for MAIN's
LIST.CD RAM buffer. But that address is OUTSIDE main's image and INSIDE the overlay slot, and every
overlay's splat config stacks symbols.us.txt. High RAM is REUSED: an address that is a buffer to main
is live CODE to an overlay. So splat saw a symbol boundary mid-code and, across 97 of 134 overlays:
  * CUT 97 REAL FUNCTIONS IN HALF (a head ending on a `lui`, no return), and
  * INVENTED 96 PHANTOM ONES      (a tail beginning by reading the assembler temp $at).
193 slices NOBODY COULD EVER MATCH — not "hard", not "a compiler wall": unmatchable by construction.
They sat in the harvest queue as ordinary work, so agents would burn on them forever and the failures
would be filed as intrinsic compiler residuals.

The phantom listCdBuffer.s in ov_SC01_005 literally begins:
    lw $ra, 0x10($sp) / addiu $sp, $sp, 0x18 / jr $ra
splat cut a function immediately before its EPILOGUE and called the epilogue a function.

AND IT HAD ALREADY CONTAMINATED REAL WORK: in ov_SC03_031 the cut landed where the epilogue was
exactly `jr $ra; nop`, so the Phase-26 x134 sweep innocently BANKED the phantom as
`void listCdBuffer(void) {}` — byte-correct, gate-green, entirely fictitious — while leaving
func_8017FFC4 permanently unmatchable. Removed.

WHY NO GATE CAUGHT IT, AND WHY THAT IS THE POINT: INCLUDE_ASM pastes the two .s halves back VERBATIM
in original order, so the image is byte-identical either way. The byte-gate was green the whole time
and always would have been. It is a perfect CORRECTNESS oracle and a NULL COVERAGE oracle. No
assertion added INSIDE it could ever have found this. What found it was a SECOND, INDEPENDENT oracle:
tools/sig_image.py derives boundaries from the ORIGINAL bytes without splat, and DISAGREED with the
corpus (58,524/58,621 agreement with spimdisasm; correct on all 97 disagreements).
  => When one oracle is structurally blind to a class of error, the answer is not a better assertion
     inside it. It is a SECOND ORACLE THAT CAN DISAGREE WITH IT.  (`make audit-corpus` is now that.)

THE RULE (the mirror of R13/R15, never written down): a symbol whose address falls inside ANOTHER
binary's vram window must never enter that binary's symbol stack.
FIX: config/symbols.us.ram.txt — main-scoped symbols outside main's image — stacked ONLY by
config/splat.us.exe.yaml. Main keeps the name it needs (10 %hi / 11 %lo refs; 143dbb89 byte-identical);
the overlays never see it. Exactly one symbol was in scope fleet-wide; the resident window was clean.

AND A REAL FUNCTION THE ACCIDENT WAS HIDING: in ov_SC01_084 / ov_SC02_041 / ov_SC03_094 / ov_SC06_008
there IS a genuine function at 0x80180000 (111 / 35 / 28 / 74 ins), reachable ONLY via a fn-pointer
table (.word func_80180000) and never by `jal` — so splat cannot find it and needs the boundary
DECLARED. listCdBuffer had been supplying it by luck. Now declared honestly, per-overlay, in
config/symbols.<ov>.txt — exactly where R13/R15 says an overlay-scoped symbol belongs.

=== A5: the closeness oracle every crack agent trusts was lying on 155 functions ===
masked_diff._reloc_kind() knew 26/HI16/LO16. An over-approximating sweep of every reloc objdump emits
across all 3,367 build objects found FOUR: R_MIPS_26, HI16, LO16 — and R_MIPS_PC16 (211). PC16 fell
through to a FULL-WORD compare, but the object holds an UNRESOLVED PLACEHOLDER in the branch
displacement, so that compare can NEVER succeed.
DECISIVE TEST (derived from the invariant, not from reading the regex): INCLUDE_ASM pastes the
ORIGINAL asm, so for every stub diff_object_s() MUST be 0. Measured, coverage-asserted:
    2,741 functions scored — old mask: 150 LIES;  PC16 masked: 4 LIES.
(The 4 survivors are the separate length-delta defect.) A phantom non-zero sends an agent to grind at
a wall that is not there, and the wasted attempt is then booked as a MATCHING failure, feeding
reserved_walls() and PERMANENTLY BLACKLISTING a function that was never broken.

=== NEW FINDING (found by cutting the R22 corner): a STALE OBJECT CAN PRODUCE A FALSE PASS ===
`.o <- .s` is not a dependency make can see: assembly arrives via INCLUDE_ASM, expanded to a `.include`
consumed by maspsx/as AFTER cpp, while -MMD tracks headers only. Re-extract, build incrementally, and
make links a STALE object. This is not merely slow — INCLUDE_ASM pastes the ORIGINAL bytes, so a stale
object still yields the original image: SHA1 GOES GREEN while the split just changed is never exercised.
A broken config change can be "verified" by an incremental build. Live proof: 8 of 136 binaries linked
stale objects here; they failed LOUDLY ONLY BY LUCK (the dead symbol was an undefined reference) — a
merely-different-but-valid split would have gone green on all 136.
R22/H3 already legislate this, and I broke them. But a rule that needs a human to remember it is not a
gate. FIX: `extract` now invalidates the objects that include what it just rewrote (main's are top-level,
so -maxdepth 1 — verified it cannot clobber the other 1,605 objects). Structural, not advisory.

R14 self-catch, recorded: my first A5 test passed `fn=` to diff_object_s(), which takes two args; the
TypeError was swallowed by my own `except Exception: continue` and it reported 0 scored / 0 lies. I
wrote the exact bug I was auditing, inside the test for it. Caught only because 0 looked wrong. The
test now asserts its own coverage.
2026-07-14 10:12:19 -06:00
Drew T bb65d36341 fix(phase-26a): A1 — dedup_integrate was a gate that could print a FALSE GREEN
The audit's priority #1: a fail-closed byte-honesty validator whose silent skips nothing
downstream can catch. Three false-green paths, all measured, all now fail-closed with
negative controls.

R33 FIRST (derive, don't re-derive). The registry makes two claims; the tool only ever
checked one, and mis-described that one:
  C1 EQUIVALENCE ("these vrams hold the same code in the ORIGINAL") — checked against the
     sigs, which sign the ORIGINAL bytes. KEPT. But the docstring claimed it also caught
     SOURCE drift: it cannot. A sig is a property of the ROM, immutable w.r.t. src/. Source
     drift is caught by the BUILD. Docstring corrected (P9).
  C2 BANK ("matched once in the source header, instantiated at every member") — NEVER
     CHECKED. Now DERIVED from the build invariant: INCLUDE_ASM pastes the ORIGINAL asm, so
     a member NOT wrapped in it is byte-exact, and one that IS wrapped is not banked —
     whatever the registry says. C2a: the group's macro token must occur in its source file.
     C2b: no member may still be an INCLUDE_ASM stub.

THE THREE FALSE GREENS
 1. 1808 groups claimed a DEFINE_func_* macro; only 1801 exist. The 7 ghosts printed [ OK ] —
    hiding 532 member-instances / 22,344 instructions of REAL, UNBANKED work (4 fns matched in
    ov_SC01_077, still INCLUDE_ASM in the other 133 overlays).
 2. An absent .run/sig.<bin>.jsonl degraded to "0 validated, 0 failed" and EXIT 0. On a fresh
    clone the gate validated NOTHING and passed. Now fails; --allow-unsigned is the escape.
 3. The bank claim was never checked at all.

THE CAUSAL CHAIN (the audit's thesis in one example). 3 of the 4 hidden fns are defined in
ov_SC01_077_jr_8012ACE0.c — a _jr_* split file. dedup_propagate.overlay_files allowlists only
("_a","_o0","_o0b","_after"), so the propagator could not SEE them; the group was registered
anyway; dedup_integrate greenlit the lie. TWO silent-skip bugs compounding: one created the
hole, the other hid it. Harvest fuel -> .run/audit/a1_harvest_fuel.json, banked in A5.

BLAST RADIUS, MEASURED NOT PREDICTED (R14). Headline metrics UNCHANGED to the decimal
(instr-weighted 66.5%, distinct-code 46.8%) — weighted_metrics() derives from the invariant and
was structurally immune to the lying registry. FLEET REAL substantive unchanged (282,466):
progress.py had already been taught to distrust it (commit:0574). Only dedup_integrate still
believed it. A null result that CONFIRMS R33: the tool that refused to re-derive was the one
that was right.

- registry repaired: 1813 -> 1806 groups (7 ghosts removed; instances 223,725 -> 222,787)
- make report GREEN end-to-end: 1806 validated, 0 failed | C1 coverage 222,787/222,787 signed
- negative controls: stubbed member -> exit 1; missing sig -> exit 1; --allow-unsigned -> exit 0
- report-only tool: no compiled artifact depends on it, so no R22 clean-fleet is owed here
2026-07-14 02:50:28 -06:00
Drew T cc7ee23d03 feat(phase-26): func_801380E0 swept ×134 siblings — R22 136/136 byte-identical 2026-07-14 02:18:46 -06:00
Drew T c12c497e10 feat(phase-26): func_801380E0 banked ×1 (crack wave) — whole-binary gate, R22 136/136 2026-07-14 01:52:02 -06:00
Drew T 8a3f227ac1 feat(phase-26): func_8015444C swept ×134 siblings — R22 136/136 byte-identical 2026-07-14 01:50:19 -06:00
Drew T 9caea60142 feat(phase-26): func_8015444C banked ×1 (crack wave) — whole-binary gate, R22 136/136 2026-07-14 01:29:48 -06:00
Drew T cffbdbe88e feat(phase-26): func_8016AB6C swept ×134 siblings — R22 136/136 byte-identical 2026-07-14 01:28:41 -06:00
Drew T f5f3c44693 feat(phase-26): func_8016AB6C banked ×1 (crack wave) — whole-binary gate, R22 136/136 2026-07-14 01:00:51 -06:00
Drew T 55a63fae95 fix(phase-26): remove the duplicate code-subseg line from ov_SC01_077's committed config
Residue of the same isolation-revert bug fixed for ov_SC01_000 in commit:0558: a failed bank left its
isolation's config in place, the retry re-isolated on top, and a duplicate
  - [0x4b364, c, ov_SC01_077_jr_801734BC]
line rode into a commit. It is HARMLESS to splat (a zero-length subseg), so R22 stayed green and the
correctness gate never saw it — but it BLOCKED every subsequent isolation, which is what failed 5 of
the 9 crack-wave banks. Caught only by the fail-loud validation added in commit:0558 (a tool that refuses
to proceed on input it does not understand), never by the byte-gate. Fleet audit: ov_SC01_077 was the
ONLY affected config of 137. ov_SC01_077 rebuilds d19c9580 BYTE-IDENTICAL.
2026-07-14 00:59:13 -06:00
Drew T ffcd914ed5 feat(phase-26): func_8013FFD8 swept ×128 siblings — R22 136/136 byte-identical 2026-07-14 00:58:33 -06:00
Drew T b813432b1b feat(phase-26): func_8013FFD8 banked ×1 (crack wave) — whole-binary gate, R22 136/136 2026-07-14 00:31:58 -06:00
Drew T 7a5657e83c feat(phase-26): func_8015A3C8 swept x132 siblings — R22 136/136 2026-07-14 00:30:06 -06:00
Drew T 6f3441d261 fix(phase-26): 10% of the canonical-callee oracle was silently missing (own-line-brace DEFINE macros)
- BUG: gen_harvest_targets.SIG_IN_BODY_RE required `)\s*{` between a DEFINE_func_* macro's signature
  and its opening brace. When the brace sits on its OWN continuation line there is a line-continuation
  BACKSLASH between them:
        s32 func_80148824(void *arg0) \
        { \
  and `\s` does not match `\`. So the regex silently dropped every own-line-brace macro.

- BLAST RADIUS (measured): 186 of 1801 engine_core.h shared signatures — 10% of the oracle — were
  MISSING from the canonical-callee map that cast_call_sites / sig_unify / gen_harvest_targets resolve
  against. A draft calling one of them kept its own guessed signature, hit `conflicting types` against
  the TU's real definition, and the recovery pass reported nothing to fix — the failure looked like a
  hard wall. This is why the crack wave's byte-exact cores would not bank.

- FIX: `[\s\\]*` instead of `\s*`. Oracle 2122 -> 2308 entries.

- PROOF: func_8015A3C8 (493 ins, MATCH standalone) went from "28 conflicting types, unbankable" to
  BANKED ×1 BYTE-IDENTICAL at the `recovered` stage, with zero hand edits. R22 clean-fleet 136/136.

- This is the phase's SIXTH silent-skip bug and the THIRD of the same brace-placement class (§19
  find_site; scope_data_externs' own-line brace; now this). Cookbook §40's standing lesson applies:
  a tool that silently no-ops on input it cannot parse is indistinguishable from one that had nothing
  to do — prefer fail-loud on unparsed input.
2026-07-14 00:08:59 -06:00
Drew T cc08601ae7 feat(phase-26): func_80178D40 swept ×134 — the heaviest core in the game, fleet-wide
- 132/132 siblings banked (0 failures) via jtbl_family_bank --raw + the lazy-isolation chain.
  Each sibling: isolate -> jtbl carve -> remap from the raw crack -> stage ladder
  (raw -> scoped §8d -> recovered -> reconciled) -> WHOLE-BINARY byte-gate.
- R22 clean-fleet 136/136 BYTE-IDENTICAL from `make clean`; 0 NON_MATCHING (G4).
- METRICS: instr-weighted 63.8 -> 64.7%; distinct-code 40.7 -> 42.8% (+2.1 points from ONE core —
  890 ins x 133 overlays = ~118K instructions of unique engine code); fn-count 82.43%.
- tools/bank_exemplar.py promoted from scratch: bank a cracked EXEMPLAR ×1 through the same stage
  ladder jtbl_family_bank uses for siblings (carve/lazy-isolate -> raw/scoped/recovered/reconciled
  -> whole-binary gate). The exemplar path was previously hand-run each time.
2026-07-14 00:02:26 -06:00
Drew T 07ebb5658d fix(phase-26): jr_isolate_all empty-region0 skip — cutting an already-isolated region's non-leader works
Cutting func_80178D40 out of ov_SC01_000_jr_801734BC adds the region's banked LEADER (0x801734BC)
as a cut too (the one-carve-per-object rule), making region 0 EMPTY (the object's first item IS the
first cut) — and region 1's derived name equals the object name, so emitting region 0 duplicated the
line exactly -> splat "segments out of order". Skip an empty region 0; region 1 rightly claims the
object's offset and name. First sibling then banks through the full chain (isolation validation
green -> carve -> --raw remap -> stage ladder -> whole-binary gate): ov_SC01_000 BANKED, included
here. The remaining 132 siblings sweep next.
2026-07-13 22:14:57 -06:00
Drew T 7e4165676d fix(phase-26): isolation-residue corruption chain — config cleanup + revert() restores config + fail-loud validation + --raw sweep mode
Three-layer fix for the func_80178D40 ×133 sweep failures:

- LAYER 1 (the residue): jtbl_family_bank.revert() restored carve pieces + src/ but NOT the
  isolation's CODE-subseg lines in the splat config. A failed bank attempt (BEBC's first try)
  left its isolation config in place; the successful retry re-isolated on top and a DUPLICATE
  `- [0x4b364, c, ov_SC01_000_jr_801734BC]` line rode into the commit (harmless to splat —
  zero-length — so R22 stayed green). revert() now also restores config/splat.<ov>.yaml.
  The committed duplicate is removed (ov_SC01_000 rebuilt BYTE-IDENTICAL 9052dc0e).

- LAYER 2 (the detonation): jr_isolate_all walked the duplicated object TWICE -> two
  replacements -> a reversed duplicate block -> splat "segments out of order". It now VALIDATES
  the generated config (code subsegs strictly ascending, names unique) and refuses to write on
  violation, naming the likely cause — a corrupt input dies at the tool, not three tools later.

- LAYER 3 (the sweep template): jtbl_family_bank gains --raw <crack.c> — template from the RAW
  crack via remap_hseq_body instead of the exemplar's banked source unit. REQUIRED when the
  exemplar banked at the `reconciled` stage: a reconciled body is TU-SPECIFIC (§41c — uniquified
  type names, TU-targeted casts), so extract_unit hands the sweep a polluted template and every
  sibling gate-fails (byte-proven: 178D40 banked reconciled -> sweep 0/4; 8015AE2C banked raw ->
  sweep 133/133). Same law as family_sweep --reconcile-raw.
2026-07-13 22:13:11 -06:00
Drew T 660aa9f215 feat(phase-26): func_80178D40 (890 ins, ×134 — the heaviest core) banked ×1 in ov_SC01_077
The §46 crack (MATCH 890/890, pin-free) banked through the whole-binary gate: lazy isolation ->
new region ov_SC01_077_jr_80178D40 + jtbl carve -> the FULL stage ladder (raw 36 conflicts ->
scoped -> recovered 5 -> RECONCILED banked; canon_sig_reconcile's type-name uniquification resolved
the SV3/Obj20/Blk typedef collisions) -> BYTE-IDENTICAL d19c9580. R22 clean-fleet 136/136.
The ×133 sibling sweep (PURE per-location, members staged) runs next.
2026-07-13 22:05:53 -06:00
Drew T 3a67dd609f feat(phase-26): func_8017BEBC (952 ins, ×113) CLOSED + banked ×1 — the §47 live-length slider
The largest unmatched core in the game, walled at close=2 for the permuter (25 min, no close) and
queued for a gdb-on-cc1 read. Closed WITHOUT gdb — the RTL dumps were the oracle:

- THE TIE, byte-measured (.lreg): &g.sz1 pseudo 228 refs 13 / live_length 783; &g.sz2 pseudo 230
  refs 13 / 782 -> pri = int(390000/L) = 498 == 498, an exact int-truncation tie in global.c:594
  allocno_compare. Tie-break = creation order -> allocation follows emission; the target needs them
  to DIFFER (allocation sz2-first, emission sz1-first). The shipped operand-permutation workaround
  could only pick one (close=2 vs close=10).
- THE FIX (§47): restore NATURAL operand order (emission correct) + ONE zero-byte
  `__asm__ volatile ("")` placed BETWEEN two existing GTE volatile asms (no new cse/sched barrier —
  one is already there) -> +1 static insn at global-alloc time -> L 784/783 -> pri 497 vs 498 ->
  the tie SPLITS toward the shorter-lived (later-created) pseudo, which is ALWAYS the direction
  "allocation != creation" requires. All 10 grants cascade; MATCH 952/952 first try; the slider
  emits only #APP/#NO_APP (zero bytes). PIN-FREE, ×113 template-safe.
- BANKED ×1 in ov_SC01_000 through the WHOLE-BINARY gate (jr fn — match_one is not the arbiter,
  §8a): lazy isolation -> new region ov_SC01_000_jr_8017BEBC + 9-piece jtbl interleave -> splice ->
  BYTE-IDENTICAL. One TU-visible decl reconcile en route (D_800B9A02: declare the TU's `short`,
  force the unsigned halfword at use `(*(u16*)&D_800B9A02)` — §8d sub-class (b)).
- R22 clean-fleet 136/136 BYTE-IDENTICAL; 0 NON_MATCHING (G4). The ×113 sibling sweep is IMM-class
  (scattered addresses) -> Task-8 mechanical work via the imm engine.
- cookbook §47 (the slider method + the placement rule + the direction law); decision-log (R31).
2026-07-13 22:02:46 -06:00
Drew T 1ab9905368 feat(phase-26): §8d scope_data_externs — the ×133 sweep blocker fixed; func_8015AE2C banked ×134
- ROOT CAUSE (R14 — the session-7 diagnosis was half right): the isolated region builds [ OK ]
  WITHOUT the body, so §8b isolation was never implicated. `family_remap.gather_externs` prepends
  carried decls at FILE scope; D_801812A4 is a fn-ptr dispatch table the sibling declares FOUR
  incompatible ways at BLOCK scope inside its own later functions, so the carried file-scope decl
  ESTABLISHES A GLOBAL THE TU NEVER HAD and every later block-scope extern must now agree with it.
  Byte-proven asymmetry: BLOCK(int)->BLOCK(struct*)->FILE(void*) builds; FILE(void*)->BLOCK(int)
  errors. It was the ONLY hard error in the build — all 27 carried function externs were fine raw.

- THE FIX (demote, don't reconcile): tools/scope_data_externs.py emits a carried D_ extern at BLOCK
  scope inside the function body when the TU has no file-scope decl of it above the insertion point.
  Byte-neutral (an extern emits no code; type + access opcodes unchanged) and never worse than raw,
  so it needs no oracle, no type comparator, no fn-ptr parser. Restores fidelity — the original
  declares these symbols at block scope in exactly this way. Wired into jtbl_family_bank as the
  `scoped` stage: raw -> scoped -> recovered -> reconciled (scoped is the base for the later stages).

- reconcile_decls is the WRONG instrument for this class, twice: its oracle answers "what does the
  FLEET call this symbol" when the question is "what can THIS TU see", and its DATA_DECL_LINE_RE
  cannot parse `extern void (*D_x[])(void *);` — silently skipping the very symbols that were
  failing (the phase's third silent-skip bug, after find_site braces + overlay_files splits).

- R17 TRIAGE RULE, first real test, held: `conflicting types` = the compiler REFUSED TO COMPILE =
  a C front-end diagnostic = our Python. Reading cse.c/global.c would have taught nothing.

- RESULT: func_8015AE2C (562 ins, reach 134) swept 133/133 siblings, 0 failures. R22 clean-fleet
  136/136 BYTE-IDENTICAL (534 changed src files); dedup-check 1813 validated / 0 failed; 0
  NON_MATCHING (G4). instr-weighted 63.0 -> 63.6%; distinct-code 39.1 -> 40.5% (+256 unique fns /
  +79,957 ins) — one core, ~0 agent tokens.

- knowledge captured during the producing session (R30/R31/R21): cookbook §8d, decision-log
  2026-07-13 session 8, SETUP tool-inventory row; CURRENT_PHASE session-8 checkpoint.
2026-07-13 20:45:15 -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 258f10c048 feat(phase-26): func_80182268 family banked x3 — the lazy jr pipeline proven end-to-end
Sibling sweep via jtbl_family_bank: ov_SC02_000 + ov_SC02_003 (cross-address, the
fn lives at 0x8017FCB0 in both) BANKED byte-identical. With the exemplar that is the
complete family (3/3).

This closes the de-risk: the lazy jr bank composition now runs end-to-end on a real
cracked core — lazy isolate -> jtbl_carve into the isolated subseg -> cross-address
remap -> raw-first two-stage gate -> whole-binary byte-gate -> x-members.

R22 clean-fleet 136/136 byte-identical; 0 NON_MATCHING (G4).
2026-07-13 14:43:36 -06:00
Drew T e79d030499 feat(phase-26): func_80182268 banked via the LAZY isolation path + the void->s32 gate-cap fix
End-to-end proof of the §8b lazy bank composition on a real cracked jr core:
lazy isolate -> jtbl_carve into the isolated subseg -> C body -> whole-binary gate
-> d19c9580 BYTE-IDENTICAL; R22 clean-fleet 136/136.

- func_80182268 (31-ins jr, ov_SC01_077_after) MATCHED first try: shared-tail
  fallthrough (jtbl cases 3+7 enter case 4's tail) + the u16-shift sign-extend idiom
  ((s8)(*(u16*)(p+0x70) >> 8) -> lhu/sll16/sra24). Carve collided with the committed
  func_801734BC carve -> lazy isolation fired exactly as designed.
- R14 FINDING (cookbook §41d): the Phase-17 canonical convention "void->s32 return is
  byte-neutral (§3a-1)" is FALSE for a void body with no `return` — it costs ONE extra
  instruction. canon_sig_reconcile applies it unconditionally, so it turned a perfect
  31-ins MATCH into 32 ins. That extra word made the isolated object's .text 4 B long,
  shifting EVERY data symbol +4 -> ~271k differing bytes, image +5 B. match_one said
  MATCH; only the whole-binary gate caught it (G3/P9).
- FIX (generalizes the §19 sig_unify lesson): every recovery pass is a FALLBACK, never
  unconditional. jtbl_family_bank now gates RAW first, reconciled only on failure.
- 136/136 byte-identical from a clean tree (R22); 0 NON_MATCHING (G4).
2026-07-13 14:34:04 -06:00
Drew T ca50ee6978 feat(phase-26): §8 multi-jtbl --order carve + family-1 (func_801734BC ×134)
- ld_interleave.py --order: address-ordered N-piece data->rodata->data sandwich
  for overlays with 2+ matched jr-functions; legacy --front/--tail path is byte-
  untouched (main EXE + the 133 single-carve func_8012ACE0 siblings unaffected)
- jtbl_carve.py rewritten additive/regenerate-from-config: parse the tail data
  region + existing .rodata carves, split the containing data piece for the new
  jtbl, re-emit the address-ordered pieces + the --order arg; same-subseg carve
  collision fails loud (-> jr isolation); idempotent
- jtbl_family_bank.py: `make extract` BEFORE the carve (asm must match the reverted
  committed config; the old error-string retry was fragile) + revert-on-carve-fail
- family-1: func_801734BC (34-ins PURE jr, ov_SC01_077_after) matched in ov077
  (shared-tail switch idiom) + banked 133/133 siblings = x134 — CROSS-subseg
  multi-jtbl (func_8012ACE0 in _a + func_801734BC in _after)
- R22 clean-fleet 136/136 byte-identical (~52s); 0 NON_MATCHING (G4)
2026-07-12 21:51:27 -06:00
Drew T 5a08180617 feat(phase-26): §8 ×134 automation — func_8012ACE0 banked fleet-wide (133/133, R22 136/136)
- the jr-function ×134 harvest pipeline, proven end-to-end: per family sibling,
  jtbl_carve (per-sibling jtbl-rodata carve, computed from THAT sibling's own jtbl
  address — the fn is at the same vram across overlays but its jtbl floats) -> make
  extract (auto ld_interleave) -> remap_hseq + canon_sig_reconcile -> whole-binary gate
- tools/jtbl_carve.py: per-overlay §8 carve generator (config data-tail split +
  <ov>_JTBL_INTERLEAVE var)
- tools/jtbl_family_bank.py: the sibling sweep driver (idempotent, revert-on-fail, byte-gated)
- tools/family_remap.py: extract_unit now carries single-line typedefs (jr-function bodies
  define local `typedef struct{} Foo_<addr>;` that must template with the body — the
  propagation cap for these; additive, byte-gate-protected)
- func_8012ACE0 family: 133/133 siblings BANKED, 0 failures; R22 clean-fleet 136/136
  byte-identical; 0 NON_MATCHING (G4)
- metrics: distinct-code 39.1% (50,698 unique fns), instr-weighted 63.0%
- opportunity (has_mid_jr families): 237 total (5,805 members) = 46 small mid/tiny
  (771 members, same mechanical pipeline) + 191 substantial (the Fable5 cores, Task 7 paused)
- NEXT: R22 profiling/parallelization; then the other 45 small jr families
2026-07-12 19:02:25 -06:00
Drew T 095a611e75 feat(phase-26): §8 jtbl-rodata tooling — overlay PoC proven (func_8012ACE0, R22 136/136)
- overlay jr-functions can now bank as C: gcc switch jump tables form a .rodata island at
  the overlay TAIL; carve a matched fn's jtbl into a dotted [.rodata, <code-subseg>] subseg
  + ld_interleave (data->rodata->data sandwich) places it byte-exact. cookbook §8a + SETUP.
- tools/ld_interleave.py: --section .<binary> param (derives the <binary>_TEXT/DATA/RODATA/
  DATA2/BSS symbol prefix); default .main = the EXE, byte-identical (backward-compat proven)
- Makefile + config/overlays.mk: <bin>_JTBL_INTERLEAVE hook + a $(strip)-guarded extract
  branch (gotcha caught: a trailing #comment on the := left whitespace -> non-empty -> the
  branch misfired on resident with the EXE defaults)
- PoC: func_8012ACE0 (25-ins jr-fn in ov_SC01_077) reconciled (canon_sig_reconcile) + banked
  BYTE-IDENTICAL d19c9580 -- the first overlay jr-function matched through the C pipeline
- R22 FULL-FLEET clean rebuild: 136 passed, 0 failed (main 143dbb89 unaffected by the
  ld_interleave change); 0 NON_MATCHING in any default build (G4)
- P9 findings: func_80159C84/func_8015444C (the 2 carried Fable5 jr bodies) are rtu_match
  FALSE-matches (incomplete jtbls: 52B vs 56B -> never bank); the maspsx "hang" scare was a
  truncated experimental-file artifact (real pipeline builds in ~1s)
- metrics: distinct-code 39.1% (50,572 unique fns), instr-weighted 62.9%
- NEXT: the ×134 automation (generate the per-overlay carve + template the reconciled body)
2026-07-12 16:37:37 -06:00
Drew T f62cd42c32 feat(phase-24): T7 §G — func_801372B0 banked ×134; ×1→×134 giant endgame COMPLETE; fleet 65.99→66.02%
- func_801372B0 (207 ins, reach-134) propagated ×134: unique-renamed its local SVEC/GLINE
  -> Svec_801372B0/Gline_801372B0 (a DIFFERENT same-named SVEC/u16 lives in _after.c, so a
  bare-name lift would double-define fleet-wide) + lifted to engine_types.h; ov_SC01_077
  byte-neutral (d19c9580); dedup_propagate --recover -> 134 byte-identical, E_func_801372B0.
- Clean fleet check-all 136/136 (R22), dedup-check 1812->1813/0, fleet 65.99->66.02%.
- Completeness scan (R14): NO matched giant remains ×1. Only small reach-134 ×1 fns left
  (3 now-propagatable stragglers + 17 local-type-blocked) = the T8 tail.
- The giant endgame is fully banked ×134 (whale + 6 §G cracks + func_801770E0 + func_801372B0);
  the 2 remaining reach-134 giants are permanent walls (func_80178004, func_801412A8 — G4).
- cookbook §39: native-DEFINE-path for -O2 giants (whale shared-header is -O0-only) · the
  overlay_files post-whale-split gap · find_site extern-comment class · unique-rename
  typedef-lift · R14 handoff-staleness.
2026-07-07 23:39:27 -06:00
Drew T 8e6658ee85 feat(phase-24): T7 §G — func_801770E0 banked ×134 (native DEFINE-macro path); fleet 65.95→65.99%
- func_801770E0 (152 ins, reach-134) propagated ×134 via dedup_propagate --recover.
  Chose the NATIVE DEFINE-macro path over a hand-rolled shared header: func_8014E048
  (pins+asm) is already ×134 via a DEFINE macro, proving that path handles pin/asm -O2
  giants (the whale needed a shared header only because it is -O0 -> separate object).
  Clean fleet check-all 136/136 (R22), dedup-check 1811->1812/0.
- R14: func_8014E048 was ALREADY ×134 (T6 §A) — the whale-session handoff was stale;
  only func_801770E0 + func_801372B0 actually remained ×1.
- tooling (reusable): dedup_propagate.overlay_files now also scans the whale-rollout
  _o0b/_after splits — post-whale-region fns (func_801770E0 in _after.c) were invisible
  for both source-def-find and stub-replacement. func_801770E0 extern block made
  contiguous (a comment between externs made find_site drop 5 externs; byte-neutral).
2026-07-07 23:21:20 -06:00
Drew T 8cfbbf2d47 feat(phase-24): T7 whale func_80144B9C banked ×134 (-O0 reach-134 rollout) — clean fleet 136/136
The single biggest byte-weight lever (770 ins ×134 ~ +1.6% byte-weight), banked across all 134
overlays as -O0 compiled C (was ×1 in ov_SC01_077, commit:0463).

- ROLLOUT (tools/rollout_whale_o0.py): per single-file overlay, LINE-split <ov>.c at the whale
  (splat emits in vram order), carve the yaml code subseg into before/<ov>_o0b(-O0)/<ov>_after,
  thin <ov>_o0b.c #includes the shared src/shared/func_80144B9C.h (the whale C moved there — DRY,
  TU-local typedefs, not a fragile 200-line DEFINE_ macro). Makefile WHALE_O0B_OBJS wildcard -O0.
- DEDUP: group E_func_80144B9C (134 members, h_exact 74186b97, source=the header; group_members
  keys on binary+vram so a header-share validates like a macro-share).
- MILESTONE: clean fleet check-all 136/136 (R22); dedup-check 1811/0; FLEET REAL 225816->225949,
  byte-identical 65.91->65.95% function-count (the gain is byte-weighted). Validated on ov_SC01_000
  + spot-checks SC02/SC03/SC07 before the full fleet.
- cookbook §38 + SETUP inventory.
2026-07-07 22:23:10 -06:00
Drew T 3b0cc190b2 feat(phase-24): T7 whale func_80144B9C CRACKED + banked ×1 (-O0 struct-assign) + ×134 infra
- CRACK (cheap Opus, no Fable5/calls.c): the 770-ins reach-134 whale's 2-insn residual was a
  STRUCT ASSIGN `D_80078E50 = *ent;` (sizeof(ENT)==0x24), NOT an explicit memcpy() call — gcc-2.7.2
  -O0 expands a >MOVE_RATIO-word struct copy via emit_block_move->emit_library_call(memcpy),
  precomputing dst/src into pseudos then addu into $a0/$a1 = the exact 2 missing moves.
- -O0 SPLIT: whale is a 2nd -O0 region (prologue 21F0A003) in the -O2 'after' segment; carved into
  its own -O0 object o0b (splat.ov_SC01_077.yaml 3-way + Makefile CC1FLAGS=-O0; address-sorted
  line-split preserves all banked C). ov_SC01_077 == d19c9580.
- memcpy: memcpy=0x8005C324 in symbols.resident.txt (overlays+resident only; main untouched vs its
  MEMCPY.o) + __asm__("memcpy") on the engine_core.h block-copy macro (non-builtin C name -> no
  built-in codegen, same call).
- MILESTONE: CLEAN fleet check-all 136/136 byte-identical (R22), dedup 1810/0. reach-134 -> ×134 (W9) next.
2026-07-07 22:01:58 -06:00
Drew T c106774776 feat(phase-24): T7 §G — 6/8 giants cracked, 4 ×134; fleet 65.75→65.91%
- MATCHED 6 reach-134 giants: func_801571C4 (permuter), func_8014EA4C/801372B0/
  801770E0/80176D94/80148094 (Fable5, sequential idiom-banking chain)
- 2 genuine walls stay INCLUDE_ASM (G4): func_80178004 (close=7), func_801412A8 (close=29)
- propagated x134: func_801571C4/8014EA4C/80176D94/80148094 (134 overlays byte-identical;
  dedup 1810 groups/0 failed; genuinely-clean make-clean+extract-all+check-all = 136/136)
- func_801372B0/801770E0 banked x1 (x134 follow-up: pin/asm + local-type self-containment gaps)
- tools: p16_permute.py comment-fix (unblocked the permuter fleet-wide) + permuter_ils.py (warm-restart ILS)
- knowledge: cookbook §37 + docs/gcc-2.7.2-map/t7g-giant-harvest.md
2026-07-07 20:20:43 -06:00
Drew T 8ba3b82307 feat(phase-24): T7 — 3 Fable5-cracked giants ×134 (func_801392FC/8013A530/8013AF20); fleet 65.64->65.75%
- func_801392FC (182, close=2->MATCH): CROSS-BB COMBINE LAW (a backedge-crossing count is a variable,
  not a foldable (s16)load; reorg steals the sll into the delay slot) + VOLATILE-FRAME-PARITY (volatile
  count-load avoids the cse-common -> combine keep-load -> stale-allocno reload slot). cookbook §36.
- func_8013A530 (204, close=10->MATCH): the RC-6 'reload knot' WAS the pins; the $0-ADD OPAQUE COPY
  (iVar7 = fc + zr, zr=$0) assembles to addu $v1,$a1,$zero but doesn't reserve the reg + 3 zero-byte
  levers. regalloc.md RC-12/RC-13, §36.
- func_8013AF20 (185, close=15->MATCH): the 'impossible' const-hoist order was libgpu addPrim's 24-bit
  BITFIELD store (store_fixed_bit_field emits 0x00ffffff first) + delete the inherited barrier; P_TAG
  lifted to engine_types.h (byte-neutral). loop.md, RC-7, §36.
- banked via the §35 recipe (fix_arity_callers --any-proto -> sig_unify -> harvest_verify ->
  dedup_propagate --recover). clean fleet check-all 136/136, dedup 1806/0, 0 NON_MATCHING.
- SESSION: 7 giants ×134 total (1 R14-free, 2 Opus-solo, 4 Opus->Fable5); fleet 65.48 -> 65.75%.
  gcc-2.7.2 reference tree extended (expmed.c/mips.md/... added). Giant queue (§G) stored for next session.
2026-07-04 04:14:43 -06:00
Drew T 6802997180 feat(phase-24): T7 — 2 more giants ×134 (func_8012D098 + func_8012EC04, one-shot Opus); fleet 65.56→65.64%
- func_8012D098 (189 ins, ALL 8 $s regs) + func_8012EC04 (178, sibling+GTE-tail): both MATCHED by
  Opus alone applying §32/§34 — NO Fable5. Finding: the '3 hardest 8-$s-reg giants' were mis-ranked;
  their $s pressure is param/buffer-derived, not global-array hoists -> Opus one-shots them.
- banking recipe (per-giant integration is mechanical, §30a): fix_arity_callers --any-proto
  (no-proto the conflicting caller extern vs the matched def-sig) -> sig_unify (callee proto) ->
  strip draft-local typedefs already in engine_types.h + anonymize named locals -> harvest_verify
  ×1 -> dedup_propagate --recover ×134. (skip cast_call_sites — it mis-casts no-proto void f().)
  clean fleet check-all 136/136, dedup +2 groups/0 failed, 0 NON_MATCHING.
2026-07-03 23:50:05 -06:00
Drew T 994368fbcd feat(phase-24): T7b/T5 — 2nd giant func_80138ED0 MATCHED + banked ×134; fleet 65.52→65.56%; §34 idioms
- func_80138ED0 (159 ins, reach-134): Opus applying §32 -> close=21 (all semantics/control-flow/
  constants exact, +the giv-init fence lever) -> Fable5Max reading the vanilla gcc-2.7.2 source ->
  MATCH (every regalloc/sched class C-reachable, no permuter).
- banked via the standard pipeline (validates it on a real un-reconciled sibling): cast_call_sites
  reconciled func_8013914C (u8*,u16*)->(s32,s32)+cast; reconcile_decls a NO-OP (2 data bases
  giant-local -> no fleet conflict, confirms no false-positive); harvest_verify ×1 d19c9580 ->
  dedup_propagate --recover ×134 (pins/asm body propagates fine). clean fleet check-all 136/136,
  dedup 1800->1801/0, 0 NON_MATCHING.
- NEW §31 idioms (cookbook §34 + regalloc.md RC-11 + loop.md): gcc-2.7.2's 3-qty local-alloc SORT
  BUG (local-alloc.c:1441 — <=3 qtys allocate in creation not density order; decoy-qty fix) + the
  zero-byte asm allocation toolkit (input-only/multi-input/def+use dummies) + the giv-init fence +
  gdb-on-cc1. gcc-2.7.2 reference tree completed (18 .c); SETUP §5.6.
- T5 satisfied: reconcile_decls proven on 2 real giants (func_80129CF8 reconcile-path byte-proof +
  func_80138ED0 no-op/full-pipeline). CURRENT_PHASE T5 logged.
2026-07-03 21:09:38 -06:00
Drew T eb53ae988e feat(phase-24): T7b/T1 — func_80129CF8 ×134 (the "×134 wall" was an R14 misdiagnosis); fleet 65.48→65.52%
- R14: diagnosed the prior "×134 BLOCKED / all overlays excluded" by RUNNING it — refuted.
  func_80129CF8's ×1 bank was already fleet-canonical; dedup_propagate --recover propagates it
  to all 134 overlays byte-identical (no new tool needed). The "wall" was a stale-asm /
  incremental-tree artifact (the T5c/T6-§A trap).
- banked ×134 via existing dedup_propagate --recover; clean fleet check-all 136/136,
  fleet 64.90→65.52%, dedup 1799→1800/0, 0 NON_MATCHING (G4).
- T7b reframed: the reconcile tool automates the manual decl-reconcile for FRESHLY-matched
  giant drafts (the 6 sibling giants + wave tail), not an 'unlock' of already-reconciled giants.
- CURRENT_PHASE: T1 done + the R14 finding logged; plan plan-…mossy-dawn.md (T1-T6).
2026-07-03 17:44:29 -06:00
Drew T 99ccc37480 feat(phase-24): T6.4 — find_site trailing-comment externs → func_8014E048 + func_80157580 ×134
- find_site extern-collection: allow a trailing `/* comment */` after the `;`. The
  comment-blind regex `^\s*extern\b.*;\s*$` stopped the backward scan at
  `extern u8 D_801152A8[];   /* canonical TU type */`, dropping every EARLIER extern →
  compiles_standalone failed on the now-undeclared callees/data (func_80135A4C,
  func_80133784, D_801152A8). R14: THIS — not "pin/asm" as the backlog framed it — was
  func_8014E048's real self-containment blocker.
- propagated func_8014E048 (the T5b S11 pins+barrier crack) + func_80157580 ×134;
  dedup 1797→1799 groups (0 failed). CLEAN fleet check-all 136/136 BYTE-IDENTICAL (R22).
  Fleet byte-identical 65.40% → 65.48%.
2026-07-03 15:17:50 -06:00
Drew T 5b3697553f feat(phase-24): T6 — 13 leaf-MATCH fns propagated ×134 (fleet 64.90→65.40%)
find_site + dedup_propagate --recover + build_engine_types fixes, then re-bank
the 13 recover_integration leaf-MATCHes and propagate each across all 134 overlays.

- find_site: match INDENTED inline defs (was column-0 only, silently dropping every
  recover_integration-banked def from propagation — T6 blocker 1). Unit-tested:
  indented defs match; indented call-exprs (if/assign/bare/return) correctly rejected.
- dedup_propagate --recover: on a straggler byte-gate failure, FIRST no-proto that
  overlay's conflicting caller extern + re-gate (Part B, byte-neutral, same lever as
  fix_arity_callers --any-proto); else EXCLUDE only that overlay (Part A, ×N-1) rather
  than the historical all-or-nothing drop. Wired into gate_stage.
- build_engine_types: comment-aware find_defs/find_typedefs (blank_comments). The
  generated header's own "...typedef lift" comment was captured as a bogus `typedef
  vec`, self-colliding and blocking every --strip. NOTE: full --strip still conflicts
  with the _a/_o0 split files, so split-file overlays need a TARGETED lift.
- banked + propagated 13 fns ×134: func_8014F74C 801542A4 8015BE94 8015F380 80160F00
  801653B8 80166244 8016E778 801732C4 8017331C 80173374 80174554 801745AC.
  func_8014F74C needed PosT/MoveT lifted to engine_types.h (targeted, byte-neutral).
- dedup 1784→1797 groups (0 failed). CLEAN fleet check-all 136/136 BYTE-IDENTICAL (R22:
  make clean && extract-all && check-all). Fleet REAL 224073, byte-identical 65.40%.

R14: the confounding stale-asm/ tree (13 missing .s) that masked the first --recover
test is fixed by re-extract; the 3 pre-existing --auto-from stragglers (0x80174650/
8012A018/80165CA0) are pin/asm + uncaptured-local-macro (SHB) bodies, correctly dropped.
2026-07-03 15:00:46 -06:00
Drew T be38b94147 feat(phase-24): T6 — flagship func_80132784 propagated ×134 (+1.6% byte-weight) via straggler-reconcile
The 400-ins giant func_80132784 (S11 prologue-weave; cracked T4, banked ×1) is now shared across
ALL 134 overlays byte-identical — the highest single byte-weight lever in the project.

- Blocker (T4-deferred): dedup_propagate's single-`--addr` plan is all-or-nothing; ONE straggler
  overlay (ov_SC02_005) failed to compile the shared macro -> the whole fn dropped, kept ×1.
- Root cause: ov_SC02_005 declared a CONFLICTING caller extern `void func_80132784(s32,s32,s32)`
  while the def is `(s32,s32,u32)` (3rd param s32 vs u32) -> `conflicting types`. The call site
  casts `((void(*)(u8*,u8*,u16))func_80132784)(...)` so the extern type is codegen-irrelevant.
- Fix (T6 integration-recovery pattern, proven): reconcile the straggler's caller extern to the
  def's canonical signature (s32->u32, byte-neutral), then propagate. dedup_propagate then rebuilt
  all 134 overlays BYTE-IDENTICAL; registered group E_func_80132784 (134 members).
- dedup-check: 1784 validated, 0 failed. Verified by a clean R22 fleet check-all (136/136).
- This is the concrete spec for the T6 tool: detect a straggler's conflicting caller decl,
  reconcile to the def's canonical sig, re-gate, propagate full (vs. the all-or-nothing drop).
2026-07-03 04:21:15 -06:00
Drew T fcfe3afea6 feat(phase-23): gccmap-remat gate — +1 fns x1 propagated (fleet 64.86%) 2026-07-02 20:08:10 -06:00
Drew T 396fd28398 feat(phase-23): toolkit-storeload gate — +2 fns x2 propagated (fleet 64.82%) 2026-07-02 17:33:17 -06:00
Drew T 6678c6868a feat(phase-23): Fable5Max cracks §20 "unsteerable" giant func_8014EE14 ×134
- Fable5Max agent (Agent model=fable) matched a 248-ins reach-134 GIANT on the
  §20/§10 store-vs-load wall (22 phases "CONFIRMED unsteerable") by reading the
  gcc-2.7.2 source (tools/reference/gcc-papermario) + RTL -da dumps. Leaf
  MATCH(248 ins) -> whole-binary banked:1 -> dedup_propagate ×134. Verified:
  check-all 136/136 byte-identical, dedup-check 1780 validated/0 failed.
- 3 byte-proven idioms -> cookbook §30 (corrects §29's "not a bigger model"):
  (1) store-vs-load is a deterministic MEM_IN_STRUCT_P /s aliasing flag, not a
      scheduler tie-break; steer via ((struct{s32 f;}*)p)->f (anon struct keeps
      /s AND propagates ×134) to grant, *p to deny
  (2) def-side return-type wall has a MACRO escape: widen a discarding caller
      macro's extern void->s32 (byte-neutral, check-all-verified) -- extends §29
  (3) birthing-boost prologue-order lever: __asm__("":"=r"(x):"0"(x)) re-tie in a
      later bb kills sched.c's REG_N_SETS==1 priority boost
- tools/glm_parallel.sh: K concurrent OpenRouter/GLM cloud drafters (parallel
  api_draft), key read from .env at runtime
- §10/§20 "store-vs-load unsteerable" backlog now re-test candidates:
  func_8014F2E0, func_80150528, func_8014EA4C
2026-07-02 16:56:56 -06:00
Drew T 13122771a0 feat(decomp): bulk_harvest — +45 fns across 13 binaries, 6 propagated (fleet 64.7%) 2026-07-02 15:29:38 -06:00
Drew T 0d1e8d2372 feat(decomp): bulk_harvest — +44 fns across 18 binaries, 3 propagated (fleet 64.69%) 2026-07-02 14:57:27 -06:00