Commit Graph

1052 Commits

Author SHA1 Message Date
Drew T 890dd08e6f docs(phase-29): §88 — the behemoth close-out laws (cross_jump/call, slti literal-position + its equality false-positive, banking order, the reloc gate) 2026-07-26 22:52:22 -06:00
Drew T d2a79deff2 feat(phase-29): ALL THREE BEHEMOTHS BANKED — func_80183814 (5,122), func_8017DC1C (1,518), func_8017D2DC (1,586)
Zero functions >1000 ins remain unmatched anywhere in the fleet.

func_80183814 (5,122 ins — the LARGEST function in the game) — round 2 closed it: length 5127->5122
exact, structural residual 36->0, register-sensitive 1201->0, frame -256 -> -0xF8 exact, saves
10 -> .mask 0x807f0000 exact. Verified independently (R14): match_one MATCH (5122 ins).
  ROUND 1's DIAGNOSIS WAS WRONG and the agent refuted it properly: the +5 length was a SYMPTOM, not
  the lever, and the §83d max_reg/cse.c:8340 story does not hold — a 15-line reproducer reproduced the
  case-0/3 CSE exactly (so it cannot be max_reg-gated), max_qty only gates extension ACROSS blocks,
  and the target leaves $s7/$fp unused (no pressure story). Confirmed from a second direction: C01 has
  the identical two groups over the identical symbols with ZERO residual, because a `break` puts a
  CODE_LABEL between them. The two biggest levers were pure DECLARATION SCOPE (§45/§76), not pins.
func_8017DC1C (1,518) — MATCH first round, pin-free, zero __asm__ dials. NOT a jr fn (0 mid-fn jr).
func_8017D2DC (1,586) — MATCH first round (banked in the previous commit).

BANKING ORDER MATTERS — a new failure mode found and worked around: banking func_8017DC1C BEFORE the
carve chain broke the build. Its draft establishes the canon for 39 previously-undeclared externs;
jr_isolate_all's re-partition (overlay_src_split) then DROPPED ALL 39 across the new split boundary
(`D_801C1EB0 undeclared`), leaving them in NEITHER file. The §77 preamble-drop class, in a third tool.
FIX = ordering, not patching: run the §81 carve chain FIRST on a clean tree (gated BYTE-IDENTICAL),
then bank. Reverted, re-sequenced, both banked clean.

R22 clean-fleet 140/140 BYTE-IDENTICAL; tools-health OK; dedup 1886/0; 0 NON_MATCHING (G4).
Fleet: instr 81.6 -> 81.7% · distinct-code 69.1 -> 69.3% · fn-count 89.52%.
2026-07-26 22:16:48 -06:00
Drew T 09b1993059 feat(phase-29): T0.7 sweep (104 members) + BEHEMOTH func_8017D2DC banked (1,586 ins)
T0.7 — the §86 one-member probe applied to the remaining FREE families: 9 LIVE / 6 DEAD / 5 unstaged.
The three highest-value families by raw size (18,084 / 11,234 / 10,880 ins) all probed DEAD — the
probe skipped them instead of burning ~400 gate cycles rediscovering it. Swept the 9 live: 104 banked,
8 of 9 families fully cleared (func_8017BEF8 has 8 stragglers).

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

R22 clean-fleet 140/140 BYTE-IDENTICAL; tools-health OK; dedup 1886/0; 0 NON_MATCHING (G4).
Fleet: instr 81.5 -> 81.6% · distinct-code 69.0 -> 69.1% · fn-count 89.49 -> 89.52%.
2026-07-26 22:02:37 -06:00
Drew T 1eb36504f6 docs(phase-29): §87 — match_one never LINKS, so the 315 'integration' entries are not bankable
T0.6 measured: the autopsy's integration bucket (315 match_one MATCHes, 'blocked only on plumbing')
banked 0/27 through the full gate_stage ladder. Two causes, neither plumbing:
 (1) UNDEFINED DATA SYMBOLS — the gate fails at LINK on symbols defined in NO overlay's symbol file.
     match_one compiles one TU and never links, so an extern resolving nowhere is structurally
     invisible to it. (Refuted the obvious alternative: the drafts WERE authored for the right binary.)
 (2) STALE DRAFTS — 'redefinition of struct S80172C50': the struct was since lifted into
     engine_types.h, so the draft's own copy collides. A stored draft is scored against TODAY's tree.

=> FOUR match_one blindness classes now catalogued: §81 jump tables, §84 masked %lo, §87 link, §87
staleness. A match_one MATCH is 'this TU compiles to the right bytes with relocations masked' —
nothing about linking, nothing about the current tree. A stored MATCH is a CLAIM WITH A TIMESTAMP.

