- 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.
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.
- 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.
- 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.
- 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.
- 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.
- 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).
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).
- 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.
- 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.
- 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.
- 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.
- 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).
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.
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.
- 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.
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).
TWO mislabels in one tool, both found by making it print what the compiler actually said.
1) compiles_standalone() returned a bare False and the caller filed EVERY failure under
"overlay-local TYPE (the real cap)". The dominant real cause is undeclared FILE-SCOPE EXTERNS.
Now returns (ok, stderr) and the skip is classified by actual cc1 output.
2) find_site()'s backward walk over "preceding contiguous externs" skipped BLANK lines but not
COMMENT-ONLY lines, so a full-line /* ---- */ between two extern groups dropped every extern
above it. Comment lines are now skipped like blanks and filtered out of the emitted body so
make_macro never meets a `//`.
RESULT, measured honestly: func_80174CB0 went from "not self-contained" to a 138-member PLAN, but
--recover banked only x3 (ov_SC07_006/007/011); 135 overlays excluded. Those exclusions are NOT
byte divergence (all 138 share h_exact) -- they are the CARRIED EXTERNS colliding with each target
overlay's own decls. The carry is necessary but not sufficient: it must reconcile per-target-TU
(cdecl.compatible(), the shape reconcile_tu already uses). Spec updated in CURRENT_PHASE.md.
- R22 clean-fleet 140/140, 0 failed. dedup-check 1883 validated / 0 failed, C1 coverage complete.
- fleet instr 79.9% (10,501,384 / 13,141,652); +246 ins from the x3.
- WHY THIS MATTERS beyond the numbers: the Phase-21 backlog already prescribed "macro-extern-
injection frees them x134 (~+0.3%)" and it was never built, because the mislabel told every later
session these were the known-hard type wall. A wrong diagnostic label cost ~4 phases.
- cookbook §68. NOTE the exclusion message is ALSO mislabelled ("byte-diverge / irreconcilable"
conflates differing bytes with a non-compiling instantiation) -- logged to fix.
compiles_standalone() returned a bare False and the caller attributed EVERY failure to the
overlay-local type cap. The dominant real cause is undeclared FILE-SCOPE EXTERNS: the body
references extern decls living outside the extracted def block (func_80174CB0: 22 of them;
carrying them makes it compile cc1 rc=0).
- compiles_standalone now returns (ok, stderr); the skip is classified by actual cause:
"missing file-scope extern (CARRY-FIXABLE): <names>" vs "overlay-local TYPE (the real cap)".
- FLEET SIZING (--auto-from ov_SC01_077 --check-only): 7 skipped, ALL 7 carry-fixable, 0 genuine
type-cap. Three of them (0x80142B2C/0x801535F4/0x80155800) are on the Phase-21 backlog list whose
note ALREADY said "macro-extern-injection frees them x134 (~+0.3%)" -- never built, because the
mislabel told every later session they were the type wall. A wrong label cost ~4 phases.
- also: func_80174CB0's local Mtx_/Svec_ typedefs swapped for the canonical shared MATRIX/SVECTOR
(byte-identical layouts); ov_SC07_006 still BYTE-IDENTICAL 7ca772be.
- value behind the real fix: the 7 (~+0.3pp) + func_80174CB0 x138 (16,974 ins, ~+0.13pp), ~0 tokens.
- _carry_externs itself is SPEC'd but NOT built here: it writes 138 overlay files (§63 class) and
wants a fresh session with an R22 budget. func_80174CB0 (banked x1) is the test case.
SESSION-17 filed this as §65g-class: "not 'run one more tool', but 'needs a transform that does
not exist yet'". Refuted. It needed the correct self-declaration.
- The TU expands DEFINE_func_80174C80() carrying `extern s32 func_80174CB0(s32, s32);`, while all
~100 prior drafts defined `void func_80174CB0(s32, s16)` — matches perfectly STANDALONE, dies in
the real TU with `conflicting types`. Defining it `s32 (s32, s32)` and recovering param_2's
s16-ness with an explicit (s16) cast at the func_80012558 use site is byte-identical.
- Drafted by an isolated agent (Opus 5 @ High, 65k tok) pointed at the NAMED blocker with the
canonical callee sigs supplied — not asked to re-derive the C. It self-verified through the real
cpp->cc1->maspsx->as chain (cc1 rc=0, 123/123 ins, 0 diffs) before reporting, so the bank was
first-try clean.
- make check BINARY=ov_SC07_006 BYTE-IDENTICAL (7ca772be); R22 clean-fleet 140/140, 0 failed.
- Propagation ×138 follows as a separate targeted step (§55b: bank -> commit -> dedup_propagate --addr).
- FOLLOW-UP LOGGED: the recovery ladder also relaxed `extern s32 func_80174CB0(s32,s32)` -> `()` in
src/shared/engine_core.h (+2 overlay files), escalating a binary-local bank to FLEET tier. The
banked def AGREES with the original prototype, so that edit looks unnecessary — to be tested.
Builds the guard SESSION-17 left as a TODO after the func_801463A0 `_s`-alias trap, where a draft
invented extern aliases no symbol table defines, read MATCH under rtu_match, and could never bank.
- diffs the symbols a draft's object references (reloc records) against the target .s's
%hi/%lo/jal set; reports MISSING (invented-alias signature) and INVENTED separately.
- fills a real hole: match_one/masked_diff compare relocation-MASKED words (object-vs-.s is
symbol-agnostic BY CONSTRUCTION) and rtu_match COMPILES WITHOUT LINKING -- so both are
structurally blind to this class. R34: a second oracle that can disagree with the first.
- NEGATIVE-CONTROL PROVEN: with one data extern renamed to an invented alias, match_one reports
the SAME 14 mismatched as the correct draft; symcheck exits 1 naming both symbols.
- --c compiles via match_one so the pinned triple/flags can never drift (R33); or --obj.
- applied to the live func_8014D820 close=14 draft: 12/12 symbols agree, so a match there will
link cleanly -- the §65c class is ruled out for it in advance.
- cookbook §67a + SETUP tooling-inventory row (R21). Necessary condition, NOT a match oracle:
still finish on the whole-binary byte-gate (G3/P9).
- PROBE ANSWERED (the SESSION-17 open item): a0's first use is body-line 41, a1's is 28
-> use order ALREADY matched the target's birth order while birth order was inverted.
The §31 RC-1/RC-2/RC-3 first-use-order hypothesis is REFUTED for this class; decl order
is inert too. Both retired, do not re-buy.
- ROOT CAUSE (byte-read): gcc schedules the arg->pseudo entry copies as ordinary in-block
insns and hoists an unconstrained one to the earliest slot. Mine raced `move $s4,$a0` to
idx 2, which freed $a0 to become the early load temp (target: $v1) and left the target's
idx-12 load-delay slot unfilled. The "wrong temp reg", the mirrored `sw $sN`/`move $sN`
prologue and the +1 instruction were ONE defect in three costumes.
- THE LEVER (cookbook §67, written in-session per R30): an UNPINNED launder
`__asm__ __volatile__("" : "=r"(pv) : "0"(p));` placed at the statement where the target's
copy lands, later uses rewritten to pv. Zero instructions. Prerequisite: collapse redundant
pointer aliases first (the two-pseudo split made gcc serve the first use from the incoming
arg reg). Placement is the knob and is NOT linear -- sweep 3-4 anchors (3-statement plateau).
- 25 -> 16 by reading; permuter_ils (REGALLOC, 10x180s) 16 -> 14 in cycle 1 then x9 unchanged
(§66d-3: a repeat means stop). Its edit is semantics-preserving (hoists desc.y+0x10) and
cleared the idx 271/272 cluster. Seeds tracked: s18_func_8014D820_close{16,14}.c.
- MEASURED NEGATIVES recorded so they are never re-bought: pinning the laundered var to $s4
(pre-stages via $t0, 305 ins); pinning the reused temp t to $3 (287/303); an artificial
"r"(t) dependency (inert -- gcc still hoists); laundering after the beqz (305); dropping the
a2 pin (29); wholesale pos/desc reorder or sinking z0=ent->z (+1 ins).
- NOT banked (G3) -- residual 14 in 2 clusters: idx 21/22 scratch $v1 vs $a0, idx 84-98 the
desc.y/currentLocationId schedule. SCHEDULE-weighted ILS running from the close=14 seed.
- Also measured: func_80140958 260/260 54 - func_80176734 371/371 56 - func_80176218 328 vs
327, whose +1 is NOT §67 (it hoists a global address into an extra callee-saved $s6 that the
target rematerializes -> the §17 array-decay lever).