Commit Graph

313 Commits

Author SHA1 Message Date
Drew T 98775dd1d5 feat(phase-30 S1): func_80135260 zero-crack sweep (136 ins) 2026-08-01 09:06:58 -06:00
Drew T 3ffd9e5419 feat(phase-30 S1): func_8017AE2C zero-crack sweep (174 ins) 2026-08-01 09:06:50 -06:00
Drew T 0367bde898 feat(phase-30 S1): func_80159C84 zero-crack sweep (337 ins) 2026-08-01 09:00:17 -06:00
Drew T e845a3ab48 feat(phase-30 S1): func_8015444C zero-crack sweep (363 ins) 2026-08-01 08:58:30 -06:00
Drew T c373e5a2dd feat(phase-30 S1): func_8013FFD8 zero-crack sweep (213 ins) 2026-08-01 08:56:08 -06:00
Drew T 91973fb2f7 feat(phase-30 S1): func_8017A4AC zero-crack sweep (536 ins) 2026-08-01 08:55:01 -06:00
Drew T 8f837f6196 feat(phase-30 S1): func_8015AE2C zero-crack sweep (562 ins) 2026-08-01 08:54:33 -06:00
Drew T 79b896caac feat(phase-30 S1): func_8015A3C8 zero-crack sweep (493 ins) 2026-08-01 08:54:07 -06:00
Drew T da5090ee03 feat(phase-30 S1): func_8017BEBC zero-crack sweep (952 ins) 2026-08-01 08:51:48 -06:00
Drew T b96352e9ec feat(phase-30 S1): func_8014032C retry without --span-rel — the spans that hold only the NEW tables 2026-08-01 08:45:39 -06:00
Drew T 7c5d308c49 feat(phase-30 S1): func_8014032C sibling sweep — 183 ins x137 (see log) 2026-08-01 08:42:12 -06:00
Drew T 10dc6d3635 feat(phase-30 S1): --span-rel unblocks the zero-crack head; func_8014032C ×1 probe banks (§132b)
S1's head family (0x8014032C, 183 ins ×137 = 25,071 templatable ins) gate-failed on its probe
sibling. Diagnosis (the §132 ladder, one build): the object emits FOUR tables — BOTH functions in
it are multi-switch (8+5 entries each) — while the carve derived THREE starts.

The missing start belongs to the ALREADY-MATCHED owner func_8013FFD8, and neither oracle can see
it: its stub .s is pruned by extract, and its second table abuts its first with NO pad (8 entries
= 32 B = 0 mod 8, so `.align 3` emits nothing) — precisely the honest limit §132's payload
zero-word recovery documents. Note the true pads [0,0,4,0] are exactly what natural alignment
produces; the build breaks only because a SHORT spec gets written.

Fix: thread the documented `--span-tables` escape through the sweep as `--span-rel` — offsets
relative to the FIRST NEW table, which func_jtbls reads from the sibling's own .s. Byte-verified
family-invariant before use (identical relative offsets on 3 sampled siblings; same code, same
entry counts, only the base moves). Empty by default => every other family untouched.

Also clears my own §132a guard of suspicion (R14): the --like transfer was inert here regardless
(exemplar subseg `ov_SC01_077` vs sibling `_jr_8013FFD8` — roles never matched).
2026-08-01 08:26:30 -06:00
Drew T 73570a5089 feat(phase-30): func_8013B83C ov_SC07_010 + the --like over-transfer guard (§132a)
The one sibling both sweeps failed on. `--like <exemplar>` transfers the exemplar span's table
STRUCTURE, and jtbl_carve matches donor to recipient by the subseg's ROLE NAME. ov_SC07_010's
-O0 region is named `_o0` — the same role as ov_SC01_077's, and the ONLY other overlay so named
(the other 136 are `_o0c`, whose role never matched, which is the only reason the sweep worked).
The exemplar had just banked 2 more owners than the sibling has, so the transfer unioned its
rebased 4 offsets with the sibling's real 2 + the new table: SIX starts for THREE emitted tables
-> jtbl_rodata_pads refused ("consumed 3 rodata .align(s) but 6 pad spec(s)").

Guard (tools/jtbl_family_bank.py like_arg): suppress --like when the sibling already carries a
committed `tables=` for the target subseg — its own record is authoritative, and jtbl_carve's new
payload zero-word recovery covers the incomplete-record case that --like used to paper over.
Derived via jtbl_carve.func_subseg, the same derivation the carve itself uses (R33); never blocks
a bank (any failure falls back to the old behaviour). Inert for all 136 siblings already banked;
fixes exactly the broken one. Both fns now bank on ov_SC07_010 => 137/137 siblings each.
2026-08-01 00:11:35 -06:00
Drew T bd92809da6 feat(phase-30): func_8013BD74 ov_SC07_010 — the --like over-transfer guard unblocks the last sibling 2026-08-01 00:11:14 -06:00
Drew T bfabf0906d feat(phase-30): func_8013B83C sibling sweep — jtbl_family_bank ×N (see log) 2026-08-01 00:08:50 -06:00
Drew T 5ea269af84 feat(phase-30): func_8013BD74 sibling sweep — jtbl_family_bank ×N (see log) 2026-07-31 23:55:22 -06:00
Drew T 8cd0c50f6d feat(phase-30): func_8013BD74 ×1 (ov_SC01_000) — the 1-sibling sweep probe banks 2026-07-31 23:40:18 -06:00
Drew T b9efe66f91 fix(phase-30): the JR-PAIR "wall" was TWO instrument defects — pair banked, class retired
S28 ledgered `JR-PAIR-IN-ONE-O0-OBJECT` (two jr fns matched in one -O0 object => a clean
build that cannot link: `undefined reference to $L105` + `func_8013C938`) with §81 step 1
(isolate one into its own code subseg) as the untested escape. BOTH the class and the escape
are REFUTED — no isolation, no compiler wall, both fns banked from a genuinely clean fleet.
The 4th consecutive "structural wall" to resolve to our own tooling (§124/§125/§126/§131).

