Commit Graph

1933 Commits

Author SHA1 Message Date
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
Drew T 398e653c92 fix(phase-29): §75a class-B remedy is the FULL §17a-1 pair — decl AND call-site cast
- The K&R-decl-only probe was HALF the fix, and cc1 said so exactly:
    ov_SC01_001_jr_801734BC.c:2616: too many arguments to function `func_8012F14C'
  `()` dissolves the DECLARATION conflict (the failure class moved PLUMBING -> CC1-FAIL), but the
  composite type after the TU's earlier `void func_8012F14C(s32);` prototype is still 1-param, so
  the macro's 3-arg CALL is a hard error. Reproduced by hand-splicing the macro into
  ov_SC01_001 and reading real cc1 stderr rather than trusting the classifier's `Error 33`.
- FIX = the other half of §17a-1 (what cast_call_sites.py does, and what §20 established): cast
  the call site so it does not depend on the TU's prototype at all —
    ((void (*)(s32, s32, s32))func_8012F14C)((s32)&mtx, (s32)&vec, (s32)&out)
  gcc-2.7.2 folds a cast of a KNOWN function symbol back to a direct `jal`, so the bytes are
  unchanged. Decl stays `()` so it cannot conflict in either declaration order.
- BYTE-GATED on the full existing radius: ov_SC07_006 7ca772be · 007 b3b95547 · 011 9885af74 —
  all BYTE-IDENTICAL.
- LESSON for §75a class B: the remedy is the PAIR, never the decl alone. A decl-only change moves
  the error from `conflicting types` to `too many arguments` and looks like a new wall.
2026-07-25 13:34:53 -06:00
Drew T 9924b26968 fix(phase-29): dedup_extend stripped a load-bearing include on a 0-banked run (§61 class)
- THE DEFECT: `if not banked: ensure_include_revert(b)` fired UNCONDITIONALLY.
  `ensure_include()` returns True only when IT inserted the line, but the revert ignored that
  return value — so on a binary that ALREADY had `#include "../shared/engine_core.h"` from
  earlier work, a zero-bank run REMOVED it, leaving every `DEFINE_func_*()` in that overlay
  unresolvable.
- BLAST RADIUS AS IT HAPPENED: the §75a class-B probe banked 0 across 135 already-wired
  binaries, so the include was stripped from ALL 135 in one run. Caught by reading `git status`
  before moving on; `git checkout -- src/` restored (nothing was committed, nothing lost).
- WHY IT SURVIVED THIS LONG: the tool's designed case is NEWLY-onboarded binaries (which do not
  have the include, so the revert is correct there), and prior runs banked >=1 per binary so the
  branch never fired.
- WHY NO BYTE-GATE SAW IT (R34): the damage lands AFTER the last gate runs. harvest_verify had
  already finished and reverted its drafts; the byte-gate is a null oracle for state mutated
  after it. This is the §61/§63 class — an undo written as an INVERSE TRANSFORM instead of a
  snapshot restore, applied without checking whether the forward action was ever taken. Same
  shape as the SESSION-14 `fix_arity_callers --revert` incident.
- FIX: capture `added_include = ensure_include(b)` and revert ONLY if this run added it.
- NEGATIVE CONTROL: stripping the include from ov_SC01_004 makes `make audit-binaries` fail loud
  ("[FAIL] ... does NOT include ../shared/engine_core.h", make Error 1) — the R36 citizenship
  gate is exactly the detector for this class, confirmed by experiment, then restored.
2026-07-25 13:27:07 -06:00
Drew T 8f63c1a8e0 probe(phase-29): §75a class-B — K&R () for the carried func_8012F14C decl (func_80174CB0)
- The class-B arity split (1944 `(s32)` vs 968 `(s32,s32,s32)`) blocked func_80174CB0 in 131 of
  134 overlays: the macro carried the 3-param prototype, the failing TU declares the 1-param one
  FIRST (ov_SC01_001: TU@328 vs instantiation@2616), so cc1 sees two prototypes of different
  arity and rejects.
