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).
- Measured locally (no MCP): per-overlay stubs that are substantial AND uncached AND undrafted = what
an import would unlock. Best single overlay 6,062 ins (0.05pp); fleet total 67,116 ins (0.51pp).
- Task 5's greedy cover (+1.59pp for ov_SC06_018) was a snapshot of a CONSUMABLE and has been consumed
by the s14/s15 waves + permuter runs. What remains is overlay-unique tail across 87 overlays, each
needing a server restart + a human /mcp for ~0.01pp.
- Ranked: giants ~+1.3pp (seeds ready) > func_801463A0 ~+0.11pp > the ENTIRE prefetch ~+0.51pp at 87
human-gated imports. The prefetch is now the worst lever on the board.
- R14 on myself: a 3-line ls of two dirs made func_8014032C look never-attempted; the full glob found
6 drafts. The fleet figure (0 cached+never-drafted at live>=100) stands. Same failure as §66c, twice
in one session — prefer the glob over a hand-listed pair.
- Balanced-if diamond and a zero-ins memory barrier both leave it at exactly 100/36, unchanged.
Why: §H kills a fold ACROSS A JOIN; here both uses are adjacent statements in the same basic
block, so there is nowhere for a fresh cse table to start.
- State: a standalone MATCH (101 ins) exists with direct-symbol u16 decls, blocked ONLY by the
canonical "extern u8 D_80126BE0[]" living inside a DEFINE_func_* macro body (engine_core.h:19813).
Exits: (a) demacroize = x1 trap (+101 ins, forfeits x138), (b) change the shared decl = T2 /
§63 disaster class, (c) a C form that keeps u8[] and defeats the address CSE = the open question.
+13,938 ins if (c) lands. Do not re-buy (a) or the two antidotes.
- 3 falsified hypotheses, then MATCH (101 ins) with direct-symbol scalar decls. The length gap was
the target re-materializing "lui $at,%hi(sym)" per scalar store while array/struct forms let gcc
CSE the address into a register (1-ins stores) -> mine was exactly one instruction short.
- Remaining blocker NAMED: the TU's canonical decl is "extern u8 D_80126BE0[]" INSIDE a DEFINE_func_*
macro body (engine_core.h:19813), so the matching u16 form gives conflicting types in the real TU
(real cc1, via rtu_match --stderr-out).
- demacroize would clear it but banks x1 (+101 ins) and forfeits x138 — a trap, not a win. The right
exit is the §H CSE address-fold antidote (balanced if/else diamond, zero asm) so the canonical u8[]
decl stays and the bank propagates x138 (+13,938 ins). Both draft forms preserved.
- rtu MATCH (101 ins) vs gate reject, baseline intact -> divergence had to be in a relocation.
All 9 jal targets agreed; of 15 data symbols the target uses, the draft referenced 14 — missing
exactly D_80126BE8.
- CAUSE: the draft declared D_80126BE0_s / D_80126BE8_s — `_s`-suffixed aliases NO symbol table
defines, invented because D_80126BE0 was already declared at a different type in the same draft.
- MECHANISM CORRECTED (§65c refinement): rtu over-claims not merely because it is relocation-masked
but because it COMPILES WITHOUT LINKING — an unresolvable extern is invisible to it by construction.
Cheap general guard: diff the draft's symbol set against the target .s's %hi/%lo/jal set before
gating (one comm over two greps; found this in seconds).
- FIXED: real symbols referenced, duplicate u8[] decl dropped, store re-expressed via &. Residual is
now an ORDINARY near-miss (100 vs 101 ins, 36 mismatched, regalloc/fold) -> permuter fuel.
Draft preserved at .run/giants/s17_func_801463A0_symfix.c.
- Did it properly: per-TU provided set via cdecl.typedef_names(tu_path) (217/215 names; it takes a
PATH), strip_provided_typedefs dropped 2/2 typedef lines from each draft, then the DRIVER's ladder.
pass 1 banked 0/2; src/ restored exactly.
- The stack: func_80156670 S8 -> B8 -> conflicting types for D_801270A8 (a DATA extern);
func_80174CB0 MATRIX/SVECTOR -> conflicting types for func_80012ABC (a callee conflict
cast_call_sites did not clear). cc1 reveals only the first layer each time (§65).
- NEW STATIC-ORACLE BLIND SPOT (R34 earning its keep): func_80156670's data conflict is CC1-ONLY —
the static oracle says `none` while real cc1 fails. First cc1-only case measured (SESSION-16 was
36/36 agreement). A `static: none` verdict is not evidence a draft is clean.
- Stripped drafts kept at .run/perm_s17j/ so the next attempt starts 3 layers in. ~+0.4pp if solved.
- func_8012B4B8 (84) + func_80169228 (105) propagated via targeted --addr (--check-only first,
never --auto-from): 138 overlays byte-identical, 2 new dedup groups, ~+26,082 ins.
- R22 clean-fleet: check-all 140 passed, 0 failed of 140. Fleet fn-count 88.90 -> 88.98%.
- The 3 non-banks are diagnosed, not guessed (blocker_probe, both oracles agree): func_801463A0 is
a real-cc1 MATCH in its own TU that the gate still rejects (§65c rtu-vs-gate divergence, link-level);
func_80156670/func_80174CB0 carry "drop when banking" typedefs textually identical to the canonical
ones. Blockers STACK — stripping the cc1-named typedef exposed the next (S8->B8; MATRIX->a callee
conflict). Remedy named: strip ALL shared-provided typedefs, then run the DRIVER's ladder.
- Ladder-only recovery (no demacroize, so these are NORMAL banks that can propagate x138):
func_8012B4B8 (84 ins) + func_80169228 (105 ins), both confirmed gone from src, not read off
the report (§55b trap 4). 2 of 5 candidates.
- DRIFT-CHECK EARNED ITS KEEP (R14): the backlog's close=0 was wrong for 2 of the 7 spine entries —
func_8012CC88's draft is for ov_SC07_006 and is 13 off in ov_SC01_077 (the documented
'backlog drafts are overlay-specific' caveat, now confirmed), func_80158638 is 2 off, not 0.
- The cross-file churn is gate_stage's own fix_arity_callers --any-proto pass on the banked fns'
caller decls (byte-neutral no-proto widening; comments preserved, H5). R22 clean-fleet 140/140.
- Diagnosed the 3 non-banks with blocker_probe (both oracles agree 3/3): func_801463A0 = real-cc1
MATCH in its own TU yet gate-rejected (the §65c rtu-vs-gate divergence); func_80156670 and
func_80174CB0 = local_type collisions on 'S8' and 'MATRIX' -> uniquify (T0, draft-only).
- Stale spine claimed 223 live stubs / 870,668 ins and ranked 3 already-banked fns in its top 7
(func_801325B8, func_8014ADE0, func_8012CC88-in-077 verified 0-live in src).
- TRUE state: 160 live stubs / 583,077 ins remaining gain.
- SHARP EDGE (R35): worklist.py --assert-partition exits at the assertion and does NOT rewrite the
doc, so 'regenerating' with it leaves the stale file in place and still exits 0. Run it bare to write.
- func_80176734: 76 -> 57 in cycle 1, then flat x9 (converged). Completes the queue.
- Seeds TRACKED at .run/giants/s17_*.c — the allowlist covers .run/giants/*.c but NOT subdirectories,
so they go at the top level (the R20 trap: a subdir would have left them untracked and one
git clean from gone).
- Queue state: 80177940 BANKED x138 | 8014D820 25 (toolkit exhausted -> Fable5) | 80140958 56 |
80176734 57 | 80176218 271 (never run). ~+1.3pp instr if the four crack.
barrier-on-a1 25 (inert) | barrier-on-a2 25 (inert) | param-staging via pinned $s3/$s4 35 | staging+barrier 34.
Staging DID fix the register assignment (loads via $v1 like the target) while shuffling birth order, so
the two are separately steerable and no tried combination gets both. Residual reproduced independently:
gcc copy-propagates the $a3 pin, so mine loads through incoming regs where the target uses the copies.
Per-cycle 80/75/72/69/64/62/60/59, monotone, never repeating. The readable signal: a repeated best
score means DONE (func_8014D820: 25 x7 -> reader/Fable5); a still-falling last cycle means
BUDGET-LIMITED (buy more cycles, it is CPU not tokens). Read the series, not the final number.
- permuter_ils from the 27-waypoint: 27 -> 25 in cycle 1, then UNCHANGED for 7 cycles.
- Residual read: target emits $s3<-a1 first, $s4<-a0 twelfth; mine the reverse. Same mapping,
swapped BIRTH ORDER, cascading into prologue save order + load base regs. §17 register-ORDER class.
- A one-line scheduling barrier on a1 (after the decl block; before it is a C89 error) changed
NOTHING. Corroborates the drafting agent's swept-pins note. Seeds carried; do not re-spend CPU.
func_80177940 was structural(OPCODE-MIXED) at close=5 and the permuter still took it 5->1: the class
names only the DOMINANT residual. Policy: at low closeness run the search anyway (CPU, not tokens);
at high closeness read first.
- The two halves of a 'not steerable from source order' note belong to different tools: the permuter
closes INSN_LUID scheduler ties a hand sweep provably cannot enumerate; the reader closes semantic
fixes the mutation set cannot invent. residual_class's bucket ([permuter] vs [structural]), already
printed by match_one, is the free handoff signal; its profile feeds p16_permute --klass verbatim.
- Diagnose from a byte-verified SIBLING, and test the naive reading first: deleting the redundant mask
alone COLLAPSED the copy (100 vs 101 ins), which is what proved a distinct PINNED register was needed.
- §66d-1: the LOOP transfers between giants, the PIN does not (the same move cost func_8014D820
285 mismatched). §66d-2: setup() wipes the scratch dir; the cleanup pkill was global.
- Targeted `dedup_propagate --addr 0x80177940 --recover` (NEVER --auto-from; --check-only first
confirmed the plan held exactly this one address, so the de-macroize hazard could not apply).
- 138 overlays rebuilt byte-identical; 0 stubs remain for the address; 1 new dedup group registered.
- R22 clean-fleet: check-all 140 passed, 0 failed of 140.
- Fleet: fn-count 88.86 -> 88.90%, instr-weighted 79.6 -> 79.7% (+13,938 ins = 101 x 138),
distinct-code 64,874 -> 64,875 unique fns.
- The loop: permuter (§31 schedule, 900s -j12) 5 -> 1, closing the 4-ins INSN_LUID scheduler tie the
drafting agent had swept by hand and recorded as un-steerable; read the last instruction (andi vs
addu); fixed it from the byte-verified sibling func_801778A8's pinned plain-copy idiom; permuter
again from the corrected seed (cse profile, 1800s) -> MATCH.
- The diagnosis was byte-driven, not guessed: dropping the redundant & 0xf alone COLLAPSED the copy
(100 vs 101 ins, 52 mismatched), proving the target needs a distinct PINNED register.
- GATE: harvest_verify --chunk 1 -> verified 1 / failed 0, d19c9580 BYTE-IDENTICAL; stub gone from
source (checked by grep, not the report). R22 clean-fleet: check-all 140 passed, 0 failed of 140.
- NEGATIVE recorded: the pin does NOT transfer to func_8014D820 (pinning its temp t to $v1 -> 285
mismatched, 303 vs 304 ins). Its run improved 33 -> 27 and plateaued; seed kept for ILS.
- REFUTES the .run/giants README's "pycparser/permuter CANNOT ingest it as-is": p16_permute.setup's
b64-pragma pin carrier handles it (6 pins -> 6 carriers, 0 raw __asm__, target.o built, §31 profile).
Checked against the tool, not the note (R35) — the 3rd recorded wall this session to dissolve.
- Drift-check first (R14): all preserved drafts reproduce their recorded closeness exactly (5/33/76/116).
func_801670E4 (close=16) is ALREADY BANKED fleet-wide — the README is stale; it is not work.
- 900s @ -j12: 5 -> 1. The permuter closed the 4-ins INSN_LUID scheduler tie the drafting agent had
recorded as un-steerable after sweeping all 6 assign orders + pin combos by hand.
- Last instruction (andi vs addu) diagnosed from the byte-verified sibling func_801778A8, whose
"nib = uVar1;" plain-copy idiom (both vars hard-pinned) after the identical (x << 16) >> 28 shift
pair is what materializes the addu. Dropping my redundant & 0xf alone COLLAPSES the copy (100 vs
101 ins, 52 mismatched), so the target needs a distinct pinned register. Pinning n to $a2 ->
101/101 with 6 left, class ADDRESSING [permuter] -> handed back to the permuter from the
structurally-correct seed rather than hand-designed.
- FIX: run_permuter's cleanup pkill matched EVERY concurrent run (two permuters silently killed each
other); scoped to the run's own scratch dir -> concurrent giant grinding is now safe.
The exclusion set built from the backlog alone missed .run/giants/ (false work: ~2.6M tokens of
characterized permuter-only drafts would have been re-bought); corrected to scan .run/**/func_*.c it
swept in the Ghidra-C INPUT cache (false exhaustion: 5,488 phantom attempts). Records the query that
actually answers 'is there fuel' and the structural point that high-reach fuel is CREATED by a
per-overlay Ghidra-C prefetch, not found.
- build_wave_args --min-live 100: ov_SC07_006 37 candidates / 0 fresh; ov_SC06_018 163 / 33 fresh,
all reach-1. Fleet-wide (139 binaries, 983 cached Ghidra-C): cached & live>=100 = 141 -> 111 gated,
30 with a preserved draft, 0 never attempted. Only fresh cached fuel anywhere = 40 fns at live 1-4.
- So the queue's '6 drafters -> ~3 banks x138' economics have no fuel. Fresh high-reach fuel is
CREATED by a per-overlay Ghidra-C prefetch (Task 5's greedy cover, imports 2-8 = +0.59pp), which
needs an MCP restart + Drew running /mcp (R23/R29).
- TWO selection bugs in my own filter, caught before spending: (1) the exclusion set missed
.run/giants/ (would have re-bought ~2.6M tokens of characterized permuter-only work); (2) it then
counted .run/ghidra_c/*.c -- the Ghidra INPUT -- as drafts, making every pool read 'exhausted'.
- Nothing spent; no agents launched.
- THE FREE TEST (cookbook §66): reverted func_801778A8's bank to its INCLUDE_ASM stub (stub state
rebuilds BYTE-IDENTICAL 7ca772be — a faithful revert proves itself; needs `make extract` first,
the R22 corollary) and re-banked it THROUGH recover_integration.py --commit --r22.
pass1 1/1 -> exact restore -> pass2 1/1 -> commit commit:0928 -> R22 140/140 -> report.json.
Bank confirmed from SOURCE (stub gone), never the report (§55b trap 4). EQUIVALENCE: git diff vs
the pre-revert commit = ONE blank line (mine) -> the driver reproduced SESSION-16's state exactly.
- DEFECT 1 (SAFETY, found by reading before firing): PROPAGATION is a fleet-tier write
(dedup_propagate --auto-from -> src/shared/engine_core.h + up to 138 overlay .c) that was both
UNDECLARED and the DEFAULT, so --max-tier binary still permitted the widest write in the toolchain.
assert_write_set cannot catch it (it runs before the gate; under --commit git status is clean).
FIXED up front: propagate now requires --max-tier fleet AND --r22, and is REFUSED after a
demacroize stage (those banks are x1 by construction; --auto-from would re-macroize and undo them).
Both refusals negative-control-tested, exit 1. The "standing hazard" is now a refusal.
- DEFECT 2 (METRIC): gate_stage scraped the fleet % via a progress.py label that no longer exists ->
fp=None -> 50 gate commits recorded "fleet None%". Now reads FLEET instr-weighted (legacy fallback
+ loud stderr warning if neither matches); parses 79.6.
- STALE DIGEST (R14): docs/progress.fleet.md at HEAD disagreed with HEAD's own source by 45 in the
dedup-shared column — generated during the §65g local_type trial whose edits were then reverted.
Regenerated (reproduced identically in-gate + standalone); headline %s unaffected.
- cookbook §66/§66a/§66b distilled in-session (R30); SETUP.md gains the missing recover_integration
row (R21 debt). tools-health OK: corpus 0/0, cdecl green, audit-binaries 140 citizens, lint OK,
dedup-check 1879/0. Fleet unchanged 79.6% instr / 67.7% distinct / 88.86% fn-count.