Consequence: with §83's 44%-misfiled finding, docs/backlog.md's headline count is NOT a work queue.
Re-gate a sample before planning against any stored-draft pool. Cheap discriminator added (grep each
D_ symbol against the binary's symbol files; any UNRESOLVABLE will fail at link regardless of ladder).

MY RECOMMENDATION WAS WRONG: I ranked this pool first on 'highest certainty of any pool we have'.
The certainty was an artifact of a tool that cannot see link errors. 0 banked, 0 tokens, tree clean.
2026-07-26 20:48:54 -06:00
Drew T 454a0d2a02 docs(phase-29): SESSION-20 closing checkpoint — ~1,070 members from five tooling root causes; 81.5/69.0/89.49 2026-07-26 20:24:01 -06:00
Drew T c2566010f2 feat(phase-29): --allow-pins sweep — 268 banked; pin templatability is PER-FAMILY (cookbook §86)
The §42e pin guard refuses any family whose exemplar carries `register __asm__` pins: 680 of the top
8 FREE families' 1,083 members (63%) were skipped BEFORE any gate ran. Re-run with --allow-pins,
letting the byte-gate arbitrate (G3/P9): 268 banked, and ZERO cc1 crashes across hundreds of pinned
compiles — confirming the SIGABRT the guard was written against was Phase 27's extract_unit
macro-drop, NOT a compiler limit. The guard is protecting against a bug that no longer exists.

THE LAW (§86): templatability is a PER-FAMILY property, not a per-member rate.
  func_801749C8  137/137 = 100%      func_80133AB0    4/136
  func_8014C6F4  137/137 = 100%      func_8014CF04    0/137
                                     func_80143D28    0/136
Two families at 100%, three at ~1%. MY REPORTED "37%" WAS AN ARTEFACT: a 19-member sample that
straddled families reported their AVERAGE and hid the bimodality. Sample PER-FAMILY, never per-pool.

=> PROCEDURE, now the default: probe ONE member per pinned family; bank -> sweep the family; fail ->
skip entirely. The blanket sweep spent ~412 futile gate cycles (60% of the run) on three families
that were never going to bank; the 1-member probe reduces that to 5 probes + 2 sweeps.

Left explicitly UNDIAGNOSED (do not guess): why two families template and three do not. Likely axis
is caller-saved pins spanning a `jal` (§74's corrupting form) vs pins fixing only a local allocno.
Diagnose BEFORE extending --allow-pins fleet-wide — the byte-gate makes a wrong guess free, but a
wrong PROCEDURE costs a sweep.

R22 clean-fleet 140/140 BYTE-IDENTICAL; tools-health OK; dedup 1886/0; 0 NON_MATCHING (G4).
Fleet: instr 81.3 -> 81.5% · distinct-code 69.0% · fn-count 89.41 -> 89.49%.
2026-07-26 20:23:28 -06:00
Drew T 52e6522f1b feat(phase-29): T0.5 — FREE-subset sweep, 3 families fully banked (389 members, +37,713 ins)
Re-derived the T0.1 decomposition post-harvest (it was stale by 395 banked members):
  zero-crack pool 76 fams / 347,892 ins  ->  73 fams / 290,850 ins   (the harvest came out of it)
  FREE (sweepable, non-jr, non-O0)       ->  58 fams / 167,368 ins

Swept the top FREE families through the gate_stage ladder (sample 8/8 first, then the rest):
389 banked; func_801463A0 / func_8017B490 / func_80156670 now stubbed in ZERO overlays.
R22 clean-fleet 140/140 BYTE-IDENTICAL; tools-health OK; dedup 1886/0; 0 NON_MATCHING (G4).
Fleet: instr 81.0 -> 81.3% (10,645,711 -> 10,683,424) · distinct-code 68.8 -> 69.0% ·
fn-count 89.30 -> 89.41%.

THE BLOCKER HAS MOVED — it is now OUR OWN PIN GUARD, not gcc and not declarations. Of the 1,083
candidate members in the top 8 FREE families, 680 (63%) were refused by the §42e pinned-exemplar
guard BEFORE any gate ran; only 403 reached staging. Two pieces of evidence say the guard may now be
over-conservative: SESSION-19 banked func_8017A4AC x134 WITH pins once the byte-gate arbitrated, and
Phase 27 dissolved the cc1 SIGABRT that motivated it (it was the extract_unit macro-drop, not a
compiler limit). Next probe: --allow-pins on a sample of 8, byte-gated.

MY OWN SCRIPT BUG, fixed + negative-controlled: the sweep loop globbed `.run/sweep/*/`, which also
matches gate_stage's INTERMEDIATE ladder dirs (-cn, -cn-cast, -cn-cast-rc, -s2in, -s2in-uni). Those
were called as if they were binaries -> 24 phantom "PARTIAL 0/1" lines inflating notbanked to 56 when
the true failure count was ZERO (stub counts 0/0/0 are the ground truth). Fixed by requiring
config/splat.<ov>.yaml to exist; negative control confirms phantoms are skipped and real binaries kept.
2026-07-26 18:32:09 -06:00
Drew T 57e63730dc docs(phase-29): SESSION-20 final checkpoint — 395 members harvested from two tooling bugs, ~56,200 ins, zero tokens 2026-07-26 16:49:29 -06:00
Drew T 015ebff536 feat(phase-29): §84 family fully harvested — 123/123 members, 0 failed (+29,280 ins, +27,840 distinct)
The derived-offset recompute swept the whole func_8013D53C family: 119 banked / 0 failed on top of
the 4 earlier; func_8013D53C is now stubbed in ZERO overlays. R22 clean-fleet 140/140 BYTE-IDENTICAL;
tools-health OK; dedup 1886/0; 0 NON_MATCHING (G4).

RECIPE (and it is NOT the return-axis recipe — sampling caught this):
  §84 derived-offset -> per-member literal recompute AND the gate_stage ladder.
  With the recompute alone the sample was 0/8; through the ladder it was 3/3, then 119/119.
  Had I reused the return-axis recipe (plain harvest_verify, which banked 272/272 there) I would
  have swept 123 members to zero banks and mis-concluded the fix was wrong. Probe-before-scale.

METRIC FINDING worth carrying: this harvest moved instr +29,280 AND distinct-code +27,840, while the
return-axis harvest moved instr +26,928 and distinct-code +0. §84-class members are byte-VARIANTS so
each is a new unique function; propagation-class members were already counted once via their shared
exemplar. => §84-class work moves the RE-COMPLETENESS number; propagation moves only the DISPLAY one.

Session fleet: 80.6 -> 81.0% instr · 68.2 -> 68.8% distinct-code · 89.18 -> 89.30% fn-count.
2026-07-26 16:48:56 -06:00
Drew T 9d9cd58028 feat(phase-29): T0.4 harvest — 272 return-axis members banked (+26,928 ins) + the §84 recompute in family_remap
THE §85 WIDEN PAID OFF AS PREDICTED. It is a ONE-TIME fleet edit, so once committed the
`conflicting types` blocker was gone for EVERY member of both families at once:
  - sample 8 first (probe-before-scale): 8/8 banked with PLAIN harvest_verify, no ladder needed
  - full sweep: 264 banked / 0 failed across 132 overlays; 10 skipped as not-stub
  - total 272 members ~= 27k ins, ZERO agent tokens
R22 clean-fleet 140/140 BYTE-IDENTICAL; dedup 1886/0; 0 NON_MATCHING (G4).
Fleet: instr 80.6 -> 80.8% (10,589,503 -> 10,616,431, +26,928) · fn-count 89.19 -> 89.26%.
distinct-code UNCHANGED at 68.3% — propagation moves the DISPLAY metric, not the RE-completeness
one (the SESSION-19 split, reconfirmed).

§84 RECOMPUTE now implemented in tools/family_remap.py (fix_derived_offsets), wired into all three
apply_remap call sites as a PRE-pass on the exemplar body (the literal is ambiguous as a substitution
token, so it cannot be a table entry):
    correct_literal = mapped(aliased_sym) - mapped(base_sym)
Verified by negative control: the hand-solved case recomputes 0x20 -> 0x18 exactly, and a site whose
target endpoint is NOT a mapped symbol is left byte-for-byte alone AND REPORTED in info
["derived_offsets"] (R32 — a silent skip is a defect, and a silent skip is how this bug survived).
2026-07-26 15:36:06 -06:00
Drew T c6b17f3056 docs(phase-29): SESSION-20 checkpoint — 4 causes diagnosed, 3 banked, the unlock identified but not yet harvested 2026-07-26 15:22:57 -06:00
Drew T 772b5c4e02 feat(phase-29): the RETURN-axis fleet widen — 2 more families unlocked (cookbook §85); 140/140
Continues the "see why and try again" chain. Diagnosed all 4 T0.2 failures to 4 DISTINCT causes:
  func_8013D53C  240x123  §84 derived-offset remap bug        -> BANKED (previous commit)
  func_8012CC88  105x137  §73/§30#2 RETURN-axis conflict      -> BANKED here
  func_8014D12C   93x137  §73/§30#2 RETURN-axis conflict      -> BANKED here
  func_80144090  154x136  LENGTH-DRIFT (+13 B, ~3 ins long)   -> genuine codegen, real work

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

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

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

Fleet: instr 80.6% (10,589,503) · distinct-code 68.3% (3,846,656) · fn-count 89.19%.
2026-07-26 15:22:21 -06:00
Drew T b6bb04ecff feat(phase-29): CRACK THE PLUMBING FAILURE — the derived-offset remap bug (cookbook §84); func_8013D53C banked
Drew: "if it fails, see why and try again with new knowledge." It failed twice, then banked.

ROOT CAUSE, byte-proven: a family_remap member reached match_one MATCH (240 ins) and failed the
whole-binary gate by ONE BYTE. The exemplar carries a deliberate matching idiom — reach a symbol via
a DIFFERENT symbol plus a literal offset, so gcc cannot CSE the two %hi/%lo pairs:
    (*(S9*)&D_801DAA78) = *(S9*)(&D_801DA998 + 0x20);  /* same addr as &D_801DA9B8 */
family_remap substitutes the symbol NAMES correctly and leaves the literal 0x20 — but 0x20 is not a
constant of the algorithm, it is the DISTANCE BETWEEN TWO PER-OVERLAY SYMBOLS:
    exemplar 0x801DA998 + 0x20 = 0x801DA9B8  OK
    member   0x801A5778 + 0x20 = 0x801A5798  WRONG (real symbol 0x801A5790)
    member   0x801A5778 + 0x18 = 0x801A5790  correct
match_one MASKS HI16/LO16 so it is STRUCTURALLY BLIND to this — the §81 blindness in its DATA form.

TWO FIXES WERE EACH INDIVIDUALLY INSUFFICIENT: the byte fix alone re-failed as PLUMBING; the ladder
alone re-failed as DIFF. Together -> BANKED, R22 clean-fleet 140/140.

TWO LADDER CORRECTIONS (my own T0.2 error): bare harvest_verify is the LAST RUNG, not the ladder —
gate_stage runs canon_resident_calls -> cast_call_sites -> reconcile_tu -> ARITY -> sig_unify ->
harvest_verify, so T0.2's "8/8 PLUMBING" measured the UN-RECOVERED rate. And reconcile_decls.py is
RETIRED (R33, superseded by reconcile_tu): asking "what does the FLEET call this symbol?" is wrong by
construction in a loosely-typed engine (548 of its answers conflicted, rewriting 60 of 196 drafts) —
so Drew's suggested tool would have made it worse.

SCOPE, MEASURED (not over-generalised, §80): the idiom appears at only 5 sites corpus-wide — BUT one
gates a 123-member family (133 staged drafts all carry the un-recomputed +0x20 with different
per-overlay bases), so the mechanical fix is worth ~240 ins x 123 ~= 29,520 ins. It does NOT explain
the pool generally: func_80144090 / func_8012CC88 / func_8014D12C have ZERO derived-offset sites and
fail for a different, still-undiagnosed cause.

THE FIX IS MECHANICAL: correct_literal = mapped(aliased_sym) - mapped(base_sym). The remap already
holds both mappings, and the exemplar's own comment names the aliased symbol.

Also observed: the ARITY pre-pass left 40 TUs of caller-decl edits after a 0-bank run (same hygiene
bug as --normalize-self-decls, twice in one session) — reverted, both binaries byte-identical.
2026-07-26 13:47:06 -06:00
Drew T 1d44ce25f3 docs(phase-29): CORRECTION — the T0.1 "zero-crack pool" is NOT banked (4 of 1,073 members = 0.4%)
Drew asked whether the 347,892-ins pool was banked. It was not: 4 members (func_801463A0 x2,
func_8017B490 x2) = +396 instr-weighted / +194 distinct-code, ~1 part in 900 of the prediction.

FRAMING ERROR OWNED: I labelled the pool "FREE" and "the actionable shortcut". The h_seq
classification establishes "no DRAFTING needed" (exemplar matched, members structurally identical);
it does NOT establish "no WORK needed", which is how "FREE" reads. The probe located the work:
- 2 of the 8 top families (270 members) refused BEFORE any gate by the §42e pin guard => "FREE" did
  not even imply sweepable
- of the members that reached the gate, 67% hit declaration plumbing, 0% hit compiler walls
- both plumbing keys tried FAILED (--fix-def-sig regressed; --normalize-self-decls 0/123)

Pool status: real, structurally confirmed, not gcc-blocked, still LOCKED. To bank it: find the
working key (reconcile_decls.py — the DATA-symbol analog, and one failure text WAS a DATA symbol —
or canon_sig_reconcile v3.2, both untried), then re-sweep (mechanical, zero-token), and handle the
pin-refused families via --allow-pins.

Recorded rather than quietly superseded because this pool has been mis-called in BOTH directions
(P26 dead-off-a-broken-tool, P28 same family 89%). A prediction stated as a bank is how that happens.
2026-07-26 13:29:45 -06:00
Drew T adafeb13d6 feat(phase-29): T0.3b autopsy — 44% of the "near-miss backlog" are not near-misses; 315 are plumbing-blocked MATCHes
Recomputed every backlog residual from the bytes (1,699 rows, -j 12, zero agent tokens) through the
validated match_one path, deriving asm-subdir + -O0 from corpus.py. R34 cross-check PASSED (closeness
agreed with masked_diff.structured_diff on all 1,610 built rows, 0 classifier errors); 89 nobuild rows
REPORTED not dropped (R32).

BUCKETS: redraft 707 | structural 528 | integration 315 | permuter 57 | unknown 3.

1. HONESTY CORRECTION: 707 of 1,610 (44%) are class SIZE-MISMATCH — the stored best-draft is a
   PARTIAL, an incomplete attempt logged with a closeness score (the func_80183814 666-of-5,122
   shape). docs/backlog.md has been overstating readiness by ~44%. These route to a FRESH CRACK,
   not to a wall and not to the permuter.
2. ACTIONABLE: 315 entries are match_one MATCH *right now*, blocked only on the reconcile ladder —
   recomputing beat trusting the stored label because the tree moved since they were logged.
   ~108,959 gain-ins; top func_80174CB0 (16,482), func_801463A0 (13,534). §52b still applies: ~half
   of close=0 drafts fail the whole-binary gate, so these are CANDIDATES not banks.
3. The permuter bucket is 57/1,610 = 3.5% (Task-13B measured 7.7% and called targeting the problem).
   Extending the mutation set is CONFIRMED not the big lever — small, real, now bounded.
4. R34 again: 3 of 4 comparable labels DISAGREE with measurement — func_80140D68 / func_8012A328 /
   func_801549F8 recorded "schedule" but measure ADDRESSING -> cse. The grinder was aimed wrong.

CONVERGENCE: T0.2 (8/8 failures PLUMBING, 0 walls) and T0.3b (315 integration) independently point at
the SAME lever — the declaration/integration reconcile ladder, worth the 224,410-ins FREE pool AND
~108,959 backlog gain-ins. Two keys eliminated today; untried: canon_sig_reconcile v3.2 and
reconcile_decls.py (the DATA-symbol analog — one T0.2 failure text was a DATA symbol).
2026-07-26 13:25:29 -06:00
Drew T bce8cf3248 feat(phase-29): T0.2b + T0.3 — two levers eliminated for ~0 tokens; the backlog is current but 92% unclassified
T0.2b --normalize-self-decls: CLEAN NEGATIVE 0/123 on func_8013D53C (the family whose failure text
matches the flag's own documented fix). The FREE pool's blocker is a DIFFERENT declaration class than
either tested flag — --fix-def-sig REGRESSED it, --normalize-self-decls no-ops on it. Untested next
candidates: canon_sig_reconcile v3.2 and reconcile_decls (one failure text is a DATA symbol,
"conflicting types for D_800A651C", which neither tested flag targets).

TOOL HYGIENE DEFECT: the flag's transform is byte-neutral by construction, so the non-neutral
backstop never fires and it LEFT ALL 123 EDITS IN PLACE after banking nothing (123 files / 246+ /
246-). Byte-safe but a "git add -A" trap. Reverted; spot-rebuilt ov_SC01_000 + ov_SC07_010
BYTE-IDENTICAL. Candidate fix: on a 0-bank group restore the snapshot regardless of neutrality
(§61's law applied to the success path — "neutral" is not "wanted").

T0.3 triage: 1,622 live entries, P9 filter finds 0 stale (backlog.py's drop-now-matched works).
LEDGER DEFECT (R32): the addr field is null for 1,501/1,622 (93%) — the address survives only inside
the name field, so an addr-keyed consumer silently sees 7%. My own first pass fell into it (read 121,
reported off a 7% sample); name-derivation resolves 100%. Fix flagged, not applied mid-session.
Closeness: 333 at 0, 184 at 1-4, 589 at 5-20. 1,486/1,622 (92%) UNCLASSIFIED — matching
residual_class.py's own docstring. Highest-value next: run residual_class over the unlabelled set so
the close band routes to a lever instead of grinding undirected. Zero tokens.
2026-07-26 13:16:01 -06:00
Drew T 6676ed8406 chore(phase-29): preserve the func_80183814 round-1 deliverables (R20)
367k agent tokens of recon: the 99.3%-structural draft, the 15-row do-not-re-buy table WITH BASES
(§80), and the 6-file harness that regenerates the draft identically (edit the 72-ins template once
-> re-propagates to all 35 sites). .run/giants/*.{c,md,py} is the curated allowlist; round 2 starts
from these rather than re-deriving.
2026-07-26 13:12:28 -06:00
Drew T d3e6d6a702 feat(phase-29): T0.2 gate probe — the FREE pool is PLUMBING-blocked, not wall-blocked (4 banked)
MEASURED, not projected (R14): 12 gate attempts across ov_SC01_000 + ov_SC01_001, one draft per
build for clean attribution.

- 4 BANKED (func_8017B490 x2, func_801463A0 x2); 8 failed; **0 DIFF — zero compiler walls**
- all 8 failures are the §75a/def-side declaration class: `conflicting types for 'D_800A651C'`
  (DATA sym) and `conflicting types for 'func_8013D53C'` (the member's OWN def-side decl)
- => raw conversion 33%, but the ceiling is NOT 33%: the blocker is declaration plumbing, which
  this project has named tools for. Plumbing recovery has out-earned drafting in every phase that
  measured both (P19 fix_arity_callers, P28 dedup_extend 6,174 members / 95.6% from one new mode)

TWO CORRECTIONS TO MY OWN T0.1 POOL MATH, both downward:
- 2 of the 8 top "FREE" families were refused outright by the §42e pinned-exemplar guard (the 270
  skips) => "FREE" does NOT imply sweepable; pins are a third blocker the decomposition missed.
  Recoverable (--allow-pins; SESSION-19 banked pinned families x134), but I mis-labelled them
- n_templatable counts the matched exemplar, so every T0.1 family figure is ~1 member (~0.7%) high

NEGATIVE RESULT (§80, scoped to this base): --fix-def-sig REGRESSES this class — 0 banked and 2
PLUMBING became CC1-FAIL despite targeting the same error text. Do not re-buy without re-testing.

NAMED NEXT LEVER: family_sweep --normalize-self-decls, whose help text cites fixing "the conflicting
types for func_X that blocked 133/137 of func_801670E4" — exactly this failure. Gate-phase transform,
so it cannot run under --stage-only, and --limit caps FAMILIES not MEMBERS => needs a full ~123-member
family run. Highest-value outstanding probe, zero agent tokens.

R22 clean-fleet 140/140 BYTE-IDENTICAL; tools-health/dedup 1886/0; 0 NON_MATCHING (G4).
Fleet: instr 80.6% (10,589,065) · distinct-code 68.3% (3,846,416) · fn-count 89.19%.
2026-07-26 13:12:09 -06:00
Drew T 1fe4850136 feat(phase-29): T1.1 func_80183814 round 1 — 99.3% structural, named lever; cookbook §83
- VERIFIED INDEPENDENTLY (R14): match_one reproduces DIFF 5127 vs 5122, LENGTH-DRIFT/+5. Agent did
  not over-claim; tree untouched. Difflib-aligned truth: 36/5122 structural (99.3%), 17/21 cases
  EXACT, args+locals BYTE-EXACT at 216B
- §83a: on a LENGTH-DRIFT class match_one's mismatch count is NOT a progress signal — 4,622 and 36
  describe the same draft (index-wise comparison smears every index after the delta)
- §83b THE LEVER: the handoff's '35x repeated template' (which I passed on flagged UNVERIFIED) is
  TRUE and was the whole game — 2,625 of 5,122 ins (51%) from ONE parameterised 72-ins body. Three
  sub-levers: pointer walk (no strength-reduction under -G0), rand()%(u32) for divu, cast barrier vs combine
- §83c TRAP: the inherited 'dead local' pad[32] is gcc's OWN SPILL AREA — removing it made the locals
  area byte-exact. §83e: two 'pure allocation' residuals were a copy-pointer walk -> zero (§80 again)
- §83d THE STALL, cited: cse.c:8340 sizes the quantity table by WHOLE-FUNCTION pseudo count, so no
  per-case edit can move a function-global CSE fork. Next move = close the +5 (buys length parity AND
  perturbs max_reg), then re-run the do-not-re-buy table on the new base
- no pins in the deliverable (diagnostic-only, table row 15) — agent self-reported unprompted
- DECISION: round 2 QUEUED, not spent now — T0.2 (224,410-ins pool) outranks a ~0.04pp lever
2026-07-26 13:02:58 -06:00
Drew T 57ee715f3c feat(phase-29): T0.1 frontier survey re-run (138 ovs) — the family lever is ALIVE; a 224,410-ins zero-crack FREE pool
- verified the tool BEFORE trusting its scan (R35): load() correctly globs all 138 overlays, but the
  generated header hardcoded '134' -> fixed to derive from the same glob (a doc misreporting its own
  scope is the P28 img_path shape, one severity down)
- stale(07-23,134ov) -> fresh(07-26,138ov): fleet 88.5/79.0/68.4 -> 89.4/80.9/69.0%; families 2721 ->
  2688; substantial 558 -> 544; with-matched-sibling 74 -> 76. Structure STABLE => the P25 family
  reframe is NOT an artifact and P26's ~0% stays unsupported post-fix
- FINDING: 3,419 instances banked but only 85 distinct CLASSES fell -> recent yield was propagation,
  not new classes (SESSION-19's split, now fleet-wide)
- THE POOL: 76 zero-crack families (exemplar already matched) = 347,892 ins = 19.4% of remaining
  distinct code, decomposed by real blocker: FREE(PURE/non-jr/non-O0) 61 fams/224,410 ins = 12.5% of
  remaining; jr 13/57,311 (§81 chain); -O0 2/66,171 (known deferred build-infra, Arm A proved 9/9 bank)
- STILL A PREDICTION (R14/G3): T0.2 re-targeted from this data to measure the GATE conversion rate on
  8 members sampled across the FREE subset before any arithmetic scales
2026-07-26 12:46:34 -06:00
Drew T 4a8e8f7e36 docs(phase-29): the Drew-approved measured-order plan (T0 discovery-first) + the roadmap-to-100 gaps 2026-07-26 12:42:10 -06:00
Drew T 5873bd9cc8 docs(phase-29): record the absolute-include portability defect as a PhaseEnd carry item (Drew: handle later) 2026-07-26 12:19:08 -06:00
Drew T 661f5aa751 feat(phase-29): bank func_8017C730 x ov_SC03_013 (+1,061 ins) via the §81 carve chain
The SESSION-19 handoff's item 1, closed as specified — no drafting, no agent.

- §77 MINIMAL CLOSURE (519 lines, not the 2,993-line whole-file carry): 18 gte_* macros
  + 5 externs + the bandsetup static-inline helper -> match_one MATCH (1061 ins)
- §81 chain, each step byte-gated before the next: jr_isolate_all --only (2 fns/1 object)
  -> BYTE-IDENTICAL; jtbl_carve --func (single-table, 44-piece interleave) -> BYTE-IDENTICAL;
  harvest_verify --chunk 1 -> verified 1 / failed 0, 7042bc71 BYTE-IDENTICAL
- R22 clean-fleet 140/140 from a genuinely clean tree; tools-health OK; dedup 1886/0;
  0 NON_MATCHING (G4). FLEET distinct-code 3,845,161 -> 3,846,222 = 68.3% (+1,061, all
  distinct — a behemoth-class bank, not a propagation); instr-weighted 80.6%
- No §75a class spoke: the exemplar's ApplyMatrixSV(void*,void*,void*) canon fix was
  already carried, so the declarations were clean and it banked first try
- cookbook §77: the ladder CLOSED with all four rungs measured (-56 -> -34 ->
  MATCH-but-uncommittable -> MATCH+BANKED), plus a NEW subsection — the CANDIDATE gate
  and the REAL gate need DIFFERENT preambles (match_one compiles standalone, so a
  shared-type body's CC1-FAIL is a report about the PROBE, not the draft; the types
  header goes in a throwaway probe copy, never in the banked draft)
- FINDING, flagged not acted on (P5d): that shortcut already leaked an ABSOLUTE include
  path into 21 git-tracked files / 23 lines. All 21 verified semantically no-op (guarded
  engine_types.h via engine_core.h at line 2) => removal is byte-neutral, but cpp must
  still find the literal path, so those TUs cannot preprocess on any clone not at
  /home/musashi/bfm-decomp. Invisible to every byte-gate (R34's null-oracle shape, aimed
  at portability). Proposed as the next task.
2026-07-26 11:57:17 -06:00
Drew T 3b3728b19d docs(phase-29): checkpoint — an explicit START HERE NEXT SESSION block
Drew asked for the next-session recommendation to be logged. Added a ranked "START HERE" block
above the open-actions list:

1. func_8017C730 @ ov_SC03_013 FIRST (~30 min, +1,061 ins) -- the match ALREADY EXISTS; pure
   integration, no agent. Minimal preamble (bandsetup + 5 externs + 18 gte_* macros) then the §81
   carve chain. Explicitly warns NOT to re-carry the whole region file (standalone MATCH that
   fails the real gate -- the §77 corollary, measured).
2. THEN func_80183814 (5,122, the biggest left) with one Opus 5 agent @ xHigh, and an HONEST
   expectation reset: the family bonanza is over. All six behemoths banked this session were one
   renderer family with matched relatives bracketing them -- that is why 5 of 9 levers were
   readable rather than discoverable. func_80183814 has 0 fingerprint overlap and 37 callees; it
   is a different subsystem. Budget TWO passes (the func_8017BF14 shape, not the func_8017C954
   near-one-shot); a 99% round 1 is on-plan, not a stall.
3. Then func_8017D2DC (32 callees -- §71 IS usable) and func_8017DC1C (ZERO callees -- §71 CANNOT
   fire; use §79 DATA-symbol fingerprinting, shared syms only, and read a matched relative's
   fingerprint from its banked C since matched fns have no nonmatchings/*.s). A 0.00 from §71 on
   a leaf means "cannot answer", not "no relative" -- that error cost a whole agent brief today.

Also notes that behemoths were the ONLY thing that moved distinct-code this session
(+26,730 of +31,649), so they stay the lever if the queue holds.
2026-07-26 11:26:29 -06:00
Drew T cf570ec75c docs(phase-29): checkpoint — reflect §77's 5th variant now folded into the cookbook
The checkpoint said §77 'gains its 4th variant' and listed 4; the static-helper variant is the
5th and was only in the phase log until commit:1027 folded it into the cookbook proper. Both
mentions corrected so the checkpoint and the cookbook agree.
2026-07-26 11:19:29 -06:00
Drew T 2199c71192 docs(phase-29): §77 — add the 5th measured variant (static helper) + the minimal-closure corollary
Drew asked whether the cookbook was actually being updated per behemoth. It was (13 commits,
each paired with its bank), but the check found a REAL GAP: the last probe's two lessons went
into CURRENT_PHASE.md and a commit message and were never folded into §77 itself. So the
cookbook PREDICTED the static-helper variant (its closing line named it) without recording that
the prediction had since been CONFIRMED, and lacked the corollary entirely.

- VARIANT 5: a `static inline` helper, dropped by family_remap -> LENGTH-DRIFT/-56 with NO
  compile error at all. The nastiest variant precisely because it produces no diagnostic: the
  draft compiles clean and is simply ~56 instructions short, which reads as a codegen residual
  rather than a missing construct. Rule added: a NEGATIVE length drift with no compile error on a
  mechanically-remapped sibling means look for an uncarried static/inline helper BEFORE touching
  a lever.
- COROLLARY (measured, and it cost a bank): carry the MINIMAL TRANSITIVE CLOSURE of what the body
  references, not the whole file. Carrying the exemplar's entire 2,993-line region file produced
  a clean standalone match_one MATCH and then failed the whole-binary gate on PLUMBING --
  over-carrying trades a match_one failure for an in-TU collision. Measured ladder: -56 (nothing)
  -> -34 (helper + externs) -> MATCH-but-uncommittable (whole file); the minimal set is the only
  bankable point.
- Also recorded: the walk-back-to-previous-brace heuristic breaks on an ISOLATED REGION FILE
  (_jr_<addr>.c from jr_isolate_all), where the construct above the function IS the needed helper
  -- it returns a 1-line preamble. A preamble-carry tool needs a reference-closure rule, not a
  positional one.
2026-07-26 11:19:05 -06:00
Drew T 22798c2809 docs(phase-29): SESSION-19 FINAL CLOSING CHECKPOINT
Fresh session safe here. No background job running; tree clean; R22 clean-fleet 140/140 (12x);
tools-health OK; 0 NON_MATCHING; dedup 1886/0. HEAD at 38 commits this session.

FLEET 80.6% instr / distinct-code 3,845,161 = 68.2% / fn-count 89.18% (opened 80.0/67.7/89.02).
+31,649 distinct-code ins: 26,730 from SIX behemoths + 4,919 from the h_norm-remap pool. Every
propagation win contributed +0 to distinct-code -- the session's most actionable finding.

Records: the banked table (11 entries incl. six behemoths and the largest match in the project,
func_8017BF14 at 4,763 ins); ten cookbook entries §73-§82 all from measurement; the through-line
(almost every cap was our own tooling or my own use of it, including four of my own claims that
collapsed under checking); six ranked open actions with named causes; six method traps that
silently return 0.00 or a false MATCH; and the measured behemoth economics (two passes at
4,700+ ins, second cheaper; reading a matched relative beat the clever lever five times).
2026-07-25 23:28:37 -06:00
Drew T 9d04c0d6df docs(phase-29): func_8017C730 @ ov_SC03_013 — standalone MATCH, not banked (§77 4th variant)
- family_remap alone: -56 LENGTH-DRIFT. §77's own text predicted the cause verbatim (a "static"
  helper is a preamble construct the extractor does not carry): the exemplar uses
  "static inline void bandsetup(...)" -- the §82-oracle-1 inlined helper -- and none was carried.
  helper + its 5 externs: -56 -> -34. Whole 2,993-line region file as preamble: MATCH (1061 ins).
- BUT the full-file carry is wrong for BANKING (my error): right for a standalone match_one
  compile, collides wholesale in the real TU. Gate -> PLUMBING, reported as "conflicting types
  for memcpy" = the §58 red-herring; the real cause needs a hand-splice + real cc1 stderr.
- NAMED NEXT STEP: minimal preamble = bandsetup + its 5 externs + the 18 gte_* macros from that
  region file, then the §81 carve chain (this sibling is ALSO a jr function). Draft preserved at
  .run/giants/s19_func_8017C730_SC03_013_nearmiss.c
- §77 gains its 4th measured variant (static helper) + a NEW COROLLARY: the right carry is the
  MINIMAL CLOSURE of what the body references, not the whole file -- over-carrying trades a
  match_one failure for an in-TU collision. Also: s19_remap_tu.py's walk-back-to-previous-brace
  heuristic breaks on an isolated region file, where the preceding construct IS the needed helper.
2026-07-25 23:27:33 -06:00
Drew T 109ce6a2c3 feat(phase-29): BEHEMOTH #6 func_8017C730 BANKED (1,061 ins) + §82 two source-shape oracles
- CRACKED at xHigh and VERIFIED INDEPENDENTLY: match_one MATCH (1061 ins); agent re-matched 3x
  from clean runs (100% register-masked AND register-kept, all 10 regions, frame 0x270 exact).
  §81 carve chain clean first try: jr_isolate_all --only -> byte-identical cacaf7c2 -> jtbl_carve
  (43-piece set) -> byte-identical -> bank -> R22 clean-fleet 140/140, tools-health OK.
  instr 80.6%; distinct-code 3,844,100 -> 3,845,161.
- WHAT IT IS: the matched base func_8017CA80 + camera height-band cull + distance-driven CLUT
  fade. func_8004974C (TransposeMatrix) sits in a 36-ins prologue deriving a Y band; the
  part-level `lim >= g.otz` cull is GONE; flat arms gain an `sz < lim` near-plane cull. The
  base+one-extra-callee fingerprint predicted this exactly.
- §82 ORACLE 1 -- A DUPLICATED `addiu $aN,$sp,K` ACROSS A `jal` MEANS THE BLOCK WAS INLINED.
  `&X` on any non-first local always creates a pseudo and CSE always merges two of them
  (expr.c:6260 ADDR_EXPR -> force_operand(..., NULL); exception: virtual-stack-vars offset 0).
  So the same stack address re-materialised at two sites separated by a jal means CSE was
  PREVENTED from merging => not the same function body. 17 non-inline spellings failed; a
  `static inline` helper reproduced the prologue BYTE-FOR-BYTE first try. Reusable probe: scan
  the ~1,200 built objects for that signature in NON-INCLUDE_ASM functions.
- §82 ORACLE 2 -- SCALAR vs AGGREGATE DECIDES *WHEN* A STACK SLOT IS ALLOCATED: lazily at first
  `&` for a scalar, AT DECLARATION for an aggregate. Six GTE result words had to be six separate
  longs, not a struct, or they don't land after the inlined helper's temps and the frame isn't
  0x270. Second-order: it also flips MEM_IN_STRUCT_P (§30's /s) -- with one word a fixed-address
  scalar, ((PolyF3*)pkt)->rgbc stops aliasing it, so a store needed respelling to keep the
  target's nop. A scalar-vs-struct choice is simultaneously a frame-layout AND an aliasing
  decision.
- BANKING FOOTNOTE (§75a class A): first bank rejected `conflicting types for ApplyMatrixSV` --
  draft (MATRIX2*, SVECTOR2*, SVECTOR2*) vs the TU/fleet canon (void*, void*, void*), 2,286 of
  2,835 sites. Conforming the decl is byte-neutral and banked first try. On a jr function expect
  BOTH gates to speak: the carve chain answers the jump table, §75a answers the declarations.
- Also reproduced: §78 (reuse a busy variable), §80(i) (a lever went -8 -> exactly neutral as the
  base moved), §72 (a register pin made it worse).
- AGENT'S OWN CAVEAT, recorded not hidden: one zero-byte __asm__ keeps a vestigial `mnc = hmid`
  alive that flow.c would delete (costing 10 ins + the 0x130 spill slot). Emits nothing, compile
  is 1061 exact, but it is a documented stand-in -- 12 natural spellings measured, all DCE'd.
2026-07-25 23:24:11 -06:00
Drew T c41acdc473 docs(phase-29): record the func_8017C730 agent in the checkpoint
Opus 5 (xHigh) on func_8017C730 (1,061 ins, ov_SC03_010). Records the strongest starting signal
yet (shared-symbol set is a strict SUPERSET of the matched base func_8017CA80 -- all 6 symbols
plus exactly one extra callee func_8004974C, and 1,061 vs 952 ins => base + ~109 ins of one
feature), the five matched family exemplars bracketing it, and the §81 warning: it IS a jr
function, so match_one MATCH is not the end -- banking needs the carve chain, which is my step.
2026-07-25 22:00:52 -06:00
Drew T 0907a35cf5 docs(phase-29): reconcile checkpoint — 5 behemoths banked, +30,588 distinct-code
HEAD commit:1021, 33 commits, R22 140/140 (11x), tools-health OK. Fleet 80.6% instr;
distinct-code 3,844,100 = 68.2% (+30,588 this session: 25,669 from five behemoths + 4,919 from
the h_norm-remap pool; propagation contributed +0). func_8017C954 added to the banked table;
func_8017C730 recorded as the approved next target.
2026-07-25 21:58:28 -06:00
Drew T faf4547345 feat(phase-29): func_8017C954 BANKED — jr carve chain cleared; a shared type was PRESENT but INVISIBLE
- BANKED (1,194 ins, ×1 distinct-code). Chain cleared, each step byte-gated before the next was
  built on it: one-line fix to jr_isolate_all._engine_types() -> jr_isolate_all --only
  func_8017C954 (2 fns / 1 object, NOT the bare 47-fn / 21-object resegment) -> BYTE-IDENTICAL
  b7b0d4ae -> jtbl_carve --func func_8017C954 (44-piece carve set + interleave order) ->
  BYTE-IDENTICAL -> harvest_verify VERIFIED BYTE-IDENTICAL -> R22 clean-fleet 140/140,
  tools-health OK. instr 80.5 -> 80.6%; distinct-code 3,842,906 -> 3,844,100.
- THE DEFECT (tools/jr_isolate_all.py): _engine_types() harvested shared type names with four
  patterns -- `typedef ... X;`, `} X;`, forward-decl `struct X;`, fn-ptr typedef -- and a TAGGED
  DEFINITION WITH A BODY matches NONE of them. So `struct PW8017E6D8 { int w; }
  __attribute__((packed));` at engine_types.h:658 was present in the shared header yet invisible
  to the carried-type check, and `extern struct PW8017E6D8 D_801E1EC4;` could not be placed.
  MEASURED BLAST RADIUS: 77 such tags in engine_types.h were invisible. One added pattern fixes
  all 77.
- WHY THIS COST 20 MINUTES INSTEAD OF A MYSTERY BYTE-DIFF THREE PHASES LATER: the Phase-26 audit
  had already turned this predicate's SILENT DROP into a LOUD REFUSAL. The original bug dropped
  4,040 col-0 decls, 683 of them function PROTOTYPES -- and a dropped prototype is a SILENT
  BYTE-CHANGER (C89 implicit `int f()`; return type drives delay-slot fill in this codebase). The
  refusal named the exact symbols and the exact remedy. A loud "I cannot place this" is worth far
  more than a green build -- the audit paying for itself, live.
- §81: the 3-step jr-carve chain + why match_one CANNOT see the problem (it masks jal/HI16/LO16,
  so a jump-table function reports MATCH while the whole-binary gate reports DIFF, correctly).
  Detect with `grep -cE 'jr \$(v0|v1|a0|t[0-9])'` on the target .s + a jtbl_ in asm/<ov>/data/.
  ALWAYS use --only: bare would have resegmented 47 jr-functions across 21 objects.
2026-07-25 21:58:04 -06:00
Drew T fa51d30d3e feat(phase-29): func_8017C954 MATCHED (1,194 ins) — banking blocked on a NAMED 3-deep infra chain
- CRACKED by an Opus 5 agent @ xHigh and VERIFIED INDEPENDENTLY: match_one -> MATCH (1194 ins),
  100% every region, 1129 -> 1069 -> 37 -> 28 -> MATCH. It is the matched base func_8017CA80
  (952) + two deltas: a 14-ins grey-colour prologue from D_801DCCA0, and a FIFTH switch arm
  (case 2 / case 3 split, proved against the real jump table) emitting a POLY_FT4 plus a 7-word
  subtractive overlay.
- NOT BANKED. The whole-binary gate said DIFF and it is RIGHT: this is a jr (jump-table) function
  (jr $v0 at .s:409; table jtbl_801DB70C in asm/ov_SC06_029/data/tail21.data.s). Matching the C
  makes gcc emit that jtbl into .rodata while the raw copy stays in the data tail -> duplicate +
  wrong address. match_one masks jal/HI16/LO16 so it CANNOT see this -- the §53 carve law.
- THE CHAIN, each step failing LOUD with its own remedy (the tooling behaved well, R32/R35):
  (1) harvest_verify -> DIFF, not PLUMBING.
  (2) jtbl_carve --func func_8017C954 -> refuses: subseg ov_SC06_029_jr_8017AE2C would host
      NON-CONTIGUOUS .rodata carves (0xb3468, 0xb35b4); one object can't leave a gap for the
      unmatched jtbl between them. Remedy: isolate into its own code subseg first.
  (3) jr_isolate_all --dry-run (47 jr / 21 objects) -> REFUSES: 2 file-scope decls
      (extern struct PW8017E6D8 D_801E1EC4/EC8) could not be placed, and it will not emit a region
      that silently omits them ("a dropped prototype is a SILENT BYTE-CHANGER" -- C89 implicit
      int f(), and return type drives delay-slot fill here). NB struct PW8017E6D8 IS already in
      engine_types.h:658, so this looks like a placement-logic gap, not a missing type -- that is
      the precise next thing to check.
- => banking is a bounded BUILD-INFRA task (T2 config resegment => full R22), not more matching.
  Deliberately not started this deep into the session. Match + harness preserved and tracked.
- AGENT FINDINGS: §80(i) confirmed twice more (x_e1swap measured exactly neutral then later paid
  -2; the za lever measured worse and became necessary two levers on). NEW DIAGNOSTIC: when a
  residual is "a whole block of registers renamed by ONE SLOT", read the .greg `;; N conflicts:`
  AND `;; N preferences:` lines for the block's top allocno -- a missing hard-reg conflict plus a
  new copy preference is the signature of a one-slot slide, one dial away not forty bugs
  (c954_reg.py, the per-region scorer, is the reusable tool).
- HONEST CAVEAT (the agent's own): its lever 1 is a hand-placed byte-free __asm__ register-clobber
  dial, not a construct the original author would have typed; 14 natural spellings were tried and
  measured. Bytes unaffected, true source shape unfound; the report names the next probe.
2026-07-25 21:39:50 -06:00
Drew T 9b4b027f0e docs(phase-29): record the func_8017C954 agent + the fingerprinting method trap
Opus 5 (xHigh) on func_8017C954 (1,194 ins, ov_SC06_029); func_8017C730 queued next per Drew's
approval of successive single agents. Records why this target (1.00 SHARED-symbol fingerprint vs
the matched renderer base; 4 matched exemplars bracket it) and — importantly — the two ways I got
the fingerprint wrong before getting it right: per-overlay D_801????? names can never match across
overlays (compare only shared syms < 0x80128158), and a MATCHED function has no nonmatchings/*.s
so its fingerprint must be read from its banked C. Both mistakes silently return 0.00.
2026-07-25 20:40:57 -06:00
Drew T da5b32ac4c docs(phase-29): reconcile checkpoint — 4 behemoths banked, +29,394 distinct-code
HEAD commit:1017, 29 commits, R22 140/140 (10x), tools-health OK. Fleet 80.5% instr;
distinct-code 3,842,906 = 68.2% (+29,394 this session: 24,475 from four behemoths + 4,919 from
the h_norm-remap pool; propagation contributed +0). func_8017BF14 added to the banked table as
the largest single match in the project; its open action retired; 5 behemoths remain.
2026-07-25 20:29:34 -06:00
Drew T 8b828f1ea6 feat(phase-29): BEHEMOTH func_8017BF14 CLOSED — 45 -> 0 (4,763 ins, the largest match yet)
- 45 -> 37 -> 33 -> 21 -> 11 -> 3 -> 2 -> 0, reproduced 3x from independent work dirs. Verified
  independently before believing it (R14): match_one MATCH (4763 ins), then harvest_verify
  --binary ov_SC03_116 BYTE-IDENTICAL, then R22 clean-fleet 140 passed, 0 failed of 140.
  distinct-code 3,838,143 -> 3,842,906 = 68.1% -> 68.2%. instr 80.5%. Agent was interrupted by a
  weekly API limit and RESUMED FROM ITS TRANSCRIPT -- its round-2 harness survived, nothing was
  re-derived.
- §80 THE PROCESS CORRECTION, worth more than the match: A DO-NOT-RE-BUY ENTRY IS SCOPED TO ITS
  BASE, NOT TO THE FUNCTION. Three of round 1's ~40 measured negatives INVERTED on round 2's
  base -- the same edit (qsingle23) measured 1,040 mismatched on the 45-base and 11 on the
  21-base. Re-testing the round-1 negative list cost ~20s and produced THREE of the seven winning
  levers. Such a table records (edit, base) -> result, NOT edit -> useless; after any lever that
  moves the base materially, RE-RUN THE NEGATIVE LIST. This retroactively qualifies every
  do-not-re-buy table in the cookbook (§45, §60b, §75a, §76, §78, §79). Concrete: round 1 measured
  "removing the va->$t2 pin costs 4% elsewhere" => keep the pin; on a base with c0..c3 at function
  scope, removing those pins is worth 21->13. Same experiment, opposite conclusion.
- MY FLAGGED "#1 MOVE" LOST, and the failure is the finding. I briefed variable REUSE (§45-A /
  RC-14) as the top lever because it took func_8017F510 from 97->10. Swept in full here: EVERY
  merge lost, 43-3294 across 8 merges. Reason: the TRI and QUAD grants did not differ by RANK but
  by IDENTITY -- two independent allocno sets, and re-ranking inside one set cannot fix a two-set
  problem. Diagnose ranking-vs-identity before reaching for a merge. The actual fix (c0..c3 at
  FUNCTION scope, 33->21) was read off the two matched relatives (b5:310, b4:338) and confirmed
  against the target -- the 4th time today that reading a matched relative beat the clever lever.
- PIN'S HIDDEN COST, cited: combine_regs' hard-register branch (local-alloc.c:1795, reached from
  :1295 with already_dead==0) records the pinned reg in qty_phys_sugg UNCONDITIONALLY -- no death
  guard. A pin invites local-alloc to tie producer chains into it. New cure R7: a zero-byte
  __asm__ ref keeping the pinned value live past the temp so find_free_reg can't honour the
  suggestion -- closed the last 2 ins (c1->$a0 is uniquely load-bearing; every alternative pin
  lost 64 ins).
- §78's attribution primitive RUN and REPRODUCED: under -fno-schedule-insns, -fno-schedule-insns2
  and both, order unchanged => the rgb transposition was never a sched.c decision.
- Cold-start economics complete: round 1 = decode + exact length + exact frame + 99.06%; round 2 =
  the last 45, and cheaper. Budget TWO passes at this size. 5th source copy-paste artefact found.
2026-07-25 20:29:10 -06:00
Drew T bd768d8a4e docs(phase-29): record the func_8017BF14 round-2 agent in the checkpoint
Opus 5 (xHigh) closing the last 45/4763. Checkpoint records its deliverables, sandbox, the
round-1 residual map (a)/(b)/(c) with the measured do-not-re-buy constraints, the #1 move
(variable-REUSE sweep across c0..c3/a0v..a3v -- the one §76 lever class round 1 never swept,
and the exact merge that took func_8017F510 from 97 to 10), and the cheapest unrun probe (the
§76 attribution primitive on residual (c)).
2026-07-25 17:13:53 -06:00
Drew T f5f8dec5ee docs(phase-29): the cold-start experiment — func_8017BF14 to 45/4763; §79; full R22 discharged
- COLD-START RESULT (verified independently): 4763/4763 ins, 45 mismatched = 99.06% byte /
  99.94% structural, exact frame, exact opcode histogram. NOT a match; nothing banked (45 != 0,
  the byte-gate is the sole arbiter). The residual is 3 register-grant ties, 0 structural
  divergence. Named next move: variable REUSE across c0..c3/a0v..a3v, the one §76 lever class
  the pass never reached.
- MY BRIEF'S PREMISE WAS WRONG BY CONSTRUCTION -> §79. I chose this target partly because §71's
  callee-set fingerprint returned 0.00 against every matched giant = "a genuine cold start". But
  the function makes ZERO jal calls, so its callee fingerprint is EMPTY and §71 CANNOT FIRE:
  0.00 meant "cannot answer", not "no relative". Grepping the target's DATA symbol D_800A5E60
  found the matched func_8017BEBC at once -- func_8017BF14 is the 4-light-box member of the same
  renderer family whose 3-box sibling func_8017D960 was matched hours earlier. RULE: when §71
  returns an empty/zero-overlap callee set, fall back to DATA-symbol fingerprinting; an empty
  fingerprint must never become a cold-start brief.
- NEW LEVER (§79): THE FRAME LAYOUT IS A DECLARATION-ORDER ORACLE. gcc-2.7.2 assigns stack slots
  to spilled pseudos in pseudo-number order, and pseudo numbers follow first use ~ declaration
  order -- so the target's frame map reads back its source's declaration order. Moving ONE line
  took 73% -> 84% structural and brought all 127 slots into exact correspondence.
- §76 CONFIRMED AT SCALE: the entire -62 length residual was ONE allocno-class decision (c0..c3
  declared inside the cull blocks -> 1-death local allocnos -> global.c:668-671 removes those
  regs from the global pool -> r1lo spills), 52% -> 93%. An __asm__ ref-dial reached the same
  spill and scored WORSE -- declaration scope beat the ref dial again.
- PIN NUANCE: pins are safe on a 0-jal function (§74's hazard cannot arise), 4 pins took
  94% -> 99%; but §72 held -- pins 5 and 6 made it worse.
- EFFORT ANSWER, HONEST: xHigh from a genuine cold start on a 4,763-ins giant bought the decode,
  the exact length, the exact frame and 99.06%, and did NOT close. Budget a SECOND pass at this
  size: the first buys structure, the last ~1% is register grants.
- FULL R22 DISCHARGED: make clean + extract-all + check-all -> 140 passed, 0 failed of 140 (run
  after the agent finished, per the deferral recorded in the pool commit). tools-health OK.
2026-07-25 17:08:02 -06:00
Drew T a1f1a948af feat(phase-29): h_norm-remappable pool — +4,919 ins banked, no cracking, no agent
- BANKED (each whole-binary byte-gated; make check-all -> 140 passed, 0 failed of 140):
  func_80130D48 ×4 (1,064) · func_8018F3E4 (478) · func_8018B3D0 (478) · 13 × 223-ins siblings
  of func_8017E6D8 (2,899). distinct-code 3,833,224 -> 3,838,143 = 68.0% -> 68.1%.
- TWO OF MY OWN COUNTS COLLAPSED UNDER SCRUTINY BEFORE I ACTED ON EITHER (R14/R35):
  "func_8017CA80's family = 102 unmatched" was really 13 -- my count tallied family members whose
  NAME appears as a stub anywhere in the fleet, not instances actually unmatched (a semantics
  error, not arithmetic). "56,267 ins remappable" was really 8,114 -- 86% was the known -O0 /
  deferred set (the func_80144B9C whale, the func_8013C414 cluster). I nearly recommended a
  target on the first number.
- THE §77 CARRY GAP IS THE DOMINANT COST OF MECHANICAL REMAP: 23 of 27 first-pass CC1-FAILs.
  NEW .run/giants/s19_remap_tu.py sources the preamble from the exemplar's OVERLAY TU (the block
  between the previous top-level `}` and the def), applies family_remap's own substitution map,
  and adds the two includes match_one never adds -> 21 drafts went 0 MATCH -> 14 MATCH. The 13
  223-ins siblings share ONE exemplar, so a single preamble fix cleared all 13.
- USEFUL ASYMMETRY: func_8018F3E4/func_8018B3D0 FAILED match_one but BANKED in the whole-binary
  gate -- the real TU supplies decls the standalone compile lacks. A match_one CC1 FAIL is not a
  reason to skip the real gate on a remapped sibling.
- RESIDUAL 3,195 ins, causes NAMED not guessed: func_8017D5C0 (952) matches standalone, gate
  reports `conflicting types for memcpy` = the §58 red-herring (a warning from an unrelated TU
  position; SESSION-14 hit the same label and the true cause needed a hand-splice + real cc1
  stderr). func_80166994 ×3 + func_8016A290 ×4 still CC1-FAIL after the TU carry.
- FULL R22 DEFERRED DELIBERATELY: make clean wipes asm/, which the concurrently-running BF14
  agent reads on every probe. This batch changed only src/*.c (no config), so check-all is sound;
  the clean R22 must still run once the agent finishes.
2026-07-25 16:11:38 -06:00
Drew T 95684f9807 docs(phase-29): reconcile checkpoint — 3 behemoths + a 5-member family banked
HEAD commit:1012, 22 commits, R22 140/140 (8x). Fleet 80.5% instr; distinct-code 3,833,224 = 68.0%
(+19,712 ins this session, ALL from the three behemoths; propagation contributed +0). Banked
table updated with func_8017D960's 5-member family. Open actions re-ranked: 6 behemoths remain
(func_8017E778/func_8017CD9C are DONE as part of behemoth #2's family).
2026-07-25 15:49:22 -06:00
Drew T f9a2de3edd feat(phase-29): BEHEMOTH #2 func_8017D960 CRACKED (1806 -> 0) + its 5-member family = 16,690 ins
- CRACKED pin-free at xHigh (Opus 5 agent), then ALL FOUR family siblings banked via §40 remap,
  each MATCHING FIRST TRY: ov_SC03_090 (the crack) · ov_SC03_089 · ov_SC03_104 ·
  func_8017E778 @ ov_SC03_091 · func_8017CD9C @ ov_SC03_102 (the last two cross-address).
  Verified independently before believing the report (R14): match_one MATCH (3338 ins), then
  harvest_verify BYTE-IDENTICAL on all five binaries, then R22 clean-fleet 140/140.
- METRICS: distinct-code 3,816,534 -> 3,833,224 (+16,690) = 67.7% -> 68.0%, the first
  percentage-point movement in that metric all session. instr-weighted 80.3% -> 80.5%.
  Session distinct-code total +19,712 ins, ALL from the three behemoths; propagation gave +0.
- MY BRIEF WAS WRONG IN AN INSTRUCTIVE WAY -> §78. I said a negative length drift means "missing
  instructions". The 4 absent instructions were 4 emit tails × 1 nop -- delay slots the target
  could NOT FILL because the register it wanted was still live. otp at function scope has 4
  deaths -> fails local-alloc.c:472 -> global allocno in $a2 -> via global.c:668-671 pushes tp
  off $a1 -> the 0xFFFFFF mask is free early -> maspsx hoists it into the slot. Declaring otp
  PER EMIT ARM fixed the whole drift in one edit (3334->3338, 1806->333).
  SECOND TIME IN ONE SESSION a "structural"-looking residual was an allocno-class choice (the
  first: F510's "scheduling" transposition, §76). A nop present in the target but absent from the
  draft is usually a register-liveness fact, not missing code.
- TWO MORE REUSABLE FINDINGS (§78): gcc-2.7.2 fold NEVER leaves a literal first in an `|` chain
  (7 parenthesisations, all reassociate) -- so `or acc, var, K` first in the target means K was a
  VARIABLE in the source, an asm->source read that retires a whole sweep family. And "make it a
  variable" has TWO separable effects (fold-opacity vs a new allocno): a fresh short-lived local
  fixes structure and wrecks allocation (690 mismatched, damage ~300 ins away); reuse a busy one.
- ECONOMICS: 9 levers, each necessary by drop-one ablation, and 5 of the 9 were read straight off
  the MATCHED relatives func_8017F510 (cracked earlier today) and func_8017CA80. Crack the
  smaller family member first -- it is a lever library for the larger one.
- NEW TOOL .run/giants/s19_remap_family.py: family_remap + the §77 preamble carry in one step
  (reproduces the exemplar's FULL file-scope preamble with the tool's own substitution map
  applied). Took the 4 siblings from "4 rounds of CC1 FAIL each" to MATCH first try, ×4.
2026-07-25 15:48:54 -06:00
Drew T a5954802bf docs(phase-29): record the behemoth #2 agent run in the checkpoint
Opus 5 agent (xHigh) cracking func_8017D960 (3,338 ins, ov_SC03_090). Checkpoint records the
prize (5-member h_norm+h_seq family => ~16,690 distinct-code ins), the MEASURED baseline
(3334 vs 3338, 1806 mismatched, LENGTH-DRIFT/-4) with an explicit correction of the misleading
'one fold OR-chain error left' summary, the sandbox constraints, and the assets it was briefed
with (func_8017F510 matched today = same family at half size; func_8017CA80 matched in the same
TU; §76 allocno-class levers; the -fno-schedule-insns{,2} attribution primitive).
2026-07-25 15:15:26 -06:00
Drew T d8c96a5164 docs(phase-29): reconcile checkpoint — 2 behemoths banked, +3,022 distinct-code
HEAD commit:1009, 19 commits, R22 140/140 (7x). Fleet 80.3% instr; distinct-code 3,816,534
(+3,022 this session, ALL from the two behemoths; every propagation win contributed +0).
Open actions re-ranked: behemoths are now the PROVEN distinct-code lever, with the 8 untouched
ones listed and the func_8017D960 '4 off' summary corrected to its measured 1,806-mismatched
LENGTH-DRIFT reality. Notes that a FRESH behemoth at xHigh is the clean effort experiment,
since F510 was a High-effort continuation.
2026-07-25 15:02:57 -06:00
Drew T 130b9407b1 feat(phase-29): func_8017F5B4 (1,511 ins) banked MECHANICALLY off behemoth #3 — ~0 agent tokens
- func_8017F5B4 @ ov_SC02_031 shares behemoth #3's h_norm AND h_seq (96fe0455c344 /
  9a6bd2b91fd4) with a different h_exact = the same instruction stream differing only in masked
  reloc fields. The §40 family_remap case exactly, so NO agent was spent: family_remap
  --addr 0x8017F510 --from ov_SC03_006 --to ov_SC02_031 --to-addr 0x8017F5B4 substituted 52
  per-overlay symbols correctly on the FIRST invocation.
- match_one -> MATCH (1511 ins); harvest_verify --binary ov_SC02_031 -> BYTE-IDENTICAL;
  R22 clean-fleet 140 passed, 0 failed of 140.
- DISTINCT-CODE 3,815,023 -> 3,816,534 (+1,511). With behemoth #3 that is +3,022 distinct-code
  instructions from the two behemoths, versus +0 from every propagation win this session.
- ALL the work was PREAMBLE, none of it the body -> cookbook §77. Four CC1 FAIL rounds, each
  naming one construct the extractor drops: (1) multi-line `typedef struct {...} PolyGT4;` --
  family_remap's backward walk accepts a line only if it STARTS with extern/typedef/comment, and
  a multi-line typedef ENDS with `} PolyGT4;`, so the walk halts there AND LOSES EVERYTHING ABOVE
  IT; (2) hence the file-scope extern block above the #define BOXTEST/ATTEN block; (3) the
  exemplar's own #include lines (PolyFT3/PolyFT4 live in engine_types.h).
- THIRD CONFIRMATION TODAY OF ONE DEFECT CLASS, NOW ACROSS TWO TOOLS. §75b found
  dedup_propagate dropping a file-scope #define and PREDICTED the generalisation; family_remap
  then dropped a typedef, an extern block, and the includes. RULE (§77): after any mechanical
  template/propagate step, diff the exemplar's full file-scope preamble against what the tool
  emitted. A CC1 FAIL on a remapped sibling is a PREAMBLE report until proven otherwise -- it
  says nothing about whether the remap was right.
- Artifact preserved: .run/giants/s19_func_8017F5B4_remap.c
2026-07-25 15:02:37 -06:00
Drew T e3b51454bd docs(phase-29): reconcile checkpoint — behemoth #3 banked, no job running
HEAD commit:1007, 17 commits, R22 140/140 (6x). Fleet 80.3% instr; distinct-code 3,815,023
(+1,511 from the behemoth, the only distinct-code movement of the session). func_8017F510
added to the banked table.
2026-07-25 14:41:26 -06:00
Drew T 3ffff74f5b feat(phase-29): BEHEMOTH #3 func_8017F510 CRACKED — 97 -> MATCH (1,511 ins), pin-free
- BANKED into ov_SC03_006 through the whole-binary byte-gate (G3/P9); R22 clean-fleet
  140 passed, 0 failed of 140. Verified independently before believing the agent's report
  (R14): match_one -> MATCH (1511 ins), then harvest_verify -> BYTE-IDENTICAL.
- DISTINCT-CODE 3,813,512 -> 3,815,023 = +1,511, EXACTLY the function's instruction count and
  the ONLY distinct-code movement of the entire session. Reach is ×1 by sig, no propagation --
  which is precisely why it moves the metric propagation cannot touch. instr 80.3%, fn 89.18%.
- EFFORT EXPERIMENT (Drew): behemoths #1-#3 were worked at High; this is the first at xHigh
  (Opus 5 agent). It closed a residual the lower tier had fully localized but could not move,
  and that 3,663 permuter candidates at base 97 had failed to improve by even 1.
- MECHANISM -> cookbook §76: the allocno CLASS (local vs global) is the dominant regalloc lever
  and C reaches it ONLY through declaration scope and variable reuse -- unreachable by statement
  order, expression shape, pins, or random search, which is exactly why the permuter was spent.
  (1) `otp` per emit ARM: 4 deaths -> four 1-death local pseudos (local-alloc.c:472); its
  second-order effect via global.c:668-671 (local placements re-marked as HARD regs for
  global-alloc) had made the target's otp=$a0 STRUCTURALLY IMPOSSIBLE, visible as hard-reg 4 in
  the `;; N conflicts:` tail of the .greg dump. (2) `cb` reused as the unlit rgbc temp: refs
  27->39 lifts its global.c:594 allocno_compare priority past `tp`, flipping the 3-colouring ->
  97 -> 10. (3) one shared `rgbw` temp -> 10 -> 2. (4) mny-before-my + one zero-byte __asm__ at
  the head of the tri cull block -> MATCH.
- THREE CORRECTIONS TO MY OWN BRIEF, all byte-evidenced: residual B was never a scheduling
  residual (it fell out free with lever 2 -- a register grant seen as a schedule diff); residual
  A is RTL EXPANSION order, proven with -fno-schedule-insns AND -fno-schedule-insns2 (source
  order survives both -- that attribution primitive is the reusable bit); residual C had no
  single c3 seed (c3 has no lever of its own, it moves only when cb out-ranks tp).
- FIXED a latent SHARED-HEADER defect, pre-existing and unrelated to the draft:
  src/shared/engine_types.h closed its include guard at line 1174 of 1259, leaving 11 typedefs /
  85 lines OUTSIDE the guard since the crack-wave lift. A TU including it twice re-declares them
  and gcc-2.7.2 rejects a repeated typedef even when identical -> `conflicting types for
  Blk16_956C`. Guard moved to EOF; byte-neutral.
- ARTIFACTS TRACKED (R20): .run/giants/s19_func_8017F510_b4.c (130-line dossier) +
  s19_f510_report.md, whose ~50-row do-not-re-buy table is arguably worth more than the match,
  + the s19_* analysis tooling.
- STRETCH, MEASURED: func_8017F5B4 (1,511 ins, ov_SC02_031) has a DIFFERENT h_exact -- not a
  dedup sibling, a family_remap TEMPLATE candidate off the b4 source.
2026-07-25 14:41:08 -06:00
Drew T a3582209fc docs(phase-29): record the running behemoth agent in the checkpoint
An Opus 5 agent (xHigh) is cracking behemoth #3 func_8017F510 (1,511 ins, ov_SC03_006,
reach x1 = pure distinct-code). Checkpoint now names its deliverables (.run/giants/
s19_func_8017F510_b4.c + s19_f510_report.md), its sandbox constraints (no src/config/docs,
no commit, no make), the re-measured baseline (1511/1511, 97 mismatched, ADDRESSING/cse,
99.5% structural), the A/B/C residual breakdown, and the byte-proven fact that the permuter
is spent on it. Also records Drew's effort experiment: behemoths #1-3 ran at High, this is
the first at xHigh.
2026-07-25 13:53:43 -06:00
Drew T 216b53b9bc docs(phase-29): reconcile the SESSION-19 checkpoint to the final state
func_80174CB0 sweep complete (×135), R22 140/140 (5× this session), tree clean, no background
job running. HEAD commit:1004, 12 commits. Fleet 80.3% instr / 67.7% distinct / 89.18% fn-count.
+46,433 ins banked this session with zero function drafting. Open action 1 closed; the ranked
list now opens on FRESH CRACKS (the only distinct-code lever, needs /effort ultracode).
2026-07-25 13:44:55 -06:00
Drew T 6e9cbda926 feat(phase-29): func_80174CB0 ×3 -> ×135 (§75c pair); the census predicted the residual exactly
- dedup_extend banked 132 / 179 planned across 135 binaries: func_80174CB0 VERIFIED in 132,
  FAILED in exactly 3. 123 ins × 132 = 16,236 ins.
- THE PREDICTION HELD TO THE OVERLAY. The blocker breakdown across the original 134-binary sweep
  was 131 class-B (func_8012F14C arity split) / 3 class-A (func_80012ABC, census 73 s32 vs 7
  s16). Fixing class B alone banked 132 and left 3 -- precisely the class-A set. A diagnosis that
  predicts WHICH members will still fail, and is right, is much stronger evidence than one that
  explains failures after the fact; same shape as §75b predicting that the 3 stuck members would
  be exactly the 3 files carrying the __volatile__ spelling of SHB.
- FLEET: instr-weighted 80.2% -> 80.3% (10,539,723 -> 10,555,959); fn-count 89.14% -> 89.18%;
  distinct-code 67.7% UNCHANGED (propagation moves coverage, not distinct-RE -- fresh cracks are
  the only lever there). dedup 1886 validated / 0 failed, C1 coverage 239,604/239,604.
  0 NON_MATCHING (G4).
- R22 clean-fleet: make clean && extract-all && check-all -> 140 passed, 0 failed of 140.
- cookbook §75c committed with this batch. The 3 residual overlays need the 7 `s16` func_80012ABC
  decls normalized -- worth 3 overlays only, so do it only if trivially cheap.
2026-07-25 13:44:24 -06:00
Drew T a999f0badd docs(phase-29): REFRESH the SESSION-19 checkpoint (it had gone stale mid-session)
Drew caught that I paused with a stale checkpoint — the block still read HEAD commit:0996 /
80.1% / R22 3x and predated the ENGINE_SHB x135 result, the dedup_extend include-stripping
bug + fix, and §75a/§75b/§75c. Stale is worse than absent; per-task commits are not a
substitute. Refreshed with: the banked table (4 fns, +30,197 ins, zero drafting), the six
cookbook entries, the in-flight func_80174CB0 sweep + explicit recovery instructions if it
did not finish, the ranked open actions (fresh cracks = the only distinct-code lever), and
an explicit list of the five errors I made this session.
2026-07-25 13:37:53 -06:00