- Per cdecl.compatible's MEASURED gcc-2.7.2 behaviour a no-prototype `()` is accepted in BOTH
  orders here: prototype-first + ()-second always; ()-first + prototype-second when no parameter
  is altered by default promotion -- and all three args are s32, which does not promote. So one
  K&R decl should satisfy both populations regardless of where each TU declares it.
- Call site UNCHANGED (`func_8012F14C((s32)&mtx, (s32)&vec, (s32)&out)`): with a K&R decl the
  args pass under default promotions, and s32 args are unaffected -> same codegen.
- BYTE-GATED on the full existing radius before extending: ov_SC07_006 7ca772be · 007 b3b95547 ·
  011 9885af74 -- all BYTE-IDENTICAL. The extend result is the real test of the prediction.
2026-07-25 13:19:20 -06:00
Drew T 3bbfe21596 feat(phase-29): func_80165CA0 ×3 -> ×135 via ENGINE_SHB; +22 fns ×1; §75b (the carried-#define gap)
- dedup_extend banked 157 / 478 planned across 135 binaries: func_80165CA0 (99 ins) ×135
  (~+0.10pp) + 22 other functions ×1 picked up in the 3 overlays the first sweep excluded.
- FLEET: instr-weighted 80.1% -> 80.2% (10,525,534 -> 10,539,723, +14,189 ins); fn-count
  89.09% -> 89.14%; distinct-code 67.7% (unchanged — propagation moves coverage, not distinct-RE).
  dedup 1886 validated / 0 failed, C1 coverage 239,472/239,472. 0 NON_MATCHING (G4).
- R22 clean-fleet: make clean && extract-all && check-all -> 140 passed, 0 failed of 140.
- §75b — extraction lifts `extern`s but NOT file-scope `#define`s, so a body matched with a macro
  in its preamble compiles only where that overlay's define is in scope ABOVE the splice point.
  Signature is a LINK error (`undefined reference`), never `conflicting types`: an unexpanded
  SHB(x) parses as a call to an undeclared function. The diagnosis PREDICTED the membership —
  the 3 stuck members are exactly the 3 files carrying the __volatile__ spelling of SHB, i.e. the
  function's own preamble still sitting above its own instantiation.
- R14/R35 IN ACTION: the full-sweep census REVERSED the ranking I had just committed. I put the
  class-A normalization first at "~+0.13pp if it reaches ×138"; measured across all 134 it is
  worth 3 overlays (func_80012ABC 3, func_8012F14C 131). The cheap win was the one I ranked
  third. §75a's "collect across the whole sweep before scoping" earned itself immediately.
- NEXT (specified, not guessed): func_80174CB0 is class B on func_8012F14C (1944 `(s32)` vs 968
  `(s32,s32,s32)`). The macro carries the 3-param prototype; the failing TU declares the 1-param
  one FIRST (ov_SC01_001: TU@328 vs instantiation@2616) -> two prototypes, different arity ->
  reject. Per cdecl.compatible's MEASURED rule a K&R `extern void func_8012F14C();` is accepted
  BOTH ways round here (prototype-first + `()`-second always; `()`-first + prototype-second when
  no param default-promotes, and s32 does not) -> it should satisfy both populations in either
  order. One-line probe on the carried decl, byte-gate the 3 members, then extend.
2026-07-25 13:18:36 -06:00
Drew T 364ddd7055 fix(phase-29): ENGINE_SHB — the carried-#define gap that capped func_80165CA0 at ×3
- CAUSE (measured, not guessed): the 132 extend failures were `undefined reference to 'SHB'` --
  a LINK error, not a type conflict. SHB is not a symbol; it is a file-scope
  `#define SHB(x) __asm__(...)` sign-extension barrier. A body's preamble can carry `#define`s
  as well as `extern`s, but extraction lifts only the externs -- so the `#define` was left behind
  in the source overlay. In ov_SC01_077 it sits literally BETWEEN the two carried externs and the
  instantiation:
      extern s32 D_8011D030;
      extern s32 D_80126728;
      #define SHB(x) __asm__ __volatile__("" : "=r"(x) : "0"(x))
      DEFINE_func_80165CA0()
  The other 132 overlays DO define SHB -- ~300 lines further down the file (stub @4462 vs
  #define @4781 in ov_SC01_001), i.e. BELOW the splice point, so the preprocessor never expands
  it and cc1 emits a call to an undeclared `SHB`. Pure ORDERING; nothing was missing.
- Also explains why the 3 current members are EXACTLY the 3 files carrying the __volatile__ SHB
  spelling: that define is the function's own preamble, still sitting above its instantiation.
- FIX: engine_core.h owns the barrier as ENGINE_SHB (distinct name, so the overlays' own SHB --
  which exists in BOTH a volatile and a non-volatile spelling -- can never collide), and
  DEFINE_func_80165CA0's 7 uses now call it. Volatile form: what the 3 banked members compile
  with today. The body is now self-contained wherever it is instantiated.
- BYTE-GATED the full existing blast radius: ov_SC01_077 d19c9580 · ov_SC01_000 9052dc0e ·
  ov_SC07_006 7ca772be -- all BYTE-IDENTICAL.
- This is the dedup_propagate counterpart of Phase-27's family_remap._carry_macros (§75b).
2026-07-25 13:04:15 -06:00
Drew T 1f9289f790 docs(phase-29): SESSION-19 CLOSING CHECKPOINT — supersedes the SESSION-18 block
Fleet 80.1% instr / 67.7% distinct / 89.09% fn-count; R22 140/140 (3x this session);
dedup 1886/0; 0 NON_MATCHING. Banked func_8014D4C0 + func_8014F3E8, both x138.
Carries forward the ranked open actions (func_80174CB0 class-A-on-the-target-side,
func_8012F14C class-B arity probe, func_80165CA0 class C, the 7 ov_SC01_077 capped fns,
func_8014D820 = the Fable5 case, fresh cracks = the only distinct-code lever), the
behemoth table (now noting func_8017D960's pins are §74-audited safe), and the hazards
(+ the new one: dedup_extend refuses a dirty tree, H4).
2026-07-25 13:01:05 -06:00
Drew T 39127535da feat(phase-29): func_8014F3E8 ×4 -> ×138 via dedup_extend; §75a enumerates the exclusion classes
- THE NORMALIZATION PAID: one `dedup_extend --binaries <the 134 excluded>` banked 134/400
  planned -- func_8014F3E8 VERIFIED in ALL 134 -> ×138 total (+4,288 ins), no drafting at all.
  A 4-overlay island became full fleet reach because the carried extern finally agreed.
- FLEET: instr-weighted 80.0% -> 80.1% (10,509,526 -> 10,525,534 = +16,008 ins, exactly the
  projected 84×138 + 32×138); fn-count 89.02% -> 89.09%; distinct-code 67.7% (unchanged, as
  expected -- propagation moves coverage, not distinct-RE). dedup 1884 -> 1886 validated / 0
  failed, C1 coverage 239,315/239,315. 0 NON_MATCHING (G4).
- R22 clean-fleet: make clean && extract-all && check-all -> 140 passed, 0 failed of 140.
- §75a — "PROPAGATION-CAPPED" IS AT LEAST THREE CLASSES, and the classifier names which:
    A minority spelling   `conflicting types` + a lopsided census (1710 vs 4) -> normalize, cheap
    B genuine arity split same message, TWO real populations (func_8012F14C: 1944 `(s32)` vs
                          968 `(s32,s32,s32)`) -> the §29 loose-typing wall; a K&R `()` MAY satisfy
                          both but is order-dependent -> PROBE, do not normalize on a guess
    C missing extern      `undefined reference to 'SHB'` -- a LINK error, unrelated to types
  The discriminator is one grep (census the symbol cc1 named) and it decides the remedy.
- R14 self-correction recorded: I predicted func_80174CB0 was "the identical class". It is class
  A in KIND but on DIFFERENT symbols, and different ones per overlay (func_80012ABC at
  ov_SC01_000 where the minority is on the TARGET side; func_8012F14C at ov_SC01_001 = class B).
  One member's error names one blocker, not the blocker set -- collect the classifier's line
  across the whole sweep before scoping a fix.
- func_80174CB0 (×3) and func_80165CA0 stay capped, each now with a named cause and a named next
  probe -- not a wall verdict.
2026-07-25 13:00:00 -06:00
Drew T 2fcb8de6bf fix(phase-29): normalize func_8014F468 to the fleet-canonical s32 (unblocks the ×138 reach) + §75
- THE PROPAGATION CAP WAS A MINORITY-SPELLING SOURCE OVERLAY, byte-censused:
    extern s32 func_8014F468(void);   1710   |  s32 func_8014F468(void)  134   <- fleet canon
    extern void func_8014F468(void);    20   |  void func_8014F468(void)   4   <- the outlier
  and ALL 4 `void` definitions are ov_SC07_{006,007,010,011} — the overlay the F3E8 body was
  banked from. dedup_propagate carries the source overlay's file-scope externs into the shared
  macro VERBATIM, so the macro inherited `extern void` and the 134 overlays that define the
  symbol `s32` rejected it. Propagation landed on exactly that 4-overlay island.
- The exclusion message ("byte-diverge / irreconcilable") is provably the wrong cause: members
  are selected BY h_exact, so all 138 are byte-identical by construction. It is a COMPILE
  conflict, never a byte one (same defect family as §68's mislabel, same tool).
- NORMALIZED the 24 minority occurrences to s32 (4 definitions + 19 overlay externs + the 1
  line in the freshly-authored macro). func_8014F468 is a pure inline-asm $sp-switch trampoline
  — no C-level value flow — and 134 overlays already PROVED s32 is byte-correct for the
  identical function. Fleet is now uniform: 1730 extern s32 + 138 s32 defs, 0 `void`.
- BYTE-GATED the complete blast radius (the 4 instantiators of DEFINE_func_8014F3E8):
  ov_SC07_006 7ca772be · 007 b3b95547 · 010 d7b5875d · 011 9885af74 — all BYTE-IDENTICAL.
- cookbook §75: census the carried extern before believing an exclusion message; prefer a
  majority-spelling source overlay; always pass --recover; after normalizing use dedup_extend
  (the body is already a macro) not dedup_propagate --addr.
2026-07-25 12:45:11 -06:00
Drew T 10ea5ff653 feat(phase-29): propagate the widen batch — func_8014D4C0 ×138; func_8014F3E8 ×4 (cause measured)
- func_8014D4C0 (84 ins) PROPAGATED ×138: all 138 overlays rebuilt byte-identical, group
  E_func_8014D4C0 registered. 84×138 = 11,592 ins.
- func_8014F3E8 (32 ins) propagated ×4 only (the ov_SC07_{006,007,010,011} island), 134
  overlays excluded one at a time.
- TWO FINDINGS, both measured:
  (1) THE FIRST RUN'S "drop" WAS A FLAG OMISSION, NOT A WALL. Without --recover,
      dedup_propagate takes the historical all-or-nothing path on the first culprit overlay,
      so ONE divergent member cost the whole group (×0). With --recover, Part A excludes just
      the culprit -> ×4 instead of dropped. Always pass --recover on a targeted --addr run.
  (2) THE EXCLUSION CAUSE IS A MINORITY-SPELLING SOURCE OVERLAY, not byte divergence. The
      sigs prove all 138 members share ONE h_exact (2ccf344d), so nothing diverges in bytes.
      The macro carries the source overlay's `extern void func_8014F468(void);` while the
      fleet census is 1,710 `extern s32` + 134 `s32` definitions vs 20 `extern void` + 4
      `void` definitions -- and all 4 `void` definitions are ov_SC07_{006,007,010,011}, i.e.
      the source overlay I banked from is the OUTLIER. The macro inherited the minority
      spelling and silently capped its own reach at that island.
- => the fix is NORMALIZATION (24 occurrences), not a reconciliation engine; the follow-up
  commit flips the SC07 minority to the fleet-canonical s32 and re-propagates.
- R22 clean-fleet: make clean && extract-all && check-all -> 140 passed, 0 failed of 140.
2026-07-25 12:42:24 -06:00
Drew T 6f9860c46a docs(phase-29): §74 — pin-safety audit; the 5-pin behemoth draft is SAFE (open action #3)
- AUDITED .run/giants/s18_func_8017D960_b2.c (pins $25 $17 $19 $20 $21) WITHOUT recompiling:
  the SESSION-18 match_one object survives and cmp proves its t.c is this draft.
- VERDICT SAFE. The corrupting form of the §72 hazard is a CALLER-SAVED pin ($25=$t9) whose
  live range spans a jal — gcc-2.7.2 does not save/restore an explicit-register variable
  across a call. Byte-checked: exactly 3 jal, all at 0x2c-0x50; first pin write at 0x58 =>
  NO call after the pins are established. Corroborated by a token census of the C (every
  call-shaped token after line 270 is a file-local macro: gte_*, BOXTEST, ATTEN, CLAMP80).
- The observed excess writes (2/3/3/5/5 vs 2 assignments each + 1 epilogue lw) are the BENIGN
  §72 mode: gcc using the pinned reg as scratch before the pinned value lands (lui/lw/addiu on
  $20, with addu t9,s4,zero routing r1's value out through it). Nothing live was clobbered.
- cookbook §74: the reusable audit (objdump the surviving object; compare jal addresses against
  the first pin write; expect writes == assignments + 1 epilogue restore) + the standing rule —
  prefer a callee-saved register for any pin outliving a call; a caller-saved pin across a jal
  is a real wall verdict, not a drafting slip.
2026-07-25 12:28:14 -06:00
Drew T 1c0d29d91d feat(phase-29): §30#2 widen batch — func_8014F3E8 + func_8014D4C0 banked; §73 (the two axes)
- FLEET WIDEN (T2, one edit): extern void -> extern s32 for func_8014F3E8 + func_8014D4C0
  across src/** (16 decls in engine_core.h + 5,079 in 3,459 overlay .c; 0 `extern void`
  left, 0 pre-existing `extern s32`). Scope re-verified against the tree first (R14/R35):
  the SESSION-18 counts reproduce exactly and no decl exists outside the `extern void <name>`
  shape in any .c/.h under src/.
- BYTE-NEUTRALITY OF THE WIDEN ISOLATED FIRST: ov_SC07_006 7ca772be + ov_SC01_000 9052dc0e
  BYTE-IDENTICAL before splicing any draft (ov_SC01_000 chosen because it instantiates the two
  return-CASTING macros — the only sites a decl's return type could touch codegen).
- BANKED into ov_SC07_006 (both ×1, both reach ×138 by sig: single h_exact across 138/138):
  func_8014F3E8 (32 ins) on gate 1; func_8014D4C0 (84 ins) on gate 2.
- FINDING -> cookbook §73: the widen fixed only HALF the conflict. A def-side self-decl
  conflict has TWO independent axes — RETURN (fleet macro-widen, T2, R22-mandatory) and
  PARAMS (canonical param types + casts at each USE, T0, no fleet edit). func_8014D4C0
  failed the first gate on the PARAM axis (canon `void*` vs draft `u16*`); the §17a-1 move
  applied to the def's own signature banked it with nothing outside the draft touched.
  Diagnose the axis before reaching for the expensive fix.
- R22 clean-fleet: make clean && extract-all && check-all -> 140 passed, 0 failed of 140.
  make report: dedup 1884 validated / 0 failed, C1 coverage 239039/239039, 0 NON_MATCHING (G4).
  Fleet 80.0% instr / 67.7% distinct / 89.02% fn-count (the ×138 propagation is the value).
2026-07-25 12:24:30 -06:00
Drew T 5d19a48236 docs(phase-29): SESSION-18 CLOSING CHECKPOINT — supersedes the stale mid-session block 2026-07-25 12:00:36 -06:00
Drew T dfa366c7c6 docs(phase-29): cookbook §72 — behemoth #3 to 1511/1511; a register pin is a PREFERENCE, not a reservation
func_8017F510 (1,511 ins): EXACT length, frame 0x258 exact, byte-exact prologue AND epilogue,
identical sp-slot set, 99.5% register-masked structural / 93.3% byte-aligned, SYMS-OK, 97 divergent.
Not a match (G3). §71's callee-set lever delivered ~90% of the C and a first compile at 1528/1511.

- CORRECTNESS FINDING (qualifies §17): a local `register s32 x __asm__("$30")` pin produced a
  seductive 1511 ins / 98.9% and was a MISCOMPILE -- gcc-2.7.2 ALSO allocated $s8 to an unrelated
  live value. A pin is a HINT to the allocator, not a reservation. Never ship one without inspecting
  the pinned register's defs. Banked work is safe by construction (the byte-gate rejects a
  miscompile); the exposure is UN-GATED drafts. ACTION: behemoth-2's draft carries FIVE pins
  ($25 $17 $19 $20 $21) and must be re-checked before anyone builds on it.
- THE HONEST FIX was source-level: the +17 drift was live-range stretching from REUSING w/wz for the
  vertex-word reads (spilling amb, 7 lw+nop pairs). Dedicated temps -> 1528->1511, 88%->99.6%, no pin.
- GIV RECORD ORDER (§70 family): part->prim must be read BEFORE part->nprim -- loop.c:combine_givs
  walks bl->giv in REVERSE record order, so the last-recorded giv becomes the combined base.
- RESIDUAL 97 traced to ONE seed: c3 is $a2 in the target, $a3 in the draft; tp takes the other of
  the pair and renames the whole 4-tail block. Fix c3 -> $a2 and ~93 should fall together.
- SPENT, byte-recorded: decl-order permutations, block-scoping, splitting/inlining tp, reusing f0,
  vertex axis orders, and decomp-permuter (4,724 candidates, base 97, ZERO improvement -- a §3 hard
  tail outside the C-randomisation space).
- b3_align.py / b3_pos.py supersede the b2_* aligners.
2026-07-25 02:05:40 -06:00
Drew T 1de9a1a2e9 docs(phase-29): §71 corrected — fingerprint a giant's family by CALLEE SET, not adjacency or h_seq 2026-07-25 01:26:06 -06:00
Drew T 8e18bb3df6 chore(phase-29): preserve the remaining behemoth-2 analysis tools (b2_cmp/dump/map/marks/side) 2026-07-25 01:22:36 -06:00
Drew T 28d10601ae docs(phase-29): cookbook §71 — behemoth #2 to 3334/3338; the adjacent-sibling lever; §69 partly REFUTED
func_8017D960 (3,338 ins): 3,334 ins drafted, 98.8% register-masked-identical, 88.3% byte-aligned,
byte-exact prologue AND epilogue, exact 0x320 frame, same 10 saved regs, identical ~110 stack slots,
SYMS-OK. NOT a match (G3) -- but an order of magnitude closer than behemoth #1.

- THE LEVER: it is the LIT VARIANT of func_8017CA80, the 952-ins renderer immediately above it in the
  same file (already matched). Diffing the sibling gave ~90% of the C free and a 3334/3338 draft on
  the FIRST compile. GENERALISED: before mapping any giant, grep for an already-matched adjacent
  function that is the same routine. One grep can replace days of analysis.
- §69 PARTLY REFUTED: its law 1 (write whole body coarsely -> correct frame/saved-reg set) CONFIRMED
  and decisive; law 2 (measure region-aligned) confirmed but its TOOL did not transfer (per-switch-
  case); its HEADLINE ("the deliverable is the map, not a match") is refuted for non-dispatchers --
  §69 was derived from a 359-call dispatcher with no sibling.
- TOOL SUPERSESSION: .run/giants/b2_mask.py + b2_full.py = shape-agnostic masked sequence aligner
  (structural AND byte numbers). Replaces s18_regions_comparator.py for all giants.
- FAMILY: func_8017CD9C + func_8017E778 are the same 3,338-ins fn with only 3 light-descriptor
  symbols changed -> one crack templates x3.
- MY OWN PROFILING ERROR, recorded (R14/R35): I briefed "no switch" from a sltiu jump-table grep; the
  switch is a COMPARISON TREE (23 slti). A jtbl grep is not a switch detector.
2026-07-25 01:18:00 -06:00
Drew T ba35785ec4 feat(phase-29): bank func_801777BC (59 ins) x138 — the giv-init base-register lever (§70)
- MATCH (59 ins), real-TU verified by the agent before handing back (cc1 rc=0, 59/59, 0 diffs).
- Propagated x138 with ZERO exclusions -> confirms the ×3 cap on func_80174CB0 was purely the
  carried-extern collision: a body with no externs propagates clean.
- R22 clean-fleet 140/140, 0 failed. dedup-check 1884 validated / 0 failed, C1 coverage complete.
- FLEET CROSSES 80.0% instr-weighted (10,509,526 / 13,141,652); fn-count 89.02%; distinct 67.7%.
- THE LEVER (cookbook §70): residual was ONE instruction, addiu $t0,$t1,0xC vs $t0,$a0,0xC -- a giv
  based on a copy of the param. Reading gcc-2.7.2 loop.c/cse.c proved the natural form can never
  emit the target: cse.c:make_regs_eqv makes the copy canonical (it out-lives a0) and
  loop.c:update_reg_last_use won't extend a0's last-use (giv-init UID >= max_uid_for_loop). Fix:
  walk the PARAMETER itself, so record_initial sees the biv init as hard reg (reg:SI 4),
  valid_initial_value_p accepts it (precondition: no calls), and emit_iv_add_mult bases the giv on
  $a0 -- yielding both required instructions free.
- META: this compiler-source reasoning was done by an ORDINARY Opus 5 drafting agent, unprompted --
  the tier Phase 23 reserved for Fable5. One data point, recorded as such; the cheap action is to
  give routine drafting agents the gcc source path.
2026-07-25 00:49:04 -06:00
Drew T c31b1ad0b3 docs(phase-29): cookbook §70 — the giv-init base register lever (walk the param, not a copy) 2026-07-25 00:39:58 -06:00
Drew T a8872fa169 docs(phase-29): cookbook §69 — behemoth recon (func_80183814, 5122 ins): map it, don't draft it
First attempt on the game's largest unmatched function. No match (never the goal); the deliverable
is the map, and every claim is byte-verified against the target .s.

- STRUCTURE: an actor state machine, not a straight-line giant. 21-case switch via jtbl_801F4CE4
  (sltiu 0x15); 359 jals to only 37 DISTINCT callees (verified); 48-ins preamble + 19-ins shared tail.
- THE FINDING: it decomposes into repeated templates, not 5122 unique instructions —
  35 instances of one "spawn-effect" packet (~1400 ins, crack one -> 34 free),
  7 "wait/countdown" (already reproduced at 0 skeleton diffs), 12 "HUD/text",
  plus twin cases (0≈3, 1≈4). Only 3 cross-jump edges couple anything.
- TWO GENERAL LAWS FOR GIANTS, measured: (1) register pressure is GLOBAL, so a partial draft gets
  10 callee-saved regs instead of 8 and a matching PREFIX is structurally unavailable — write all
  cases coarsely first, then refine; (2) match_one's global number is meaningless on a partial giant
  (666 vs 5122) — measure REGION-ALIGNED instead.
- NEW REUSABLE TOOL: .run/giants/s18_regions_comparator.py (region-aligned skeleton comparator, works
  on any giant). Caveat travels with it: masks register numbers + jal targets, so it proves STRUCTURE,
  never closeness; finish on the whole-binary gate (G3/P9).
- 2 idioms cracked in passing (the D_x[t+K] constant-fold needing a separate index statement; the
  (s16)*(u16*)p + /455 magic-0x90090091 form).
- VERDICT: tractable but a ~2000-line WRITE, not a hard puzzle — no scheduler wall, no unsteerable
  regalloc. Recipe for the next attempt recorded.
- artifacts preserved under the tracked .run/giants/ path (.gitignore now allowlists *.py there).
2026-07-25 00:33:06 -06:00