From 034c46bc283e227ac84822896de0b90d6c491e1d Mon Sep 17 00:00:00 2001 From: Drew T <50529377+Druthulu@users.noreply.github.com> Date: Mon, 17 Aug 2026 10:14:41 -0600 Subject: [PATCH] =?UTF-8?q?chore(phase-31):=20S53=20checkpoint=20rewritten?= =?UTF-8?q?=20as=20a=20clean=20fresh-session=20handoff=20(161=20banked,=20?= =?UTF-8?q?main=2020.4%,=20=C2=A7188=20correction,=205-step=20next-session?= =?UTF-8?q?=20plan)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/progress.md | 16 ++-- phase-ends/CURRENT_PHASE.md | 172 +++++++++++++++++++----------------- 2 files changed, 98 insertions(+), 90 deletions(-) diff --git a/docs/progress.md b/docs/progress.md index 417ddf8677..1f67afe47e 100644 --- a/docs/progress.md +++ b/docs/progress.md @@ -1,19 +1,19 @@ # BFM matching progress (generated by tools/progress.py — authoritative) -REAL substantive matches : 175 <- the Gen1-exit >=25 bar counts THIS +REAL substantive matches : 328 <- the Gen1-exit >=25 bar counts THIS (of which dedup-shared : 2 one body -> N sites, config/dedup.us.yaml) LINKED real PsyQ objects : 959 <- byte-identical via linked SDK objects -NON_MATCHING (near-miss) : 7 +NON_MATCHING (near-miss) : 4 splat-auto empty no-ops : 42 -INCLUDE_ASM stubs : 913 +INCLUDE_ASM stubs : 749 data blobs (excluded) : 2 ---------------------------------------- -matchable functions : 2096 -REAL / matchable : 175 / 2096 = 8.35% -byte-identical/ matchable: 1176 / 2096 = 56.11% (REAL+LINKED+empties) +matchable functions : 2082 +REAL / matchable : 328 / 2082 = 15.75% +byte-identical/ matchable: 1329 / 2082 = 63.83% (REAL+LINKED+empties) LINKED subsegs: apicard1 apicard2 apicard3 apicard4 libc2_1 libc2_2 libcd1 libcd2 libetc libgpu libgs1 libgs2 libgs3 libgs4 libgs5 libgs6 libgte1 libgte10 libgte11 libgte12 libgte13 libgte14 libgte15 libgte16 libgte17 libgte18 libgte19 libgte2 libgte20 libgte21 libgte22 libgte3 libgte4 libgte5 libgte6 libgte7 libgte8 libgte9 libmcrd1 libmcrd2 snd1 snd2 snd3 snd4 snd5 snd6 snd7 snd8 snd9 (959 fns) -REAL matches: CdQueueBusy CdReadRequest DebugMenuHandler GameModeDispatch LoaderResetReadState LzssDecodeSector ResourceGetCdLoc func_8001099C func_800128B4 func_80012AB0 func_80013200 func_80013228 func_800132BC func_80013328 func_80013350 func_800133BC func_800133E4 func_80013450 func_80013F3C func_80013F68 func_80014168 func_800141F0 func_800142C8 func_80014338 func_80014774 func_80014928 func_80014960 func_80014BFC func_80014C28 func_80014CF8 func_80014D68 func_80014D94 func_80014DC0 func_80014E80 func_800153A4 func_80015424 func_800166E8 func_800167B8 func_800168B4 func_80016940 func_80017D98 func_80017DF8 func_80017E30 func_80018F20 func_80019018 func_8001903C func_80019198 func_80019378 func_80019388 func_80019398 func_800193A8 func_8001AA78 func_8001AA88 func_8001AAA0 func_8001AF04 func_8001B22C func_8001B23C func_8001B324 func_8001B34C func_8001B374 func_8001B384 func_8001B394 func_8001B85C func_8001BA84 func_8001BE20 func_8001BFA0 func_8001BFE8 func_8001C00C func_8001C1E4 func_8001C2C4 func_8001C448 func_8001C558 func_8001C924 func_8001CB00 func_8001CBDC func_8001CC3C func_8001CCA0 func_8001CD04 func_8001CD50 func_8001CD9C func_8001CDE8 func_8001CE28 func_8001CE68 func_8001CEC0 func_8001CF00 func_8001D0E8 func_80021008 func_80021050 func_80021120 func_80028200 func_80028428 func_80028558 func_800285CC func_80029044 func_8002906C func_80029094 func_80029218 func_80029254 func_80029264 func_8002931C func_8002941C func_80029504 func_80029514 func_8002953C func_8002954C func_8002957C func_8002958C func_8002959C func_80029664 func_80029AF4 func_80029CD4 func_80029E30 func_80029FD4 func_8002A04C func_8002A1B4 func_8002A200 func_8002A234 func_8002A26C func_8002A27C func_8002A400 func_8002A44C func_8002A480 func_8002A4B8 func_8002A4C8 func_8002A670 func_8002A6BC func_8002A6F0 func_8002A728 func_8002A738 func_8002A8E0 func_8002A92C func_8002A960 func_8002A998 func_8002A9A8 func_8002AEF8 func_8002AF08 func_8002AF18 func_8002AF60 func_8002B00C func_8002B064 func_8002B08C func_8002C8BC func_8002D240 func_8002D4B8 func_8002D7FC func_8002D834 func_8002EAB0 func_8002EBAC func_8002ED90 func_8002EE90 func_8002EFD0 func_8002EFF8 func_8002F064 func_8002F0F4 func_8002F620 func_8002F648 func_8002FAE0 func_80031B7C func_80034844 func_80034A54 func_80034AE0 func_80034B0C func_80035210 func_8003621C func_80036EB4 func_80036EE8 func_80037004 func_80037334 func_80037358 func_80037368 func_80037CC8 func_800381E4 func_8003836C func_80038638 func_80038A00 -NON_MATCHING: CdReadSectorReadyCB CdReadStateMachine LoaderInitFileTable ResourceLoadStateMachine StreamLoadStateMachine func_80015A74 func_80016714 +REAL matches: CdQueueBusy CdReadRequest ClearOTag DebugMenuHandler GameModeDispatch GsTMDfastF3GL GsTMDfastF4GL GsTMDfastG3GL GsTMDfastG4GL LoaderResetReadState LzssDecodeSector MoveImage ResourceGetCdLoc SetGraphQueue SetRCnt func_8001099C func_80010F80 func_800128B4 func_800129CC func_80012AB0 func_80013200 func_80013228 func_80013294 func_800132BC func_80013328 func_80013350 func_800133BC func_800133E4 func_80013450 func_80013F3C func_80013F68 func_80014168 func_800141F0 func_800142C8 func_80014338 func_800143AC func_80014444 func_80014774 func_800147B8 func_80014928 func_80014960 func_800149E0 func_80014B10 func_80014BFC func_80014C28 func_80014CF8 func_80014D30 func_80014D68 func_80014D94 func_80014DC0 func_80014DEC func_80014E24 func_80014E80 func_80014ED4 func_80015018 func_80015144 func_80015208 func_800153A4 func_80015424 func_80015498 func_80015D4C func_80015F04 func_80016110 func_80016450 func_80016638 func_800166E8 func_800167B8 func_800168B4 func_80016940 func_80016B60 func_80016C28 func_80016D78 func_80016F18 func_80017294 func_80017778 func_80017930 func_80017B98 func_80017D98 func_80017DF8 func_80017E30 func_80018094 func_800184F0 func_80018A20 func_80018CE8 func_80018F20 func_80019018 func_8001903C func_800190AC func_80019198 func_8001923C func_80019378 func_80019388 func_80019398 func_800193A8 func_800193B8 func_8001AA78 func_8001AA88 func_8001AAA0 func_8001ABBC func_8001ACF0 func_8001AF04 func_8001B22C func_8001B23C func_8001B26C func_8001B324 func_8001B34C func_8001B374 func_8001B384 func_8001B394 func_8001B7C4 func_8001B85C func_8001B86C func_8001BA84 func_8001BBBC func_8001BE20 func_8001BE30 func_8001BFA0 func_8001BFE8 func_8001C00C func_8001C1E4 func_8001C2C4 func_8001C448 func_8001C558 func_8001C6E4 func_8001C744 func_8001C7B0 func_8001C8C4 func_8001C924 func_8001C97C func_8001CA1C func_8001CB00 func_8001CBDC func_8001CC3C func_8001CCA0 func_8001CD04 func_8001CD50 func_8001CD9C func_8001CDE8 func_8001CE28 func_8001CE68 func_8001CEC0 func_8001CF00 func_8001D0E8 func_8001D3FC func_8001D8C4 func_8001E094 func_8001E668 func_8001E7E0 func_8001F730 func_80020248 func_80020F34 func_80021008 func_80021050 func_80021120 func_80023138 func_800233CC func_80023570 func_80024BC0 func_80024DE8 func_80025000 func_8002528C func_80025504 func_80025818 func_80025A30 func_80025CBC func_80025EB8 func_800262D8 func_80027200 func_800275BC func_800277DC func_800279AC func_80027C10 func_80027D20 func_80027F4C func_80028200 func_80028394 func_80028428 func_80028558 func_800285CC func_80028A48 func_80028C50 func_80029044 func_8002906C func_80029094 func_80029218 func_80029254 func_80029264 func_80029274 func_8002931C func_8002941C func_80029504 func_80029514 func_8002953C func_8002954C func_8002957C func_8002958C func_8002959C func_800295D4 func_80029664 func_80029AF4 func_80029CD4 func_80029E30 func_80029ED4 func_80029FD4 func_8002A04C func_8002A1B4 func_8002A200 func_8002A234 func_8002A26C func_8002A27C func_8002A400 func_8002A44C func_8002A480 func_8002A4B8 func_8002A4C8 func_8002A670 func_8002A6BC func_8002A6F0 func_8002A728 func_8002A738 func_8002A8E0 func_8002A92C func_8002A960 func_8002A998 func_8002A9A8 func_8002AAB4 func_8002AC00 func_8002AEF8 func_8002AF08 func_8002AF18 func_8002AF60 func_8002AF70 func_8002B00C func_8002B064 func_8002B08C func_8002C320 func_8002C8BC func_8002C8F4 func_8002CDD8 func_8002D034 func_8002D1F0 func_8002D240 func_8002D4B8 func_8002D6D8 func_8002D7FC func_8002D834 func_8002DF80 func_8002E638 func_8002E700 func_8002EAB0 func_8002EBAC func_8002EC10 func_8002ED90 func_8002EE90 func_8002EFD0 func_8002EFF8 func_8002F064 func_8002F0F4 func_8002F4E4 func_8002F620 func_8002F648 func_8002F67C func_8002F714 func_8002FAE0 func_8002FB08 func_8002FC64 func_8002FD14 func_80030730 func_80030A14 func_80030D80 func_800314DC func_80031B7C func_80031BE0 func_80032048 func_800322A8 func_800324A4 func_80032774 func_8003324C func_80033398 func_800335B8 func_800336A8 func_80034314 func_80034844 func_80034A54 func_80034A9C func_80034AE0 func_80034B0C func_80034C24 func_80034CF0 func_8003500C func_80035210 func_80036130 func_8003621C func_80036EB4 func_80036EE8 func_80037004 func_80037028 func_80037144 func_80037334 func_80037358 func_80037368 func_800373D0 func_8003750C func_80037CC8 func_80037CD8 func_80037D98 func_800381E4 func_80038210 func_8003836C func_80038638 func_80038668 func_80038838 func_80038958 func_80038A00 func_8003A234 func_80052654 func_8005283C func_80059658 func_80059BFC func_8005AE80 func_8005B7B0 func_8005BA90 func_8005D184 func_8005E0AC func_8005E528 func_8005E820 func_8005F75C func_8005FBC8 +NON_MATCHING: CdReadSectorReadyCB CdReadStateMachine StreamLoadStateMachine func_80015A74 build SHA1: 143dbb89f34491258bbc27810d0a12ec8b43a8dd (byte-identical) diff --git a/phase-ends/CURRENT_PHASE.md b/phase-ends/CURRENT_PHASE.md index 68b5f8d922..1fab0c36cd 100644 --- a/phase-ends/CURRENT_PHASE.md +++ b/phase-ends/CURRENT_PHASE.md @@ -146,98 +146,106 @@ R22 clean-fleet **213/213** after every banked batch · tools-health green · 0 ## 🛑 SESSION CHECKPOINT — S53 FINAL (2026-08-16/17). Phase 31 CONTINUES. NOTHING IN FLIGHT. -**Tree CLEAN. R22 `check-all` 213 passed / 0 failed of 213 from a clean tree. EXE `143dbb89`.** +**HEAD `commit:2453`+ · tree clean except Ghidra `db.*.gbf` restart-noise (R23: do NOT stage) · +R22 `make check-all` = 213 passed / 0 failed of 213 from a clean tree · EXE `143dbb89` · 0 NON_MATCHING.** +No process running, no cron armed, no workflow in flight. 39 commits this session; Drew pushes. ### Banked this session: 161 functions -| lane | banked | -|---|--:| -| wave R — mass (ov_SC06_029 36, ov_SC02_005 21, main 18) | 75 | -| wave S — mass (ov_SC04_011 30, ov_SC03_028 33) | 63 | -| the 27-draft recovery backlog (incl. 2 fragment merges) | 23 | -**main stubs 1,763 → 1,714.** Fleet: instr-weighted **95.6%**, distinct-code **90.8%** (was 90.7%), -fn-count 96.92%. 0 NON_MATCHING. 32 commits. +| lane | banked | notes | +|---|--:|---| +| wave R — mass band | 75 | ov_SC06_029 36 · ov_SC02_005 21 · main 18 | +| wave S — mass band | 63 | ov_SC04_011 30 of 45 · ov_SC03_028 33 of 34 | +| the 27-draft recovery backlog | 23 | incl. 2 real fragment merges | -### Draft rates: the drafting problem is closed -Wave R **92/110 (84%)** — mass 93%, plumbing 95%, near-miss 25%. Wave S **70/71 (99%)**, 82 agents, -0 errors. The §181 census stands: of 27 rejected drafts, **26 were byte-correct** and rejected on -plumbing alone. Every hour spent making the integration layer COMPUTE a refusal outranks an hour of -drafting. +**main stubs 1,763 → 1,714** · **MAIN game-code weighted 17.4% → 20.4%** · fleet instr-weighted +**95.6%**, distinct-code **90.8%** (was 90.7%), fn-count 96.92%. +Remaining stubs in the four worked overlays: ov_SC02_005 315 · ov_SC04_011 199 · ov_SC03_028 161 · +ov_SC06_029 134. -### Two real fragment merges banked (§181's class, solved) -* `func_8005B7B0` absorbs **five** splat-carved fragments (184 ins) — a PsyQ queue-push routine whose - wait-loop test, copy loop, shared tail and epilogue were each named as separate symbols. -* `MoveImage` absorbs `SYS_OBJ_8F4`, which was literally its own epilogue (popping a frame it never - allocated). -Both agents built a SYNTHETIC MERGED `.s` (fragments concatenated in address order) and ran the real -`match_one` against it, because the tool cannot verify a merged body otherwise. That trick is the -reusable part. - -### 🔴 THE LIBGS LINK OPPORTUNITY IS REFUTED (§187) — and I reported it wrong first -An agent found `src/800b_7.c` is `GsSortBg`/`GsSortFastBg` = PsyQ `2D_BG0.o`/`2D_BG1.o` and proposed -linking all 1,022 instructions free. My "independent" confirmation excused any word CARRYING a -relocation — as permissive as the agent's own check, so it corroborated nothing. Under the strict mask -(only the relocated FIELD may differ) the object is **520 instructions where the region is 526**, with -a one-instruction shift around COP2 words: **the game's build carries six extra GTE hazard nops.** -Same source, different assembly; `psyq_identify` was right to refuse. Reverted; build re-verified. -**Those 8 symbols stay decompilation work.** +### THE FOUR RESULTS THAT OUTLIVE THE COUNT +1. **DRAFTING IS SOLVED AT THIS SCALE; INTEGRATION IS THE ENTIRE COST.** Wave R drafted 84%, **wave S + 70/71 = 99%** (82 agents, 0 errors). Of 27 gate-rejected main drafts, **26 were byte-correct** and + rejected purely on declaration plumbing (§181 census). Three independent measurements now agree + (§180b's cold pile 11/32, wave P's 97%→68%, this census). **Budget for banking, not cracking; an + hour spent making the integration layer COMPUTE a refusal outranks an hour of drafting.** +2. **§188 — THE `jr $ra` + `addiu $sp` EPILOGUE TAIL IS AN ASSEMBLER ARTIFACT, NOT CODEGEN.** GNU + `as -O2` fills the return delay slot; cc1 CANNOT emit that shape for any `$s`-saving frame + (`mips.c:5081/5174/5204`). This **corrects §177's row 2 in place** (banner added), **answers §182's + open question**, and explains why that lane converted 4 of 16. `tools/oracle_reorder.py` now + separates a C defect from an assembler artifact in one 2×2 — a 0 in the bypass+`as -O2` cell means + the draft is already right and grinding is futile. **Six functions in that band are prebuilt SDK + objects** (libpad `pdent3/4/5`, `pdmain1`, `pdmaiini`, libapi `first.o`) → `psyq_integrate`. +3. **§187 — THE libgs SHORTCUT IS REFUTED, AND THE LESSON IS ABOUT THE ORACLE.** `src/800b_7.c` really + is `GsSortBg`/`GsSortFastBg` = `2D_BG0.o`/`2D_BG1.o`, but the game's build carries **six extra GTE + hazard nops**: 520 object instructions vs a 526-instruction region. Two checks (the agent's and my + own) called it a match because both excused a whole word whenever it carried a relocation. **A mask + coarser than the linker's is not weak evidence, it is no evidence**, and agreement between two loose + checks is not corroboration (R34). Reverted; those 8 symbols stay decomp work. +4. **COMMENT-BLINDNESS WAS A DEFECT CLASS, NOT A BUG (§184).** Three tools were comparing C text + without masking comments, so identical layouts read as DIFFERENT-STRUCT because agents annotate + fields and the TU does not — each silently refusing byte-verified work. Related: `scan_leftovers.py` + found **37 byte-perfect, still-stubbed drafts (3,240 ins) on its first run** — a wave targets ~6,500 + ins, so sweep `.run/` before spending a token on new cards (§180). ### Tooling shipped this session (all negative-controlled) -`scan_leftovers.py` **NEW** (found 37 unbanked byte-perfect drafts on the first run) · -`fragment_check.branched_into` **NEW** (the mirror trap; 5.7% of main stubs carry it, 0% in the wave-S -overlays) · `gate_main`: typedef HOIST above the include block (byte-neutral, SHA-proven), comment-blind -typedef comparison FIXED, FORWARD-typedef recognized instead of renamed · `pregate_check`: masked-text -scan, ANY return-type disagreement now FAILs, brace-bodied externs now visible · `reconcile_slate`: -comment-blind struct comparison FIXED. +**NEW** `scan_leftovers.py` (re-verify unbanked drafts; the `.s`-existence oracle) · +**NEW** `fragment_check.branched_into` (the MIRROR trap: a sibling branches INTO your range; 5.7% of +main stubs, 0% in the wave-S overlays) · **NEW** `tools/oracle_reorder.py` (§188's diagnostic) · +`gate_main`: typedef **HOIST** above the include block (byte-neutral, SHA-proven) + comment-blind +comparison fixed + FORWARD typedef stripped instead of renamed · `pregate_check`: masked-text scan + +ANY return-type disagreement now FAILs + brace-bodied externs visible · `reconcile_slate`: +comment-blind struct comparison fixed. -### Cookbook: §180–§191 (24 entries) -§180/b/c/d leftover harvest + ladder composition + mass-band exhaustion + the pgrep bracket limit · -§181 the gate's rejection census (26 of 27 rejects byte-correct) + the mirror-fragment class · -§182 §177's honest negative **(now ANSWERED by §188)** · §183 the declaration-reconciliation playbook -(the name/shape trap; why `&D_x` defeats the cast escape) · §184/b comment-blindness as a DEFECT CLASS -(3 tools) + the forward typedef · §185/b verify-the-cheap-side + check a TU retype at its USE SITES · -§186/b/c cross-jumping runs after sched2 + the s16-locals frame signal + local_alloc-vs-global_alloc as -a placement lever · §187 the libgs link REFUTED (GTE hazard nops; a mask coarser than the linker's is -no evidence) · **§188 the `jr $ra`+`addiu $sp` tail is an ASSEMBLER artifact — corrects §177 row 2, -answers §182, and names 6 SDK objects in the band** · §189 five source-cited compiler laws (split-constant -LUID adjacency · self-accumulate operand order fixed at expansion · the bb0 re-tie needs a `memory` -clobber · narrow params are born into TWO pseudos · the compare-constant row flip) · §190 three -prescriptions (preheader strata · natural-order-first with the rigidity plateau · the sched2 arg fence) · -§191 what the harvest REJECTED. - -### The S53 journal harvest (do not redo it) -10 readers over **247 wave-R/S verdicts**, then one adversarial verifier per candidate defaulting to -REJECT: 18 candidates → **10 CONFIRMED, 4 WEAK, 4 REJECTED** (`.run/s53_harvest.json`). Verifiers -rebuilt targets from the ROM where the `.s` had been pruned, re-ran A/B sweeps rather than trusting the -readers, and caught a wrong mechanism comment in `src/800.c:5430`. §177 was corrected IN PLACE with a -banner, `tools/oracle_reorder.py` was promoted out of gitignored scratch (a cookbook section may not -cite evidence that evaporates), and the reusable wave prompt's law 6 was corrected so the next wave is -not aimed at the wrong layer. +### Cookbook: §180–§191 (24 entries) — see the section list in the S53 progress-log entries above +The **S53 journal harvest is DONE — do not redo it**: 10 readers over 247 wave-R/S verdicts, one +adversarial verifier per candidate defaulting to REJECT → **10 CONFIRMED / 4 WEAK / 4 REJECTED** +(`.run/s53_harvest.json`; §191 records the rejects). Verifiers rebuilt targets from the ROM where the +`.s` was pruned on bank, re-ran their own A/B sweeps, and caught a wrong mechanism comment at +`src/800.c:5430`. ### NEXT SESSION — in order -1. **Wave T.** Same recipe: `build_wave_atlas --target-ins 6500 --min-ins 60 --max-ins 200 --rank mass` - (fleet-wide, NOT `--only-bins main` — main's mass band is spent, §180c). Regenerate the atlas first - (`make atlas`); it now predates 161 banks. -2. **The 15 wave-S rejects in `ov_SC04_011`** — that overlay's declaration landscape is the known - hostile one (6/10 failed there in wave O too). Run the §183 playbook lane on them; wave R's - equivalent converted 20/21. -3. **`func_80031A98`** — the one honest wall: an agent PROVED with a minimal cc1 repro that the - block-scope `extern s16 D_800C5328[][2];` is a hard error against the file-scope flat decl, and all - three escapes lose the match. Unblocking = retype 7 declarations + 4 banked assignments, then - re-verify those functions' bytes. -4. **`GsSortBg` / `GsSortFastBg` fragment merges** (6 symbols / 526 ins and 2 symbols / 496 ins) — the - merged drafts exist at `.run/final10/main/gfx2D_BG0_OBJ_4D8.c` (526/526 ins, 260 mismatched) and the - boundary map is in the wave-R/final-10 verdicts. Now that §187 removes the link shortcut, these are - the honest route. -5. `func_80186020` (closeness 5) — grinder/permuter fuel, NOT a hand-lever target: it survived ~900 - compiles across 11 sweeps of a fully-understood allocator tie-break (§186c). +1. **Wave T.** `make atlas` FIRST (it predates 161 banks), then + `build_wave_atlas --target-ins 6500 --min-ins 60 --max-ins 200 --rank mass` **fleet-wide** — NOT + `--only-bins main`, whose mass band is spent (§180c). Then the pre-gate ladder BEFORE the first + rebuild: `reconcile_slate --apply` → `fragment_check` → `pregate_check` → `gate_main` dry-run until + `N -> N compatible, 0 dropped`. Gate with `bisect_slate.py`, never `gate_main --apply` without + `--no-bisect`. Overlays: convert slates to `gate_lane` shape first (it needs `binary` + `name`). +2. **The 6 SDK objects from §188 Law 3** → `psyq_integrate`. Cheapest instructions on the board, and + the identification came FROM the strict oracle (unlike §187's refuted claim). Verify with + `psyq_identify` + a clean rebuild. +3. **The 15 wave-S rejects in `ov_SC04_011`.** That overlay's declaration landscape is the known + hostile one (6/10 also failed there in wave O). Run the §183 playbook lane; wave R's equivalent + converted 20 of 21. +4. **`GsSortBg` / `GsSortFastBg` fragment merges** (6 symbols / 526 ins; 2 symbols / 496 ins). §187 + removed the link shortcut, so this is the honest route. A merged draft exists at + `.run/final10/main/gfx2D_BG0_OBJ_4D8.c` (526/526 ins, 260 mismatched) with the full boundary map in + the final-10 verdicts. **Merge recipe that worked twice this session:** build a synthetic merged `.s` + (fragments concatenated in address order, interior `j ` rewritten to `j .L`), verify + with `match_one` against THAT, then hand-substitute the body at the entry symbol's INCLUDE_ASM line + and delete the other fragments' lines — the whole-binary rebuild is the real oracle. +5. **Do NOT re-run the §177 epilogue lane** (§182/§188). Use `oracle_reorder.py` to file the + assembler-artifact cases IMMOVABLE instead of drafting them. -### Watch-fors (new this session) -The `pgrep` bracket trick protects only the PATTERN — a waiter whose command line names the file -elsewhere never exits (§180d). · `gate_main --apply` reports BANKED but VERIFY `corpus.stubs()` dropped -before committing. · `gate_lane` needs `binary` + `name` on every slate record; `scan_leftovers` does not -emit them. · `tools/make_libgs.sh` is not executable — invoke it as `bash tools/make_libgs.sh`. · -`psyq_link_region.py --verify` inside `make_libgs.sh` is STALE (missing the Phase-9-required -`--vram-base`/`--exe`). +### Known-open items +* `func_80031A98` — the one honest wall. An agent PROVED with a minimal cc1 repro that the block-scope + `extern s16 D_800C5328[][2];` is a hard error against the file-scope flat decl, and all three escapes + (local 2-D pointer, inline cast, TU retype) fail. Unblock cost: retype 7 declarations + 4 banked + assignments in `func_80030A14`/`func_8003750C`, then re-verify THEIR bytes. +* `func_80186020` (closeness 5) — grinder/permuter fuel, NOT a hand-lever target: survived ~900 compiles + across 11 sweeps of a fully-understood `global.c:allocno_compare` tie-break (§186c). +* The AGREE re-gate lane stays CLOSED (measured 5%, S52). Do not reopen. + +### Watch-fors +* The `pgrep` bracket trick protects only the PATTERN — a waiter whose command line names the file + elsewhere (e.g. in a `tail`) never exits (§180d). Cost this session: a 46-min loop on a finished job. +* `gate_main --apply` prints BANKED — **verify `corpus.stubs()` actually dropped before committing.** +* `corpus.stubs()` refuses (correctly) when a binary's `.s` files are missing: after `make clean`, only + the binaries you re-extracted can be queried. `make extract-all` restores the fleet. +* `tools/make_libgs.sh` is not executable — run it as `bash tools/make_libgs.sh`. +* `psyq_link_region.py --verify` inside `make_libgs.sh` is STALE (missing the Phase-9-required + `--vram-base`/`--exe`) and reports only the objects it could PLACE — a silently smaller set. +* A workflow killed by the session usage limit resumes cleanly: `Workflow({scriptPath, resumeFromRunId, + args})` replays completed agents from cache and re-runs only the interrupted ones (proven twice). ## SESSION S52 TASK LIST (2026-08-15, ultracode) — the monitorable view (no TaskCreate tool in this harness build)