37 Commits

Author SHA1 Message Date
Drew T 783bacb5e8 src(phase-37): T4 unalias t4_ua2 — 98 of 148 alias-defined functions back under their real names with their byte-true signatures (592 files; 50 kept, causes bucketed) | R22 check-all: 218 passed, 0 failed of 218 | 🛑 T4 in progress (S107) 2026-09-12 12:27:26 -06:00
Drew T 8b0e8645e4 phase-36: S104 s104_e34 — func_800D128C banked at 0 through the whole-object gate + propagated — 3 levers → 0 asm + a class-E call alias: s16 ret, gotos into case 16 (jump.c:2371/2406/3991-3992; varasm.c:478-485) 2026-09-11 04:44:51 -06:00
Drew T 889a7ad138 phase-36: S104 s104_e34 — func_800D1658 banked at 0 through the whole-object gate + propagated — 3 levers → 0: (u16)ret == 0x8000 (cse.c:4850-4869) + the goto chain as one condition 2026-09-11 04:44:34 -06:00
Drew T fb0ae9fd0f phase-36: S104 s104_e34 — func_800D1984 banked at 0 through the whole-object gate + propagated — → 0: the same (byte-twin) 2026-09-11 04:44:18 -06:00
Drew T bc0e4888ec phase-36: S104 s104_e34 — func_800D1B80 banked at 0 through the whole-object gate + propagated — → 0: the method pointer called with its object (sched.c:2488-2545; local-alloc.c:700; jump.c:425-462) 2026-09-11 04:44:01 -06:00
Drew T 67e91ad4d4 phase-36: T7 sweep s5 — the TAIL closes at 36%: 285 of 800 bodies lever-free for zero tokens (29,527 → 29,204 sites, R22 218/218)
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.
2026-09-10 07:21:39 -06:00
Drew T cb2fb5e6db src(phase-36): T4 batch tus10 — delever: batch tus10 — 83 files (TUs; 83 drawable) · 362 bodies: 99 lever-free, 258 residue, 2 refused · sites removed 411 / needed 483 / refused 37 / deferred 3 · replays 4 (0 disagreed) · compiles 1171 in 25 s wall · final 83/83 identical · written 83 files | R22 check-all: 218 passed, 0 failed of 218 | census: THE PHASE'S NUMBER (pins + asm statements, GTE excluded): 34,100 sites in 12,570 bodies (1,823 distinct) · marked !FAKE 32,973 · UNMARKED 1,127 (delever_cycle) 2026-09-09 04:18:13 -06:00
Drew T 5ff842dfd3 feat(phase-32): T3 (3) — resident: func_800D06E8 (344 ins) BANKED byte-identical 8e17e02f — THE RESIDENT IS 100% C (145/145)
- 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
2026-09-05 01:03:07 -06:00
Drew T c513e1fbbd feat(phase-32): T1a (2) — resident: func_800D128C (243 ins) BANKED byte-identical 8e17e02f via the raw splice + a 5-piece carve; three instrument fixes (§498)
- 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
2026-09-04 23:28:59 -06:00
Drew T 380ccdc843 feat(phase-32): T1a (1) — resident code subseg split (3 regions, byte-identical 8e17e02f) + jr_isolate_all include-derived provided types (§496)
- 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
2026-09-04 23:20:04 -06:00
Drew T 6e840730a9 feat(carve): bank 4 more via the carve chain — and §8b's "non-adjacent => ISOLATE" is over-strict
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.
2026-09-02 19:34:09 -06:00
Drew T 4949acdf31 revert(integration): drop the §378 casts for the 25 chain candidates that did not bank
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.
2026-09-01 10:35:29 -06:00
Drew T cb7a28551c chore(integration): §378 chain applied to 25 fresh closeness-0 candidates (pre-gate) 2026-09-01 03:57:19 -06:00
Drew T ef504ffc32 chore(integration): decl-sync for the 21 remaining §376 candidates (pre-gate) 2026-08-31 23:54:17 -06:00
Drew T 72d3f61dcd chore(integration): self-caller casts for the 27 remaining §376 candidates (pre-gate) 2026-08-31 23:36:59 -06:00
Drew T 6cca1e3ea0 feat(decomp): main in-tree gate — 0 fn(s) 2026-08-31 23:00:25 -06:00
Drew T f59f0883ad feat(decomp): O31 overlay lane — 16 fns, clean-R22 verified 213/213
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.
2026-08-30 18:33:06 -06:00
Drew T 170f33fb8b feat(decomp): ox wave g0f overlays — 10 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-26 08:01:45 -06:00
Drew T ce12e1c2f7 chore(decomp): commit in-tree banked work before the serial lane 2026-08-25 22:42:46 -06:00
Drew T 2fea549c53 feat(decomp): ox wave dr overlays — 28 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-25 13:55:25 -06:00
Drew T ca5fd2e225 feat(decomp): ox wave di overlays — 81 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-25 12:13:33 -06:00
Drew T 520a4ca3f2 feat(decomp): ox wave da overlays — 74 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-25 10:17:06 -06:00
Drew T 45ccac8ecc chore(decomp): commit in-tree banked work before the next gate
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).
2026-08-25 10:01:52 -06:00
Drew T 829361dd7b feat(decomp): ox wave cf overlays — 50 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-25 01:09:05 -06:00
Drew T 1f7fdc7913 feat(decomp): ox wave br overlays — 8 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-24 16:50:56 -06:00
Drew T 49609fc1a6 feat(decomp): ox wave aq overlays — 60 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-24 03:26:53 -06:00
Drew T 876dc7f053 feat(phase-28 T5): resident 21 -> 14 stubs (7 banked, 90.34%) + fix match_one's fake isolation
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).
2026-07-16 01:41:57 -06:00
Drew T a480d83bee feat(phase-12): T3a — extern-conflict recovery, +20 (REAL 102->123, 85.6%)
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.
2026-06-16 14:05:20 -06:00
Drew T 393d34604b feat(phase-12): T3 pass 4 — match_one iteration loop, +13 (REAL 89->102, 71.7%)
resident-harvest-iterate workflow: 13 agents iterated the 54 hard functions using
tools/match_one.py (per-function compile+diff loop), self-correcting against real
feedback. Agents reported 34 match_one-MATCHes; the whole-build byte-gate confirmed 13
(func_800D23D0 D1754 CEF5C CF584 D17B8 D2E6C D0588 D2CA8 CFC5C CF3B8 CF104 D20C0 D1BF8).
The ~21 standalone-MATCH-but-gate-FAIL are TU-level extern-type conflicts (a draft
declares a shared symbol's type to suit its own call site, conflicting with another
function's declaration) -> recoverable via a unified extern header (next).
Expert idioms found: struct-copy prologue, void-dispatcher-is-actually-s32-returning,
*10 -> 2x+8x decomposition, polarity flips. REAL 102 (71.72% byte-identical); both
binaries clean. 41 stubs remain (extern-conflict casualties + documented cross-jump/
regalloc residuals = decomp-permuter / cookbook §3a territory, honest P9 deferrals).
2026-06-16 13:15:50 -06:00
Drew T 4c7cf48ebf feat(phase-12): T3 — +2 (typedef-strip recovery) + per-function match tool (REAL 87->89)
- 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.
2026-06-16 12:43:59 -06:00
Drew T 8dbaa489f7 feat(phase-12): T3 batch 3b — +9 via retry-resilient redraft pass (REAL 78->87, 61.4%)
Pass 3 (resident-harvest-redraft3): retry-wave workflow re-drafted all 65 remaining
stubs seeded by BOTH prior failed drafts + a sharpened debugging checklist (callee
return-type-forces-andi, signed-vs-unsigned sltu, store order, QImode decrement, the
register-pointer far-load idiom). All 13 batches completed (retry waves defeated the
transient server rate-limiting). tools/harvest_verify.py byte-gated -> +9:
func_800D2F8C func_800D1F90 func_800D2DFC func_800D222C func_800D10C8 func_800CFBF8
func_800D3120 func_800D1B10 func_800D18DC.

Resident harvest this session: REAL 1 -> 87 (61.38% byte-identical), all hand-matched
engine C, via 3 parallel-draft workflow passes (79 fns) + a deterministic byte-gate that
makes a wrong match impossible (G3/P9). resident 8e17e02f, main 143dbb89 (R22 clean).
56 stubs remain (scheduling/regalloc residuals + the big GPU/dispatch fns) -> per-function
asm-differ/permuter loop + serial Ghidra next.
2026-06-16 12:35:21 -06:00
Drew T 69227e4f6a feat(phase-12): T3 batch 3 — +8 resident fns via redraft pass + byte-gate (REAL 70->78)
Second-pass workflow (resident-harvest-redraft): agents re-drafted the failed/undrafted
functions seeded by their prior draft + a debugging checklist (load width/sign, branch
polarity, arg count, store order). Transient server rate-limiting killed 10/14 agents, so
only ~25 re-drafts landed; tools/harvest_verify.py byte-gated them -> 8 more verified:
func_800D33B8 func_800D2EE8 func_800D0C74 func_800D0CA0 func_800D2DAC func_800CF5D4
func_800D2FEC func_800CFDE8. The recovered bugs: twin-fn u16-return (D2EE8 mirrors the
matched D319C), missing call arg (CF5D4), proven index idiom (CFDE8).
REAL 70 -> 78 (53.79%); resident 8e17e02f, main 143dbb89 (R22 clean).
Remaining: ~65 stubs (17 redraft-resisters + ~48 never-redrafted [rate-limited]) -> pass 3
+ serial asm-differ on the hard GPU/dispatch tail.
2026-06-16 12:15:27 -06:00
Drew T c37332fa19 feat(phase-12): T3 batch 2 — 62 resident functions matched via parallel-draft + byte-gate (REAL 8->70)
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.
2026-06-16 11:59:02 -06:00
Drew T 6d1b0c051e feat(phase-12): T3 batch 1 — 6 trivial resident accessors matched (REAL 2->8)
Resident engine harvest underway (triple confirmed in T2). Batch 1, all byte-identical:
- func_800CF804 / func_800CF818 — set D_80127084 / D_80114E78 = 1 (s32)
- func_800CF82C / func_800CF840 — set D_800B9A0E = 1 / 2 (s16, sh)
- func_800D1714 — get D_80078E50 (u16; player-state region ~0x80078Exx)
- func_800D1724 — set D_800AE6B0 = arg (s32)

make report BINARY=resident: REAL 2 -> 8 (5.52%); byte-identical 10/145 (6.90%).
R22 clean rebuild green: resident 8e17e02f, main 143dbb89.
2026-06-16 11:17:54 -06:00
Drew T b8457a8636 feat(phase-12): T2 — resident compiler triple CONFIRMED = the EXE's (2 byte-exact matches)
- 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.
2026-06-16 11:14:25 -06:00
Drew T 03978ec4ba feat(phase-10): T4 — resident Ghidra program (2nd binary) + symbol seed + sig
- 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)
2026-06-15 23:25:00 -06:00
Drew T f06785bcf2 feat(phase-10): T2 — resident blob byte-identical (8e17e02f), the milestone
- 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
2026-06-15 23:00:51 -06:00