search: 285 of 800 exemplars matched lever-free in 2.32 h (285 of 800 bodies behind them; 94,627 compiles) — NO-MATCH 499 · MATCH 285 · UNSTRIPPABLE 9 · UNSCORED 7
- the first broad draw of non-head classes, at the cheap width, with the full generator set. By first move:
R7 105, R10 59, R12 42, R6 26, R9 20, R18 13, R8 9, R3 6, R15 4, R14 1 — and 242 of the 285 closed in ONE move.
These are not deep searches; they are bodies nobody had ever offered a single shape to. R18, one day old, is 13 of them.
- the contrast that steers the rest of T7: 36% of the tail closes mechanically, against 6 closes in ~128,000 compiles on
the head. The head's 57 classes are the agents' work; everything else is the engine's, at zero tokens. Sweep the whole
residue before spending another agent.
- check-all: 218 passed, 0 failed of 218
lever_census --check: 29,204 pin/asm sites, 29,204 marked !FAKE, 0 UNMARKED — OK
- snapshot row 15.
- the Opus drafter recovered the closeness-0 body the journals (attempts 1-3) pointed at (.run/S71b_1/fable/) — the
pack's inline 292-draft was the wrong one — and found the real blocker: the TU defines Struct80078E78 AFTER the
slot with a layout lacking bytes 0x36/0x37; only a BLOCK-scoped typedef under a distinct tag (Blk80078E78) + a
block-scoped extern compiles (decl-hoisting resolver variants recreate the S7x 'conflicting types'). Idioms:
§162k1 QImode (u8)(c-3)<2; explicit flag temp t=(u32)(r-0x64)<0x1E, s1=t^1; switch decision trees for both
currentLocationId dispatches. reloc_identity AGREE 50/50; rtu_match MATCH 344/344 (verified by the coordinator)
- jtbl_carve --func: jtbl_80113FA4 (5 words, the old tail2) joins the resident_jr_800D00E4 .rodata piece
(0x450e0..0x451c0, JTBL_PADS 0,0,0,0, tables +0x0/+0x3c/+0xb4/+0xcc); carve set 5 -> 4 pieces, --pre kept
- make extract + make build BINARY=resident -j8 rc 0; sha 8e17e02ff8954d07c979449198f7e1645046b353 == check;
pads_audit ok/ok; interleave_check ALIGNED n=4
- BANK: the stored S71 closeness-0 draft spliced into src/resident/resident_jr_800D128C.c; jtbl_carve --func
carved jtbl_80113FB8 (119 entries, 1 pad word trimmed) + jtbl_80114198 into [0x451c0, .rodata,
resident_jr_800D128C] + [0x453c4, data, tail3]; JTBL_PADS 0,4; make extract + make build BINARY=resident -j8
rc 0, sha 8e17e02ff8954d07c979449198f7e1645046b353 == check (R53). pads_audit ok/ok; interleave_check
ALIGNED n=5; verbatim_check --strict 5==5. Resident stubs 2 -> 1 (func_800D06E8 remains).
- WHY THE GATE SAID DIFF (parallel_gate banked 0/DIFF on an rtu_match MATCH): jtbl_carve.set_overlays_var
regenerated resident_JTBL_INTERLEAVE from the carve set and DROPPED the resident's `--pre hdr.rodata.o`
(§8f leading-rodata sandwich); make extract refused (ld_interleave: hdr.rodata.o would be parked with
.text), the build linked the STALE script (249,252 differing bytes from file offset 0x4), and
harvest_verify._jtbl_prep_one never read the post-carve extract's exit code (R49/R61).
- FIXES (R35/R40/R57): jtbl_carve._merge_pre carries an existing --pre forward (idempotent; overlays
unchanged, 4-shape unit control); harvest_verify refuses loudly on a failed post-carve extract and
restores the snapshot (CARVE refusal, NOT a draft verdict); interleave_check's anchor accepts a leading
--pre (was a false DRIFT n=0 on the resident; control ov_SC02_017 ALIGNED n=44 unchanged).
- cookbook §498 (+ the stale-asm-after-a-failed-extract sequencing law); SETUP rows for all three
- jr_isolate_all resident --only func_800D128C: [0x4 c resident] [0x12ec c resident_jr_800D00E4]
[0x2494 c resident_jr_800D128C]; the banked jr func_800D00E4's .rodata carve + JTBL_PADS + --order
repointed to resident_jr_800D00E4.o (config/overlays.mk resident block only, R60); make extract +
make build BINARY=resident -j8 rc 0, sha 8e17e02ff8954d07c979449198f7e1645046b353 == check (R53)
- TOOL FIX (R43/R33): the carried-type test consulted _engine_types() (engine_types.h + common.h) for
every TU, assuming each region includes engine_core.h; the resident includes only common.h, so its
file-local `typedef struct {...} CdFileLoc;` (a name engine_types.h also defines) was silently NOT
carried -> `parse error before cdFileLocTable` in both region TUs, build rc 2 while the stale binary
on disk read green. Now _provided_types(header) derives the set from the TU's own #include lines
(engine_core.h => engine_types.h + common.h, never engine_core's macro-internal typedefs; common.h
=> common.h) and _file_scope_decls(items, provided) uses it at both decision points. R39 controls:
overlay header == legacy set (1,197 names); resident set lacks CdFileLoc. cookbook §496; SETUP row
- rtu_match func_800D128C --split resident_jr_800D128C: MATCH (243 ins) on the stored S71 draft;
the gate is the next commit
resident:func_800D00E4/func_800D02D0/func_800D0488 + ov_SC07_002:func_80180248, all byte-verified
from clean rebuilds (resident 8e17e02f, ov_SC07_002 fad71342) and counted from the SOURCE.
ov_SC06_029's two are re-gated separately against HEAD — this agent's worktree predated five banks
there, so its numbers for that binary no longer apply.
TWO OF THE SIX NEEDED NO CARVE WORK AT ALL, AND CARVE-REFUSED WAS AN INSTRUMENT VERDICT.
ov_SC07_002:func_80180248's table is ALREADY inside a carve bound to its own subseg: in stub state
spimdisasm migrates the table into the fn's .s and the object fills the piece exactly, so banking
just swaps that block for cc1's identical one. `island_probe` classified it `tail` on the table's
ADDRESS, `apply()` routed it to build_carve, which resolves spans out of the RAW data asm where a
carved table no longer is -> "not found in the raw data asm" -> harvest_verify booked CARVE-REFUSED.
A verdict about the route we chose, not about the function (R43). jtbl_carve now has a `covered`
verdict (table inside an existing carve bound to the fn's OWN subseg) and a `covered-tpad` wall (the
retail copy carries a trailing §8a pad the matched body won't emit — bankable, needs a `0t<n>`
entry); a fully-covered batch is a no-op before either route.
THE RESIDENT CAN CARVE LIKE AN OVERLAY. Its three tables are adjacent and lead the island
(0x450e0..0x451ac, one span, all in subseg `resident`). The genuinely new part: the resident opens
with `- [0x0, rodata, hdr]`, a 1-word .rodata header BEFORE the code, so its layout is
rodata -> text -> data -> rodata(carve) -> data, which `ld_interleave --order` cannot express (every
listed piece lands after TEXT_START, and hdr.rodata.o would fall into the unchecked `empties` bucket
and be parked after the text, moving every byte). New `--pre` places a leading-rodata piece ahead of
the text; resident_JTBL_INTERLEAVE uses it.
NEW LAW, BYTE-PROVEN (§8b was over-strict — EXTEND the carve, do not isolate): a .rodata carve piece
binds to a code SUBSEG, not a function, and the object's .rodata is the address-ordered
concatenation of cc1's tables for BANKED functions and still-stubbed functions' MIGRATED tables. So
a span may legitimately hold a MIX, and extending a carve across an align-pad word and two unrelated
STILL-STUBBED tables was byte-identical with nothing banked — where the tooling demanded a
jr-isolation. Corollaries, all measured: migrated tables self-align (spimdisasm emits `.align 3` iff
the table's SPAN-RELATIVE offset is 8-aligned), so stubbed tables need no spec; JTBL_PADS counts cc1
tables only, so a mixed span's spec GROWS as each sibling banks; and the zero-word rule is INVALID
across a migrated boundary, because that zero is supplied by the preceding migrated block.
ALSO REPORTED, NOT FIXED (harness gap worth its own change): verify_worktree.provision omits
`.run/sig.<bin>.jsonl` — main clone 259 files, provisioned worktree 0 — and jr_isolate_all's
carve-ownership scan swallows the resulting FileNotFoundError in a bare `except: continue`. Measured:
2603 of 2603 functions raised, the scan found 0 owners, and the run aborted with a CONFIDENT FALSE
verdict ("committed .rodata carve ownership is not 1:1 — stranded/duplicated carve"). Both resolve
instantly once the sigs are present. Any worktree-run isolation before that is fixed reports a
corruption that is not there.
cast_self_callers casts a function's call sites in PREPARATION for banking it.
When the draft then fails, the cast must come back out — the tool journals every
edit for exactly that, and I did not run the undo.
The cost was concrete: the leftover cast on func_8017F8B8 made ov_SC07_000 fail
to COMPILE at HEAD, so every subsequent gate verdict on that binary was measuring
a broken baseline rather than the draft. Two drafting agents reported it as
BASELINE-RED before I noticed.
24 casts reverted across 11 files in 7 binaries; all 7 rebuild green. This is the
discipline recover_integration already documents ('REVERTS the caller edits for
anything that doesn't bank') applied to the new tool.
Hardest draw of the session: 23 of 25 targets over 120 instructions (up to 138), and the FIRST wave
whose packs auto-carried the residual class's cookbook bucket (15 of 25). Agents self-reported
25/25 MATCH with zero NEAR — against O21's 34/40 earlier the same day on an EASIER band. One wave
is not causation (the arm mix also moved toward opus), but the notes changed character: they cite
and EXTEND banked laws instead of grinding.
Gate refused 2, and BOTH were predicted by their own agents as integration rather than codegen:
func_801588CC's note named the §8e/§260-A tail-class jtbl carve (jtbl_80199FF8 parked adjacent to
.rodata) and said it needs the gate's jtbl lever, not C. func_8017E498 likewise. Reverted those two
binaries; the other 16 verify green from a full clean rebuild.
Headline lever from this wave (func_80181E98) is a SCOPE CORRECTION to §186, the same shape as the
§167-05 polarity fix earlier today: §186 says no C-level barrier steers cross-jumping — true for
STEERING, but a zero-byte __asm__ __volatile__("") before an arm's goto BLOCKS a suffix merge
outright. Traced to gcc's own jump.c: simplejump cross-jumping calls find_cross_jump(insn,
JUMP_LABEL(insn), minimum=1) and walks BACKWARDS from the j; the empty asm is an ASM_INPUT that
fails rtx_renumbered_equal_p at compare #0, so last1==0 and no merge occurs, for zero emitted bytes.
Closeness 75 -> 40 plateau -> MATCH.
Uncommitted src/ changes found at gate entry. These are banked functions from a lane that gates with commit=False, not residue — preserved, not reverted. Top-level src/*.c (main TUs) are excluded by construction (S59).
Ultracode wave: 16 isolated drafters over the resident's non-jtbl stubs (the 5 jtbl deferred —
they need the rodata-island carve, §53). Drafts only; the whole-binary byte-gate arbitrated after.
- BANKED 7/16, byte-gated: func_800CEFD0(77) func_800D0D7C(45) func_800D1B80(22) func_800D1E28(37)
func_800D1FC8(62) func_800D29F8(172) func_800D2D10(39).
Resident REAL 122 -> 129, stubs 21 -> 14, byte-ident 124/145 (85.52%) -> 131/145 (90.34%).
FLEET instr 9017152 -> 9017606 (+454 ins). R22 make clean && extract-all && check-all ->
140 passed, 0 failed of 140 (the first R22 was killed by a terminal crash and RE-RUN, not assumed).
Ground truth on 14 agrees 3 ways: source grep, splat-emitted stub .s count, progress.py.
- §52b's LAW, MEASURED AGAIN INDEPENDENTLY: the agents self-reported 11 match_one MATCH; the
whole-binary gate banked 7 (64%). All 4 blocked MATCHes died on `conflicting types`
(D_8010EDEC / D_80115110 / func_800D1984 / cdFileLocTable) — the loose-typing def-side wall, NOT
codegen. gate_stage's recovery banked 0/5 on them. A match_one MATCH is a CANDIDATE (G3/P9).
- FIX — match_one's isolation was FAKE, and its own docstring was the false spec. It promises
"Fully isolated (own temp dir) so many run in PARALLEL with no shared build -- a real asm-differ
loop for an agent to iterate against", while `--work` defaulted to the SHARED '.run/match': every
concurrent caller compiled into the same t.c/t.o. FOUND BY AN AGENT MID-WAVE, the only way it can
be found — it read another agent's function out of its own scratch ("found another agent's
func_800D2650 in my t.c") and reported it. Every other agent steered by a loop that could hand it
someone else's compile: a CONFIDENT WRONG verdict, worse than a crash. Default is now a private
.run/match/<fn>.<pid>; the default IS the promise. (Some agents had already worked around it by
passing --work themselves.) The byte-gate was never at risk — it is the sole arbiter — but the
iteration loop the agents steer by absolutely was.
- The 14 remaining: 5 PLUMBING (loose-typing) + 4 DIFF (genuine codegen: func_800D2650 close=4,
func_800CFAD0 close=5, func_800D0E30 close=12, func_800D27DC close=48) + 5 jtbl deferred.
Dossier next (T5b) — the agents' per-function residual analyses are the durable asset (R30).
The pass-4 functions that match_one matched standalone but the single-TU build rejected
on conflicting shared-symbol extern types are recovered by UNIFYING those types in
resident.c (widening definitions' return types where byte-identical — u16 f(){return
u16g} ≡ s32 f(){...} both lhu;jr; choosing asm-correct widths for globals; per-site
*(u16*)&g tricks where a neighbor pins the type). ~20 symbols reconciled
(func_800291B4/CFD68/D1714/D1078/801465C0/... + D_800AE6A8/80078E50/...).
20 of 21 recovered; func_800D00E4 stays an honest INCLUDE_ASM stub (its switch needs the
external jtbl_80113ED8 relocation, not a C-source fix — analysis preserved under #if 0).
REAL 102 -> 123 (85.62% byte-identical); resident 8e17e02f, main 143dbb89 (R22 clean).
22 stubs remain: ~20 documented compiler-internal residuals (permuter/§3a) + D00E4 + dedup.
- tools/match_one.py (new): compile ONE function's C standalone (pinned triple), mask
relocations (jal/HI16/LO16 like psyq_identify), compare to the target bytes in its .s.
Isolated temp dir -> parallelizable; a real per-function asm-differ loop for agents to
iterate against without a shared build. Validated: a matched fn -> MATCH, residuals ->
informative diffs.
- harvest_verify.py + match_one.py: strip inline scalar-typedef redefinitions (some drafts
inlined `typedef unsigned char u8;` -> C89 redefinition error vs common.h = a COMPILE
fail, not a byte mismatch). Re-gate recovered func_800CFBCC + func_800D1938.
- REAL 89 (62.76% byte-identical); resident 8e17e02f, main 143dbb89 (R22 clean).
- 54 stubs remain (scheduling/regalloc residuals + big GPU/dispatch fns) -> match_one-driven
iteration pass next.
Ultracode harvest: a 16-agent workflow (resident-harvest-draft) drafted matching C for
the 135 unmatched resident functions (each agent: asm + cookbook + the 8 worked examples,
writing .run/drafts/<fn>.c, no builds/no Ghidra). Then tools/harvest_verify.py (new) byte-
gated every draft against 8e17e02f one at a time (chunk+bisect), keeping only the byte-
perfect ones and reverting the rest -- the build is the sole arbiter (G3/P9).
- 62 / 127 drafts verified byte-identical in one pass; 65 near/hard misses reverted to stubs.
- REAL 8 -> 70 (48.28%); byte-identical 49.66%. resident 8e17e02f, main 143dbb89 (R22 clean).
- cleaned 35 redundant '#include "common.h"' lines the drafts inlined (still byte-identical).
- remaining: 65 failed drafts (close-misses + the hard dispatch/GPU/big-fn tail) + 8 undrafted
(2 agent batches hit transient API 500s) -> second-pass workflow + manual hard tail.
- opt level: resident is -O2 (0x21f0a003 frame-ptr sig count = 0, vs the EXE's 54;
the EXE's 800 game module is also -O2). No per-file override needed.
- triple (Makefile default, no override): gcc-2.7.2-psx -O2 -G0 -mips1 -mcpu=3000
-mgas -msoft-float -fgnu-linker + maspsx --aspsx-version=2.56 --expand-div.
- 2 byte-exact resident matches confirm it across idiom classes:
* func_800CF854 — lbu D_800AE6BF; sltu $zero (unsigned-!=0 accessor)
* func_800CEE84 — 8-call init: branch-store (D_80127084=0; if(D_800B9A00) =1),
delay-slot-filled func_80010AE0(0x3E0), early-scheduled load
- R22 clean rebuild: resident 8e17e02f, main 143dbb89 — both byte-identical.
make report BINARY=resident: REAL 0 -> 2.
- R24: the "resident is 4.7" DetectPsyQ hit was a coincidental DsMix signature; the
resident's actual game-code triple == the EXE's (byte-confirmed). No candidate
ladder; the STOP-condition did not fire. Harvest (T3) de-risked.
- tools/ghidra_import_raw.sh (NEW): raw-blob importer (BinaryLoader + --loader-baseAddr +
PSX:LE:32:default) — the Gen2 counterpart to ghidra_import.sh (PS-X-EXE only); reusable for
Phase-13 location overlays. Imports the resident blob as program 'resident' @0x800CEDF8.
- tools/ghidra_scripts/DefineFunctions.java (NEW): seed splat's validated entry points
(.run/<prog>_funcs.txt) — raw-binary auto-analysis finds only the reachable subset (23/143);
this defines all 143 (created=120/existed=23/failed=0). R9-verified 143 funcs persisted.
- FINDING: DetectPsyQ reports the resident is PsyQ 4.7.0 (the EXE is 4.0.0); the lone in-range
PsyQ-signature hit is DsMix (libsnd -> resident holds the sound driver). 4.7 .LIBs DEFERRED to
Phase 11 start (Drew); carried to PhaseEnd Notes. Phase 10 needs nothing from 4.7.
- config/symbols.resident.txt: seed DsMix (R13 candidate, 4.0-sig vs 4.7 blob — confirm in Phase 11);
stacked under symbols.us.txt, applied on re-extract -> resident still 8e17e02f BYTE-IDENTICAL (R22),
main still 143dbb89 (no regression)
- Makefile: per-binary GHIDRA_PROG -> 'make sig-refresh BINARY=resident' (.run/sig.resident.jsonl)
- dup_report.resident now real (6 byte-identical intra-resident groups — Phase-11 dedup fodder)
- ghidra DB committed (R23, MCP stopped): new resident program 00000003.* (+ main db.15->16 no-op)
- mapped the blob vs bytes: word0 data header (0x36); clean code 0x4..0x4610 (145 funcs,
zero embedded jump-tables/trap-ops); data tail 0x4610..EOF (pointer tables + 78.5KB zeros)
- split: [0x0, rodata, hdr] + [0x4, c, resident] + [0x4610, data, tail]
- fix 1: the leading data word sits BEFORE code, which fights section_order; emit it as
rodata (no-dot) so section_order [.rodata,.text,.data,.bss] places it first @0x800CEDF8 —
a 1-word analogue of main's rodata-island, no ld_interleave needed
- fix 2: build_path=build (not build/resident) so splat's .ld object paths match the
Makefile's build/asm/** + build/src/** pattern rules (only elf/ld/output in build/resident/)
- MILESTONE: make build BINARY=resident -> 8e17e02ff8954d07c979449198f7e1645046b353
BYTE-IDENTICAL (365,404 B, end vram 0x80128154); -G0 confirmed (0 gp refs);
R22 clean-rebuild green; main still 143dbb89… (no regression)
- src/resident/resident.c (143 INCLUDE_ASM stubs) committed; asm/resident/** regenerated