- DEFECT 1 (tools/jtbl_carve.py): ov_SC01_077_o0's carve at 0xb01a4 predates the §8e
  `tables=` persistence and is a MERGED DOUBLE (func_8013C0F8 $L75 + func_8013C414 $L105);
  the 2nd owner is MATCHED so extract pruned the stub .s naming its table. The single-table-
  predecessor inference derived 3 starts where the object emits 4 tables -> JTBL_PADS 0,4,4
  -> jtbl_rodata_pads refused mid-stream, correctly. FIX: R32 coverage assertion + payload
  recovery at the single choke point (spec_from_starts) — every zero word inside a span is an
  original `.align 3` pad (the tool's own axiom), so the word after it STARTS a table;
  recovered starts are logged. No-op where structure is known (the 134 sibling _o0c spans
  carry tables=+0x0,+0x70). Honest limit: tight (0-pad) boundaries stay unrecoverable but
  fail LOUD via the filter's count guard — never silent.
- DEFECT 2 (Makefile): no .DELETE_ON_ERROR, so `as` (a pipeline consumer) left a TRUNCATED .o
  on disk — 12 of 16 T func_, undefined $L57/$L59/$L63/$L75/$L76 — newer than its .c, and the
  NEXT build linked the corpse. That IS the S28 link error, one build downstream of a loud,
  correct compile error. Negative-control-proven on a scratch invocation.
- BANKED: func_8013B83C (272 ins) + func_8013BD74 (198 ins) in ov_SC01_077 (d19c9580).
  Byte proof: 4 tables 0x801D8254/828C/82FC/836C (13/27/27/27 entries, each zero-pad
  separated); span 0xb00fc..0xb0280 = 388 B = 52+4+108+4+108+4+108 exactly; spec 0,4,4,4.
- R22 clean-fleet (make clean + extract-all + check-all): 140 passed, 0 failed of 140.
  The incremental result was NOT trusted (§130). Fleet 93.25% fn-count / 89.2% instr /
  80.5% distinct; dedup 1905/0; 0 NON_MATCHING (G4).
- cookbook §132 + index (356 sections): the mechanism, the fingerprint (an undefined $L<n> in
  a LINK error is a truncated object, never codegen), the 30-second standalone-TU ladder that
  named the 4th table owner before any build, and the transferable rule — a fail-loud guard is
  only as trustworthy as the artifact hygiene around it.
2026-07-31 23:35:14 -06:00
Drew T 0958120006 fix(phase-30): jtbl_carve OVER-SPAN clamp — the one real instrument failure, root-caused and fixed; behemoth func_80191C50 (710 ins) banked
The last surviving "compiler wall" of the session turned out to be an off-by-one-word
carve. Chain, all byte-grounded:

SYMPTOM   jtbl_carve diverges on ov_SC06_018 after a BYTE-NEUTRAL jr_isolate_all.
SHAPE     image -3 bytes; 853 differing bytes in 699 scattered runs; **812 at byte 0 of a
          word** = the low byte of a 16-bit immediate, every sampled one changing by
          exactly -4. Not a shift, not a pad: hundreds of `%lo` operands 4 bytes low.
CAUSE     func_80191C50's own `sltiu $v0,$v1,0xC` names 12 entries; the emitted .rodata
          holds 12 words; the carve reserved 13. The 13th word (0x3038200A) is ordinary
          NON-ZERO data that spimdisasm ran into the dlabel span (the next dlabel sits
          past it). Reserve 13 / supply 12 => the .rodata piece UNDER-FILLS by one word
          => every later symbol slides down 4 bytes.
WHY MISSED The trailing-trim's axiom is "0x00000000 cannot be a jump target", so it only
          trims ZERO words. This surplus is non-zero, so nothing trimmed. The tool already
          treats `sltiu` as ground truth - it EXTENDS a table spimdisasm cut in half, and
          it WARNS when a span is too short - but had no clamp for a span too LONG.

FIX: an over-span clamp with the SAME authorization as the existing extension logic -
only when the `sltiu` bound is UNAMBIGUOUS (one bound; a multi-switch fn cannot say which
table owns which), and only when the surplus words are NOT plausible code addresses. If any
surplus word looks like a real entry it REFUSES LOUDLY rather than silently dropping one.

  jtbl_carve: jtbl_801D3BA4: clamped 1 trailing NON-ZERO word(s) - func_80191C50's own
  `sltiu 12` names 12 entries and the surplus is not code

Then: carve BYTE-IDENTICAL, draft spliced, **func_80191C50 (710 ins) BANKED**.
R22 CLEAN-FLEET: extract-all 139/139 (+main); check-all 140 passed, 0 failed of 140.

Retires the JTBL-CARVE-BREAKS-BYTES ledger class: the one instrument failure that survived
this morning's retraction round was REAL, and is now a named bug with a fix - not a wall.
2026-07-31 20:02:55 -06:00
Drew T f5af36c955 Revert "chore(phase-30): jtbl carve for func_8013BD74 in ov_SC01_077 (byte-neutral, R22 140/140)"
This reverts commit commit:1287.
2026-07-31 14:40:36 -06:00
Drew T fc08b12df6 chore(phase-30): jtbl carve for func_8013BD74 in ov_SC01_077 (byte-neutral, R22 140/140)
The SS81 chain's step 2, landed on its own so the bank can build on it: harvest_verify
refuses to run on a dirty tree (SS97 gate hygiene), and the carve necessarily dirties
config/. Carve applied -> byte-identical -> R22 140/140 -> committed. The draft bank
follows as its own step.
2026-07-31 14:37:47 -06:00
Drew T e1b0cd9acd feat(phase-30): jr cluster family func_8013C414 swept 137/137 (329 ins x137), R22 140/140
The second and last has_mid_jr family of the -O0 cluster. Same route as func_8013C0F8:
jtbl_family_bank (the SS81 carve chain per sibling) -> 137 BANKED / 0 failed.

Both jr families together: 274 members, 483 ins x137 = ~66k instructions, 0 failures.
Neither was bankable before commit:1270 routed the destination TUs to -O0.

R22 CLEAN-FLEET: extract-all 139/139 (+main); check-all 140 passed, 0 failed of 140.
2026-07-31 11:36:31 -06:00
Drew T 5d1e2ac36f feat(phase-30): jr cluster family func_8013C0F8 swept 137/137 (154 ins x137), R22 140/140
The first of the two has_mid_jr families SS53 correctly refused from the carve-less
family_sweep. Routed through the tool its tier needs (jtbl_family_bank, the SS81 carve
chain per sibling) it banks CLEAN:

  jtbl_family_bank func_8013C0F8 ov_SC01_077 0x8013c0f8  -> 137 BANKED / 0 failed
  ~7s per sibling (carve + extract + remap + whole-binary gate), ~16 min total

Only possible now because commit:1270 routed each destination TU to -O0; before that the
member's home file compiled -O2 and no body could ever match there (SS116).

INDEPENDENT CONFIRMATION OF THE SS125 DIAGNOSIS: this is the SAME tool that returned
gate-fail on every group-B (func_8017BEBC) probe earlier today. 137/137 here versus 0/4
there, same jr machinery, is exactly what the carve-vs-body diagnostic concluded --
group B's failures are its BODY, not the carve. I had first blamed the carve; the
body-free probe corrected it, and this run corroborates the correction from the other side.

R22 CLEAN-FLEET: extract-all 139/139 (+main); check-all 140 passed, 0 failed of 140.
2026-07-31 11:20:10 -06:00
Drew T b5362c7b7f feat(phase-30): the -O0 cluster HARVEST — 1,364 banks for ZERO agent tokens; fleet 92.71->93.09% fn / 88.3->88.6% instr / 78.7->79.3% distinct
The payoff of routing the cluster to -O0 (commit:1270). These functions were ALREADY
CRACKED in ov_SC01_077 and could not be banked anywhere else purely because every
destination file compiled -O2. With the destinations now -O0, they template in
deterministically -- no drafting, no agents.

  dedup_propagate --recover  0x8013C360 (h_exact x138)  -> 137 overlays byte-identical
  family_sweep --hseq        10 variant families         -> 1,227 banked / 133 failed (90%)
                                                            1360 staged across 136 groups
  ------------------------------------------------------------------------------------
  1,364 new banks

FLEET: fn-count 92.71 -> 93.09% · instr 88.3 -> 88.6% · distinct-code 78.7 -> 79.3%
(71,756 / 87,459 unique fns; +1,162 unique). dedup 1904 -> 1905 groups, 0 failed;
C1 coverage 240496/240496. 0 NON_MATCHING in any default build (G4).
R22 CLEAN-FLEET: extract-all 139/139 (+main); check-all 140 passed, 0 failed of 140.

--recover WAS LOAD-BEARING (SS75): without it dedup_propagate took its historical
all-or-nothing branch -- one failing overlay (the SOURCE, ov_SC01_077) dropped the whole
function and it printed "all candidates dropped", which reads exactly like a wall. Reading
the exclusion code instead of believing the message showed the remedy: --recover excludes
only that overlay (kept x1 with its own inline match) and propagates to the other 137.

The two has_mid_jr families in the cluster were REFUSED BY DESIGN, not attempted (SS53
interlock): 0x8013C0F8 (154 ins) and 0x8013C414 (329 ins), ~137 members each = ~466
members queued behind the jtbl carve path they actually need, rather than a fake 0% from
the wrong tool.

REMAINING in the cluster: the 133 sweep failures + the 2 jr families + the 3 addresses
never cracked anywhere (0x8013B83C, 0x8013BD74, 0x8013C08C) -- the last are genuine
drafting work, now finally possible since their TU is -O0.
2026-07-31 11:00:42 -06:00
Drew T b297c78193 feat(phase-30): T2 sweep — the -O0 cluster ROUTED fleet-wide (135 overlays, 2,200 stubs), R22 140/140
Applies tools/o0_subsplit.py across every overlay whose 0x8013B568..0x8013C98C -O0
cluster was trapped inside an -O2 jr split. This is the population the phase opened
against, and it has never been buildable-at--O0 before.

  135/135 sub-splits applied, 0 tool refusals
  140 new -O0 region files; corpus.o0_sources() 137 -> 277
  0 of them invisible to the -O0 oracle (verified explicitly -- a SILENT -O0 miss is
    the exact failure SS126 warns about: the region would compile -O2 and every residual
    it produced would be a pure artifact)
  **2,200 open stubs now live in a genuinely -O0 translation unit**

R22 CLEAN-FLEET: extract-all 139/139 (+main); check-all 140 passed, 0 failed of 140.
make tools-health OK: corpus(+resident) 0 PHANTOM/0 TRUNCATED; cdecl ALL ORACLES GREEN;
audit-binaries 140 onboarded, every one a full citizen (R36); dedup-check 1904/0,
C1 coverage 240359/240359; cookbook-index 336 sections.

The transform is byte-neutral by construction (it only moves subseg boundaries and
repartitions source), so the whole batch was gated by one clean-fleet R22 rather than
135 individual builds -- after a single-overlay probe (ov_SC01_000) proved it (R37).

NOTE THE POPULATION CORRECTION (R14, mine): I earlier reported this cluster as "275 open
stubs across 18 overlays". That was WRONG -- the sizing scan ran while R22 was rebuilding
in the background, so corpus.stubs() raised for most overlays and my bare `except:
continue` SWALLOWED the very coverage assertion R32 exists to raise. The true figure is
2,184 open stubs across 138 overlays, which vindicates the T0(f) pin of "2,192 open
members" that I had called stale. The target list for this sweep was rebuilt with NO bare
except, so R32 can do its job.

Drafting fuel confirmed present: cached Ghidra-C seeds exist for the cluster's addresses.
Drafting the 2,200 is crack-wave work (T3), not T2.
2026-07-31 10:13:44 -06:00
Drew T d2b48b7680 feat(phase-30): tools/o0_subsplit.py — the T2 carve-within-a-carve driver; +3 banked in ov_SC03_015
Promotes the proven probe (commit:1266) into a real tool, and validates it FIRST-TRY on a
fresh overlay.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

DRIVER DEFECT FIXED (mine, SS105/SS61): v1 of .run/s28_beh.sh `continue`d past a failed
gate WITHOUT reverting, leaving two half-carved overlays in the tree; only a full
`git checkout -- src/ config/` recovered it. Nothing was ever committed, so the cost was
build cycles and zero work. v2 reverts that target's config+src on EVERY failure path.
2026-07-31 08:03:08 -06:00
Drew T 0130fb340a feat(phase-30): wave-4 resumed 10/10 MATCH banked + h_exact leg (14 propagated); R22 140/140
The 12 agents killed by the usage-limit pause were resumed and ALL returned MATCH (2 had already
banked from their partial drafts, so 10 ran). h_exact propagation leg completed over all 112 banked
exemplars: 14 propagated, 42 benign skips (h_seq tier, correctly routed away per §123), 0 failures
— the 0x801466F0 'halt' was a third benign-refusal phrase, not a partial write.

fn-count 92.61 -> 92.67% | instr 88.2 -> 88.3% | distinct 70,581 -> 70,590 unique fns.
2026-07-31 07:25:47 -06:00
Drew T 471314da54 feat(phase-30): T3 waves 2+3 + 4 behemoths — 52 cores banked, 911 members propagated; R22 140/140
WAVE 3 (48 agents / 8 binaries, dealt across binaries so BANKING fans out): 48/48 match_one MATCH,
48/48 banked through 8 PARALLEL per-binary gates. WAVE 2: 15/19. BEHEMOTHS: 4 non-jr confirmed
(func_8017E120 884ins x14, func_8017FA5C 728, func_8017CAD4 755, func_8017E35C 719).
Tier-routed propagation (§123): family_sweep --hseq banked 911 members across 137 overlays.

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

CORRECTION (R14): the 'per-binary bank-rate cliff' I reported from the pre-incident gate run
(SC03_014 1/6, SC04_018 1/6, SC06_018 2/6) was an ARTIFACT — those gates ran against a tree
propagation was concurrently rewriting. Re-gated clean: 6/6 everywhere. A measurement taken during
corruption is not a measurement; I should not have theorised a cause before re-running it.
2026-07-30 22:22:35 -06:00
Drew T 159317d3fe feat(phase-30): T3 wave-1 — 8 cores banked + 4 propagated fleet-wide; R22 140/140 (fn-count 92.00 -> 92.16%)
Ultracode wave of 14 agents over fresh reach-138 cores: 14/14 match_one MATCH, 8 accepted by the
whole-binary gate (the §52b law reproduced exactly). Propagated per-function (the incident fix):
0x8012E014, 0x80151C54, 0x8012F49C, 0x80151B98 -> +573 instances. R22 clean-fleet 140/140;
instr 87.5 -> 87.7%, fn-count 92.00 -> 92.16%, distinct 69,828 -> 69,836.

The other 4 banked cores are h_seq (PURE/IMM) families: dedup_propagate is h_exact-only, so its
'reach<2' / 'not self-contained' refusals were statements about the TOOL's tier, not the functions
-> cookbook §123 (the §53 carve-law generalized to the propagation-tier axis) + a routing table.
They bank via family_sweep --hseq next.
2026-07-30 19:57:54 -06:00
Drew T d4dc533f54 feat(phase-29): T52 — func_80135260 swept 132/132 (0 failed); the family goes 4/137 -> 137/137
T51's payoff. The invocation is IDENTICAL to the T49/T50 runs; the only variable is T51's decl
scoping.

  T49/T50 (pre-T51)  4 banked / 133 gate-fail   (and all 4 were SC07 — a different cause)
  T52 sample (8)     8 BANKED / 8               52s
  T52 rest  (124)  124 BANKED / 124             13m04s
  TOTAL            132 / 132, ZERO failures

So the 133 "gate-fails" were never a codegen wall — they were one file-scope declaration per sibling
TU. Fifth time this phase a wall has resolved to tooling/plumbing.

GATES (from a genuinely clean tree): R22 clean-fleet `make clean && extract-all && check-all` ->
140 passed, 0 failed of 140. `make tools-health` OK — corpus 0 PHANTOM + 0 TRUNCATED, cdecl,
audit-binaries, report/lint/dedup 1886 validated / 0 failed (C1 239604/239604). 0 NON_MATCHING (G4).

METRICS (reconciled against make report, not asserted):
  instr-weighted   85.5% -> 85.7%   11240111 -> 11258063 = +17,952 ins
  distinct-code    76.1% -> 76.4%   67687 -> 67812 unique fns (+125)
  fn-count        90.62% -> 90.65%  320524 -> 320656 = +132 functions
  INCLUDE_ASM stubs 33189 -> 33057  = -132
+17,952 templated instructions against T50's ~18,000 estimate. distinct-code gains 125 not 132
because seven siblings are byte-identical to code already counted unique.

ALSO SETTLED:
- item 3 is now byte-confirmed, not just inspected: [gather_externs] warned "func_80135D20 ... the
  sibling will not compile" on ALL 132, and all 132 BANKED. A 100% false-alarm rate on this family,
  actively masking real causes. cdecl._mask is the fix (T51 used exactly that).
- the T51 pre-pass is now worth folding into jtbl_family_bank; T51 withheld that pending a measured
  payoff, and 4/137 -> 137/137 is it. Next task.

config/ (per-overlay splat.*.yaml + overlays.mk, written by the carve) is staged alongside src/ —
the `git add -A src/` omission this phase already recorded once.
2026-07-28 17:27:20 -06:00
Drew T 7b896a2627 feat(phase-29): T52 sample — func_80135260 8/8 banked; the T51 lever is validated
Bounded sample before scaling (the standing validate-on-a-sample invariant). The ONLY variable vs
the T49/T50 runs is T51's decl scoping; the invocation is identical.

  T49/T50 (pre-T51):  4 banked / 133 gate-fail  (and all 4 were SC07, a different cause)
  T52 sample:         8 BANKED / 8              in 52s

Committed here only because jtbl_family_bank's precondition refuses to run on a dirty config//src/
(its per-sibling revert restores from HEAD, so uncommitted banks would be silently wiped). The
remaining 124 follow in the next commit; R22 clean-fleet gates the whole task at the end.

Both config/ (the jtbl carve + overlays.mk) and src/ are staged — the omission this file already
warned about after a prior `git add -A src/`.

Also confirms item 3 empirically: [gather_externs] warned "func_80135D20 ... the sibling will not
compile" on every one of the 8, and every one BANKED. Comment-scanning false positive, as T50 said.
2026-07-28 17:04:09 -06:00
Drew T f3e8317bd1 feat(phase-29): T49 — func_80135260 x4 siblings + the 3,744-site decl conform
The §53 carve path banked only 4 of 137 siblings, ALL of them SC07 — the exact signature
func_80177DA8 showed before its §99 fix, so the same lever applies.

- jtbl_family_bank func_80135260: 4 BANKED / 133 gate-fail. The 4 are SC07 overlays.
- conform_decls dry run confirmed the class: byte-true def is
  `s32 func_80135260(s32, s32, s16 *, s16 *)` but 3,744 declaration sites say
  `(s32, s32, s32, s32)` — params 3 and 4 declared s32 where the byte truth is s16 *.
  Return type agrees, so the §85 return-axis precondition does not fire.
- Applied: 3,744 sites rewritten across 2,021 files; the tool's R32 assertion reports
  "non-canonical declarations remaining: 0  OK (axis complete)". It correctly SKIPPED the 5
  DEFINING TUs (the 4 SC07 banks + ov_SC01_077) — a defining TU owns its own declarations, since
  per-overlay byte-true signatures legitimately differ under §16 loose typing.
- This touches src/shared/engine_core.h, so it is FLEET-SHARED and R22 was mandatory (§61/§63):
  R22 clean-fleet 140 passed, 0 failed of 140.

Also recorded: jtbl_family_bank's [gather_externs] warning named func_80135D20 as an undeclared
referenced symbol, but that symbol appears ONLY in the draft's header COMMENTS (lines 3 and 29) —
a comment-scanning false positive, same class as the Phase-19 gen_harvest_targets garbled-hint bug.
It was not the cause of the 133 failures.

Next: re-run the carve path for the remaining 133 siblings now that the decl axis is conformed.
2026-07-28 15:47:52 -06:00
Drew T d6bd7bed9e feat(phase-29): T48 — func_80135260 BANKED; a file-scope extern is a TU-WIDE constraint on later functions
The T45 probe re-filed this as a crack target; it turned out to be a SCOPE problem, and the fix is a
new reusable lever.

DIAGNOSIS. The draft MATCHes standalone (136 ins) with block-scope `extern u16 *D_801870AC/B0/B8`,
which are byte-TRUE (they produce the target's 4-byte pointer loads). The TU carries FILE-scope
`extern u8 D_801870B0/AC/B8; extern s16 *D_801870B4;` at lines 3433-3436 — the preamble of the
already-banked func_80135168 — and a file-scope decl constrains EVERY LATER function in the TU, so
the draft's pointer decls became "conflicting types". Ordering is what makes this asymmetric: the
TU's own block-scope `extern u16 *D_801870B0;` at L2829 precedes the file-scope u8 decl and only
WARNS; a block-scope decl AFTER it is an ERROR.

TWO WORKAROUNDS MEASURED AND REJECTED, both +3 instructions with a rotated callee-saved bank:
  reconcile_tu (conform to the TU) -> 139 ins vs 136, 123 mismatched
  cast-at-use  (*(u16 **)&D_x)     -> 139 ins vs 136, 123 mismatched
So the byte-true code genuinely REQUIRES the pointer-typed declaration; the decls had to move.

THE FIX (move the decls, never the draft — §85 applied to DATA): scoped those four file-scope externs
into their only two consumers (func_80135168 and func_80135480, both of which already use the
cast-at-use idiom). Verified in two steps: (1) the decl move ALONE rebuilds ov_SC01_077 byte-identical
d19c9580 — declaration-only, no codegen change; (2) the original byte-true draft then banks clean,
verified 1 / failed 0. R22 clean-fleet 140 passed, 0 failed of 140.

THE REUSABLE LEVER: a FILE-scope extern in a shared overlay TU is a global constraint on every later
function in that TU. When a byte-true draft needs an incompatible type for the same symbol, scope the
existing decl to its consumers rather than bending the draft — bending it cost +3 here, twice.

Family sweep is NEXT and needs the §53 carve path (has_mid_jr: true, 137 siblings, PURE) —
family_sweep correctly refused it.
2026-07-28 15:16:38 -06:00
Drew T 75bed15697 feat(phase-29): func_80171B4C family banked 137/137 — wave22 complete (690 functions)
137/137 banked via jtbl_family_bank (jr family, carve-aware path). R22 clean-fleet 140 passed /
0 failed of 140. MEASURED: fn-count 319,412 -> 319,549 (+137); instr-weighted 84.7 -> 84.8%
(+9,590 ins); distinct-code 74.5 -> 74.7% (+130 unique fns).

WAVE22 COMPLETE: 18 targets drafted (12 MATCH / 6 NEAR / 0 FAIL, 2.59M subagent tokens) ->
5 exemplars banked -> 685 members swept -> 690 functions total.

This commit stages config/ EXPLICITLY. Twice today I omitted it and left a carve uncommitted, both
times caught by jtbl_family_bank's dirty-tree precondition rather than by me or any gate.
2026-07-28 01:03:33 -06:00
Drew T a8c0f83528 fix(phase-29): commit func_80171B4C's carve config — SECOND incomplete change set today
Same error as commit commit:1103 this morning, which I recorded as a lesson and then repeated: I scoped
`git add` to src/ and docs and omitted config/, leaving the jtbl carve that func_80171B4C's bank
depends on (its `- [0x499f4, c, …]` split + `.rodata` carve + the JTBL_INTERLEAVE order) uncommitted.
harvest_verify KEEPS a carve on success, so it is part of the banked state, and the R22 140/140 I
reported was verified WITH these files present.

Caught by jtbl_family_bank's dirty-tree precondition again — not by me, not by any gate. That is now
twice in one session that a tool's precondition was the only thing standing between a partial commit
and a broken HEAD.

THE REAL LESSON, and it is not "be more careful": a scoped `git add` is an UNVERIFIED ASSERTION about
a change set's boundary, and nothing in this project checks it. R32 says a claim like that needs an
assertion. The concrete guard: before committing banked work, `git status --porcelain config/` must be
empty or its contents must be part of the same commit. Recorded for the next session rather than
bolted on at the end of a long one.
2026-07-28 00:23:28 -06:00
Drew T 3d01aaea8c feat(phase-29): func_801789AC family banked 137/137 — fleet crosses 84% instr
137/137 banked, 0 failed via jtbl_family_bank. R22 clean-fleet 140 passed / 0 failed of 140; report
fail-closed green (dedup 1886/0, C1 coverage 239604/239604, 0 NON_MATCHING).

MEASURED: fn-count 318,447 -> 318,585 (+138); instr-weighted 83.9 -> 84.0% (+12,558 ins);
distinct-code 73.2 -> 73.4% (+131 unique fns — byte-VARIANT members, so unlike func_801330E0's
byte-identical family this one moves the distinct number too).

Closes the function REFUSED since SESSION-21 — correctly refused, since conforming its 660
declarations without first casting its 138 zero-arg call sites would have broken 138 binaries.

Also logged (T21): the sweep-throughput measurement. Drew was right that parallelism was proven and
adopted (Makefile JOBS=16; sweep_parallel.py -j12 built SESSION-20 after measuring an 8-16x loss),
but NEITHER sweep tool calls it — the adapter is reachable only via a manual --stage-only two-step,
so three sweeps today ran serially for no reason. The -j theory was wrong and measurement said so:
make is ~5s of the 16s per sibling (the loop runs up to FOUR builds per sibling), so -j16 is a 12%
win, kept but minor. The real 8-16x lever is blocked on revert() restoring the SHARED
config/overlays.mk from git — designed, not built. An attempt to wire family_sweep's parallel default
broke it twice and was reverted rather than committed.
2026-07-27 21:16:39 -06:00
Drew T 05cd7a5808 fix(phase-29): commit the jtbl carve config that belonged with func_801789AC's bank
MY ERROR: the previous commit scoped `git add` to src/ and tools/ and omitted config/, leaving the
jtbl carve's config (overlays.mk + splat.ov_SC01_077.yaml) uncommitted. harvest_verify KEEPS a carve
on success, so that config is part of the banked state — HEAD was an incomplete change set, and the
R22 140/140 I reported was verified WITH these files present, not without them.

CAUGHT BY jtbl_family_bank's precondition check ("config/ or src/ has uncommitted changes"), not by
me and not by any gate. A build without them appeared byte-identical, but that was an INCREMENTAL
build reusing objects — the same trap that produced a false all-clear earlier today — so it is not
evidence either way. Committing what R22 actually verified removes the ambiguity rather than
reasoning about it.

Lesson, same shape as R32 pointed at commit hygiene: a scoped `git add` is an assertion about the
change set's boundary, and nothing checks it. The tool preconditions are the only thing standing
between a partial commit and a broken HEAD.
2026-07-27 19:46:04 -06:00
Drew T e47d68c075 feat(phase-29): func_80135EB0 family banked 137/137 via jtbl_family_bank (R22 140/140)
The largest single family on the census: 137 siblings x 289 ins. Per sibling — jtbl_carve -> make
extract -> remap_hseq + canon_sig_reconcile -> whole-binary gate, revert-on-fail. 137/137 BANKED,
0 failed. R22 clean-fleet 140 passed / 0 failed of 140; report fail-closed green (dedup 1886/0,
C1 coverage 239604/239604, 0 NON_MATCHING).

MEASURED: fn-count 318,171 -> 318,309 (+138); instr-weighted 83.4 -> 83.8% (+39,882 ins);
distinct-code 72.5 -> 73.2% (+131 unique fns).

TWO TOOL REFUSALS MADE THIS BANK POSSIBLE, and both deserve recording:
- family_sweep REFUSED the family (has_mid_jr): §53's carve law says a carve-less sweep there returns
  "a 0% that is a TOOL artifact, not a wall". Overriding with --allow-jr would have yielded 0/137 and
  plausibly filed the highest-value family on the board as a wall.
- jtbl_family_bank REFUSED a dirty tree: its per-sibling revert restores from HEAD, so the
  uncommitted 414-file decl axis would have been destroyed. H4 enforced in code.
This is the inverse of the session's earlier failures, which all came from tools that ANSWERED
instead of refusing.

SESSION-22 TOTAL: 5 exemplars + 543 members = 548 functions.
Fleet: 82.9 -> 83.8% instr, 71.5 -> 73.2% distinct-code.
2026-07-27 18:59:58 -06:00
Drew T e44bc787eb feat(phase-29): func_80135EB0 banked (289 ins) — 418-site pointer-shape decl axis, R22 140/140
The largest target on the T14 census: 138 members x 289 ins = 39,882 templated instructions at stake.
conform_decls --check showed 418 sites in 3 forms, pointer-type-only with NO narrowing warning and no
return-type change — the func_80179B74 shape that banked 137/137. Applied (418 sites / 414 files),
gated (jtbl carve succeeded first try), R22 clean-fleet 140 passed / 0 failed of 140.

Committed BEFORE the family bank because jtbl_family_bank refuses to run on a dirty tree — its
per-sibling revert restores from HEAD, so an uncommitted axis would be destroyed. The tool enforcing
H4 in code, correctly.

Also recorded: family_sweep REFUSED this family rather than returning 0/137 — func_80135EB0 is
has_mid_jr, and §53's carve law says a carve-less sweep there yields "a 0% that is a TOOL artifact,
not a wall". That refusal is the good version of today's pattern: every false wall untangled this
session (func_8016B6BC 0/137, the 4 fabricated CC1-FAILs, Phase-28's B2 0/8) came from a tool that
ANSWERED instead of refusing.
2026-07-27 18:37:55 -06:00
Drew T acc8d762a0 feat(phase-29): func_80179B74 family swept 137/137 (R22 140/140)
134/134 BANKED on the remainder after 3/3 on the probe — the FOURTH full-family sweep this session,
all four unblocked by the --like role guard, three of them 100%.
R22 clean-fleet: extract-all 139/139, check-all 140 passed / 0 failed.
2026-07-27 14:02:30 -06:00
Drew T 5ec8aa77af feat(phase-29): func_80179B74 family probe 3/3 banked 2026-07-27 13:39:41 -06:00
Drew T 2985f306d9 feat(phase-29): func_80179B74 banked — conform_decls cleared it as pointer-type-only (R22 140/140)
1,600 decl sites across 523 files, in THREE different forms (s16 *a0 / short * / short *p),
conformed to the byte-true 'void func_80179B74(u16 *p)'. conform_decls ALLOWED this one: the arity
is unchanged, so no 0-arg call site can break, and the return is unchanged, so §85's precondition
does not apply. Gated BYTE-IDENTICAL; R22 clean-fleet 140/140.

The tool has now refused one axis (func_8015B950, correctly — it would have broken 138 binaries)
and cleared another (this one, correctly). Both verdicts held under R22.
2026-07-27 12:47:44 -06:00
Drew T 6b9e2b7f33 feat(phase-29): func_8016AE5C family swept 136/137 (R22 140/140)
133/134 BANKED on the remainder after 3/3 on the probe. ONE sibling refused (ov_SC03_108,
gate-fail) and is left as a stub rather than forced — a 136/137 recorded honestly beats a 137/137
that needed a shortcut. Third full-family sweep this session, all three unblocked by the --like
role guard.

R22 clean-fleet: extract-all 139/139, check-all 140 passed / 0 failed.
2026-07-27 12:45:20 -06:00
Drew T 7804d75230 feat(phase-29): func_8016AE5C family probe 3/3 banked 2026-07-27 12:21:57 -06:00
Drew T d4c4a4d563 feat(phase-29): func_8015B950 family swept 137/137 (R22 140/140)
134/134 BANKED on the remainder after 3/3 on the probe — the second clean full-family sweep this
session, both unblocked by the --like role guard. func_8015B950 is stubbed in NO overlay.
R22 clean-fleet: extract-all 139/139, check-all 140 passed / 0 failed.

At 271 ins x 137 members this is the session's largest single family by instruction weight.
2026-07-27 12:21:07 -06:00
Drew T 8b52bdb30b feat(phase-29): func_8015B950 family probe 3/3 banked (each whole-binary gated) 2026-07-27 11:57:26 -06:00
Drew T f459f53083 feat(phase-29): func_8015B950 banked — ONE cast unlocked the 925-site axis that broke 138 binaries
The same axis that broke 138 of 140 binaries an hour ago now lands clean, because conform_decls'
NEW arity guard located the actual obstruction instead of leaving me to absorb it by hand.

THE OBSTRUCTION WAS ONE LINE. Conforming `extern s32 func_8015B950(void)` -> `(s32 arg0)` turns
every 0-arg CALL SITE into `too few arguments`. My hand attempt assumed those were spread across the
926 TUs and would need 926 casts (the func_8012AAAC precedent, where it really was 137 separate
sites). They are not: there is exactly ONE call, in `src/shared/engine_core.h`'s
`DEFINE_func_8015BEE4()` macro body — expanded into all 926 TUs by the preprocessor.

func_8015BEE4 is a THUNK: `return func_8015B950();` with $a0 passing straight through from its own
caller. So the 0-arg call shape is byte-CORRECT and must be preserved, not fixed —
`return ((s32 (*)(void))func_8015B950)();` keeps it exactly (§17a-1; gcc folds the cast of a known
symbol to a direct jal, and the s32 return is unchanged so the thunk's value still flows).

Sequence: 1 cast -> conform_decls --apply (925 sites, R32 completion assertion: 0 remaining) ->
gate BANKED byte-identical -> R22 clean-fleet extract-all 139/139, check-all 140 passed / 0 failed.
The draft's 2 callee-decl conflicts (func_801725A4, func_80147078) dissolved with the axis.

Worth 37,398 templatable ins; the ×137 family sweep is next.
2026-07-27 11:56:23 -06:00
Drew T 7c1640888f feat(phase-29): func_8016AE5C banked + tools/conform_decls.py; a 138-binary break R22 caught
BANKED: func_8016AE5C (85 ins ×138). R22 clean-fleet 140/140.

⚠️ I BROKE 138 OF 140 BINARIES AND R22 CAUGHT IT — the per-binary gate could not.
Conforming func_8015B950's decl from `(void)` to its byte-true `(s32 arg0)` across 926 sites gated
BYTE-IDENTICAL on ov_SC01_077 and broke 138 other binaries with Error 33. §63/§85 exactly: a T2
write set is provable only by R22, and the binary the gate authorises is not the binary that breaks.
MECHANISM: conforming a decl to a signature that TAKES parameters makes every existing 0-ARG CALL
SITE a hard `too few arguments` error once a prototype is in scope. Not a declaration-only change.

PROCESS NOTE (mine): a first R22 reported 138 failures, an individual rebuild of a "failing" binary
said BYTE-IDENTICAL, and I nearly filed it as a flake. The second clean R22 reproduced it exactly —
the individual build passed only by reusing objects the clean run rebuilds. An incremental pass does
not refute a clean-tree failure; that is R22's whole premise, pointed at me. Reverted to a known-good
baseline (a stray jr_isolate region file was also in the tree) and redid the one good bank cleanly.

NEW tools/conform_decls.py — because applying this axis by hand three times in one session is how a
half-axis happens. Derives the byte-true signature from the DRAFT's definition (§58b), rewrites EVERY
site, asserts completion (R32). Encodes both preconditions: the §85 return axis (refuse if any caller
consumes the return) and a NEW arity precondition (refuse if 0-arg call sites exist, naming the cost).

The guard immediately gave a better diagnosis than my hand-fix had: func_8015B950's 0-arg call is in
ONE place — src/shared/engine_core.h, a DEFINE macro body — expanded into all 926 TUs. That fix is a
SINGLE cast, not 926 edits. Named as the next step rather than run on tired context.

Also lands cookbook §91 (the --like role trap) from the previous step.
2026-07-27 11:42:32 -06:00