Commit Graph

92 Commits

Author SHA1 Message Date
Drew T d593ee20fe feat(phase-18): Step-3b calibration — §17-toolkit wave banks 9 reach-134 matches (55.58->55.94%)
- upgraded harvest wave (.run/harvest_wave_3b.js) teaches the §17 TOOLKIT: triage the
  match_one diff -> reconstruct / array-decay / register-pins+barrier (instead of stubbing
  the regalloc tail). Calibration: 16 fresh tractable reach-134 targets.
- whole-binary close-rate 9/16 = 56% (vs Phase-17 baseline 33%): 2 via register pins
  (func_8012CB64, func_801468C8), 2 via array-decay (func_80149544, func_80149584),
  5 via clean reconstruction. Each reach-134 -> propagated x134 (config/dedup.us.yaml +9).
- FINDING (R16 flywheel): the match_one->gate gap (12->6 then ->9) is the §3a call-site
  CASTS the agents skipped + sig_unify narrowing the extern to canonical -> conflict.
  Recovered 3 by call-site arity-cast / void-return cast (codegen-neutral). Step-1 prompt
  must teach call-site casts + re-validate after sig_unify.
- make check-all 136/136 byte-identical (R22); dedup-check 1432 validated, 0 failed;
  0 NON_MATCHING in any default build (G4).
2026-06-20 13:40:11 -06:00
Drew T 667504a4ba docs(phase-18): correct §17/§8e — register-order class is STEERABLE via pins (not unsteerable)
- §17 rewritten: the call-crossing register-ORDER class is MATCHABLE with register
  __asm__ pins + a scheduling barrier (byte-proven func_8012B8E4), not unsteerable.
  The wall was a missing lever (the pins), not an impossibility. Recipe documented as
  a TOOLKIT: triage with match_one -> reconstruct / array-decay / PINS / barrier.
- §16 cross-refs + hand-matching §8e corrected to match. The ONLY genuine stub-and-skip
  left is the narrow-param loose-typing conflict (func_80146A6C).
- self-correction (P9/R14): I concluded 'unsteerable' before trying the pins; Drew's
  hand-match-everything directive exposed the gap. Recorded honestly.
2026-06-20 12:33:08 -06:00
Drew T f1bbcd241f feat(phase-18): VERDICT REVERSED — func_8012B8E4 hand-matched via register pinning
The 'unsteerable' regalloc-order class is NOT unsteerable. Drew's directive (hand-match
everything) exposed the lever I'd skipped: explicit register pinning.

- func_8012B8E4 (the flagship circular reach-134 'unsteerable' fn): 21 -> MATCH via
  * register pins: register s32 d __asm__("$16"); register s32 s1ang __asm__("$17")
    -> FORCES the $s0/$s1 global allocation gcc otherwise density-orders the other way
  * branch-polarity invert (§3-T4): 24->21
  * explicit clamp temps (t=u6+0x1000; iVar4=u5-t): fixes the reassociation, 7->3
  * scheduling barrier __asm__ __volatile__("" : : "r"(u5)): anchors the last sll, 3->MATCH
- byte-gated (harvest_verify, G3/P9) + propagated x134 (per-overlay gate); 134 byte-identical
- recipe = §10-family hand technique (pins + barriers); labor-intensive (per-fn register map
  from the asm) but it WORKS -> the circular tail IS hand-matchable, not asm-only
- supersedes the T1-T5 'unsteerable' verdict; cookbook §17 + PhaseEnd to be revised accordingly
2026-06-20 12:17:54 -06:00
Drew T ceecaeb235 docs(phase-18): T5 — cookbook §17 (steerable-vs-not) + reconcile §10-vs-§16
- cookbook §17 (NEW): the compiler-quirk wall, gcc-2.7.2-source + Xenogears confirmed:
  * UNSTEERABLE: call-crossing $s0/$s1 allocation ORDER (global.c allocno_compare density;
    exhaustive C/flag/cc1 sweep + Xenogears ships-as-asm corroboration) -> stub it (G4)
  * STEERABLE idioms: array-decay-forces-remat (NEW), for-loop-vs-do-while delay-slot
    scheduling (NEW), statement-order (§2-T2 ext); + reconfirmed branch-polarity/mask-local
  * pipeline gotcha: match_one masks relocs -> sig_unify/canonical-retype is MANDATORY
    before harvest_verify (the conflicting-types gate failure)
  * loose-typing narrow-param wall is REAL (func_80146A6C lhu/s16 vs canonical s32/lw)
- §16 reconciled: the 'not source-steerable' line cross-refs §17; §10-vs-§16 tension
  resolved by naming the residual class precisely (both right about different residuals)
- hand-matching-process.md §8e: Phase-18 outcome re-scopes the Phase-19 wave
  (triage-and-stub the unsteerable; spend on non-walled STRUCTURAL_MISS)
2026-06-20 11:54:07 -06:00
Drew T 52cfc22972 feat(phase-18): T6 — func_801399A8 matched + propagated x134 (fleet 55.51->55.55%)
- reach-134 STRUCTURAL_MISS target closed by the research idioms:
  * for-loop structure (vs do-while) -> correct beqz delay-slot scheduling
  * statement-order in the for-update (cookbook §2-T2) -> final 2 increments
  * sig_unify canonical retype (s32 return + s32 data, integer address arithmetic)
    -> resolves the TU-level conflicting-types gate failure that match_one masked
- byte-gated (harvest_verify, G3/P9): ov_SC01_077 stays d19c9580 BYTE-IDENTICAL
- propagated to all 134 overlays via dedup_propagate (per-overlay gate, fail-closed)
- make check-all: 136 passed / 0 failed; fleet 190,949 -> 191,083 / 344,010 = 55.55%
- KEY reframe: the STRUCTURAL_MISS bucket IS matchable (idioms work); distinct from
  the PERMUTER_CLASS/circular regalloc-order tail which is unsteerable (T1-T3 verdict)
2026-06-20 11:48:12 -06:00
Drew T d20b20c64b feat(phase-18): T0 — setup + exemplar set; match_one validated as the §10 oracle
- clone gcc-papermario (a6afc2af) + xenogears-decomp (f27c0768) -> tools/reference/
  (gitignored research refs; SHAs pinned in docs/SETUP.md §5.6, R20/R21)
- apparatus byte-validated: match_one cleanly measures the §10 residual on both quirk
  exemplars (the floor-free oracle Phase 17 failed to use; permuter score was polluted):
  - func_8012B8E4: 75=75 ins, 24 mismatched -> $s0/$s1 regalloc swap + reassociation (§10 A)
  - func_8012B4B8: 94 vs 84 ins, 88 mismatched -> extra-reg spill + struct-copy/reload (§10 B)
- CURRENT_PHASE.md crash-recovery log; harness task list (R28); no build-affecting change
2026-06-20 11:08:21 -06:00
Drew T c4b0cef86a feat(phase-17): close — canonical-sig layer built; the wall is the compiler, not sigs; pivot to gcc research (v1.16.0)
- canonical-sig layer (session 4): tools/census_conflict_callees.py + derive_canonical_sigs.py
  -> a 20-extern byte-neutral block atop ov_SC01_077.c (LOCAL, not engine_core.h); census
  conflict callees 20->0, blocked targets 24->0; gate pipeline now draft -> sig_unify (MANDATORY)
  -> harvest_verify --chunk 1; fleet 136/136 byte-identical (R22), 55.51% (no regression)
- FINDING (R14/P9): the conflict wall is 7%-reach not ~2x; the 4 reach-134 circular targets are
  ALL gcc-quirk/regalloc/layout-bound (0 banked); the high-reach core IS the quirk tail; struct
  types are byte-neutral for matching (the wall is gcc codegen, not knowledge)
- leverage analysis: fleet % is function-count-weighted (size adds no %); "unblock many" = the
  layer (declaration, not matching); reach is the lever (already reach-sorted); 247 tractable
  reach-134 stubs ~ +3-4% projected
- GO/NO-GO: NO-GO on brute waves at the current ceiling; GO on a compiler-quirk research phase
  (read gcc-2.7.2 source + Xenogears + the §10/regalloc classes, R17) -> then resume the wave
- docs: cookbook §16 corrected + hand-matching-process.md §8 (the layer + the finding + handoff)
- worklog archived -> phase-ends/logs/Phase17.md (R19); bumps 1.15.0 -> 1.16.0
2026-06-20 09:35:18 -06:00
Drew T f0dd9351e4 docs(phase-17): flywheel + handoff up to date — canonical-sig wall is the scaling lever
- CURRENT_PHASE.md: new session-4 START HERE (build the canonical-sig layer, then
  scale the wave); old demo-protocol START HERE marked superseded
- hand-matching-process.md S7: the Ultracode harvest wave (pipeline, calibration
  result 60% match_one / 33% whole-binary / +0.47%) + THE CANONICAL-SIG WALL (the
  60->33 gap is 100% sig conflicts; surgical per-callee canonicalization = ~2x lever)
- matching-cookbook.md S16: guided-hand-matching breakthrough + new idioms (mask-local,
  shared-ret0 goto, v0/v1 coalescing) + the wave/canonical-sig finding (R16 flywheel)
- SETUP.md: DecompileFunctions.java (headless batch Ghidra-C pre-pass) in the inventory (R21)
2026-06-19 21:16:41 -06:00
Drew T 0dd9bf6bac feat(phase-17): calibration harvest wave — fleet 55.04%->55.51% (+0.47%)
- Ultracode wave: 30 high-reach tractable residuals, parallel guided-hand-matching
  agents (m2c + Ghidra-C cache + asm + actor-struct + S1/S2/S3a playbook), self-
  validate match_one. 18/30 match_one MATCH (60%); 10/30 whole-binary verified (33%)
  after sig_unify recovered 2 -> all 10 propagated x134; 2 demo fns caught up
- 136/136 byte-identical (R22 clean check-all); REAL +1,610; 1421 dedup groups
- KEY FINDING: the match_one->whole-binary gap (60%->33%) is 100% SIG CONFLICTS
  (shared callees like func_80131CA8 declared inconsistently across parallel agents),
  NOT codegen. The canonical-sig layer (deferred as low-value) is the ESSENTIAL
  enabler -> would lift 33% toward 60%. 12/30 are the genuine gcc-quirk tail (DIFF).
- Ghidra pre-pass: tools/ghidra_scripts/DecompileFunctions.java (headless batch
  decompile -> .run/ghidra_c cache; no /mcp needed); 300 tractable targets sized
- harness: .run/harvest_wave_s3.js (embedded-targets Workflow; args channel doesn't
  transit arrays). cost ~1.89M tokens / 30 fns
2026-06-19 20:54:45 -06:00
Drew T 28c23f4be8 feat(phase-17): task-1 — bank func_8015F9A4 (fnptr close) + firm the rate
- func_8015F9A4 byte-matched + banked inline in ov_SC01_077 (whole-binary gate
  d19c9580, BYTE-IDENTICAL); a near-clone of the demo's func_8015F89C fnptr close
  -> fnptr-call class confirmed reliably closeable (2/2)
- firmed the rate: loop reconstructs CORRECT bodies 4/4, but byte-close is gcc-quirk
  bound. func_8014C308 (relocs=0, x134) structurally perfect, v0/v1 regalloc only
  (permuter stuck 455->140); func_80130AF0 (x134) body-100% but S10 delay-slot remat;
  func_8016B4F8 phantom -O2 frame. Drafts in .run/demo/ (gitignored)
- new reusable idioms (hand-matching-process.md S2): mask-local (defeats lh->lhu fold),
  shared-ret0 goto (cross-jump clustering + branch polarity)
- harvest sizing (S6): tractable easy classes are LOW-reach (fnptr 0.1%, void-widen
  0.3%); the x134 yield is locked in quirk-heavy STRUCTURAL_MISS (7.6%)/PERMUTER_CLASS
  (3.6%). Permuter route refuted (T6 callee-inlining + func_8014C308 slow). Lever =
  Ultracode guided-hand-matching wave on the high-reach tractable subset
- plan revised (Drew, A-only): harvest tractable first; giant func_80144B9C deferred
2026-06-19 20:06:33 -06:00
Drew T 19f005ea11 feat(phase-17): guided hand-matching demo — GO; 4/5 close-rate; loose-typing wall breakable
Pivot from the failed brute-force to the Ghidra-driven hand-match loop (Drew's steer).
DEMO sampled 5 residuals; 4 reached full whole-binary byte-matches:
- func_8012D3B4 (PERMUTER_CLASS) — closed + propagated x134 (DEFINE_func_8012D3B4)
- func_8012832C (STRUCTURAL_MISS switch) — closed
- func_8015F89C (fnptr-call, §15-S2) — closed
- func_80147B5C (pure struct) — closed (first try)
- func_8012A328 (STRUCTURAL_MISS) — 60/60 structure + correct regs, 1-instr gcc
  placement quirk (the §10 hard-tail minority; permuter floor-polluted)

KEY FINDING: the Phase-16 "loose-typing wall" is a signature-CONSISTENCY problem, not
fundamental — resolved by a 5-move playbook (return-widening void->s32; sign cast (u16);
arity cast — refines the §14e arity dead-end; param-canonical-matching; fn-ptr-table
typing), all byte-neutral.

- canonical-widenings (byte-neutral, fleet re-verified): engine_core.h RotTransPers +
  func_80029504 -> s32; ov_SC01_077.c func_801288B0/801289F0 -> s32
- docs/hand-matching-process.md (NEW): full replicable process + idioms + the §3a
  playbook + current banked state + automation roadmap (fresh-session-safe)
- fleet: make check-all 136/136 byte-identical (R22); 55.00% -> 55.04%; dedup-check 1409/0
- config/dedup.us.yaml: +1 group (func_8012D3B4, 134 members)
- CURRENT_PHASE.md progress log updated
2026-06-19 18:03:49 -06:00
Drew T 1431b523a4 feat(phase-17): T4+T5 — actor struct recovered (comprehension) but byte-neutral for matching
- recovered the engine actor/player struct cold via PCSX-Redux (R10/R11): base 0x80078E00,
  ~154 fields over 0x24C bytes, 32 pointer fields; HP/BP/gold/day/hour/position/BP-drain all
  live-verified and anchored to the Phase-3 player state + the walk diff. -> docs/actor-struct.md
- tools/ram_probe.py: PCSX-Redux RAM capture/diff/read/ptr-scan workhorse for field-typing
- FINDING (the matching verdict): feeding the struct to m2c as --context is BYTE-NEUTRAL.
  m2c adopts it (arg0->f_X) but structural-miss sample scores 0 better / 10 same / 2 worse vs
  m2c-alone (full code+RAM pointer set). The misses are 50-98% mismatched = m2c decompiler
  limits, not missing types. T4 fn-ptr context unblocks compilation but functions stay structural.
- conclusion: rich context (struct/type recovery) is a comprehension / decomp.me win, NOT a
  byte-match lever -> Phase-16 wall re-confirmed from the type angle. struct-core-pivot.md updated.
- emulator field-naming pass deferred (comprehension, off the matching path); NEXT: T6 permuter
  validation on the 146 genuine near-misses, then T7 go/no-go.
2026-06-19 13:03:14 -06:00
Drew T 070cf375c9 feat(phase-17): T3 — bank 42 sig_unify matches + propagate x134 (fleet 54.48%->55.00%); fix taxonomy classifier
- banked 42 gate-proven SIG_FIXABLE_KR matches in ov_SC01_077 (of 48 predicted; 6 honestly
  reverted by the whole-binary byte-gate, P9) + propagated 13 h_exact-shared x134 via
  dedup_propagate (one body -> 134 overlays, each byte-gated, fail-closed)
- fleet byte-identical-from-source 54.48% -> 55.00% (+0.52%); REAL +1,778; dedup groups
  1395 -> 1408; make check-all 136/136 byte-identical (R22); dedup-check 1408 validated/0 failed
- wall probe (R14): raw drafts 0/99 + sig_unify fails -> the K&R/sig_unify avenue is exhausted;
  the residual conflict-class is ARITY_WALL (the §14e param-count dead-end) or structural (T4/T5)
- FIX a T1 classifier bug surfaced by verifying the wall vs the bytes: tu_compile_error captured
  the baseline's pre-existing byte-NEUTRAL warnings ("makes integer from pointer", cc1 rc=0) and
  mislabeled 99 fns LOOSE_TYPING_WALL; now keeps only non-warning errors -> there is NO loose-typing
  wall, the real residual wall is ARITY_WALL=74. docs/wall-taxonomy.md amended with the correction.
- 134 overlay .c files carry the propagated DEFINE_func instantiations; a one-time full-fleet
  make extract was required for the per-overlay propagation gate + check-all
2026-06-19 12:13:38 -06:00
Drew T edb0360d30 feat(phase-17): T1 wall taxonomy — census the 957 residuals, size every avenue (skip T2)
- tools/wall_taxonomy.py: full-census classifier (m2c --valid-syntax -> match_one ->
  sig_unify + full-overlay-TU cc1) labels every unmatched ov_SC01_077 stub by blocker
  class; reproducible (~22s, --jobs 16); read-only (throwaway _wt_*.c, auto-removed)
- docs/wall-taxonomy.md: ranked taxonomy + per-lever aggregation + sequencing recommendation
  (957 residuals, 99.2% carry an actionable label)
- findings (byte-gate-validated, R14: SIG_FIXABLE_KR = exactly the 4/4 gate-passing set):
  - T4+T5 rich context (struct/jump-table/fn-ptr-table types) = 67% reach, incl. all 30 jtbl giants
  - T6 permuter = 146 candidates (101 <=4-mismatch near-certain)
  - T3 sig_unify = 48 gate-proven immediate wins
  - loose-typing WALL = 99 (10%); non-faithful defer = 16
  - T2 DATA-symbol byte-array header = 0 functions -> SKIP (the cookbook §14c-c lever is empty)
- recommended resequence: T3 -> T4+T5 (built together) -> T6 ; drop T2 (pending Drew's P5d nod)
- struct-core-pivot.md: Phase-17 quantification note; CURRENT_PHASE.md: T1 done + resequence
- all binaries byte-identical (T1 read-only; ov_SC01_077 d19c9580 clean rebuild)
2026-06-19 11:31:41 -06:00
Drew T 9062f0fcc0 docs(phase-16): PIVOT — m2c+permuter won't crack the loose-typed core; new plan + harness fixes
- docs/struct-core-pivot.md: findings + decision + new research directions. Root cause = the
  original engine is LOOSELY TYPED (K&R; same fn called with int/ptr, arg/no-arg across sites),
  so no single canonical signature exists -> m2c guesses inconsistently, permuter can't fix
  semantics, byte-gate (correctly) rejects. Yields ~3%, not the crack. New plan: emulator-recover
  the actor struct/types -> Ghidra global type propagation -> Ghidra-C -> permuter+gate.
- harness bug-fixes (REAL, kept): p16_permute output-0-only match (killed the false '42%'),
  base.c keeps callee externs, winner_to_draft line-strip; sig_unify canonicalizes m2c's
  no-extern prototypes; gen_engine_decls.py (documents why a global canonical header breaks
  loose-typed matches).
- a few byte-gated leaf matches banked in ov_SC01_077.c.
2026-06-19 10:05:58 -06:00
Drew T 7141e9752b feat(phase-16): S0 close + S2 foundation — m2c-compat in common.h (byte-verified)
- S0 (cookbook §15): ran m2c on real ov_SC01_077 stubs (R14). Finding: m2c
  --valid-syntax output COMPILES via m2c_macros.h (M2C_FIELD = byte-faithful cast);
  30/30 sampled targets use only byte-faithful macros. Compiling != matching: the
  residual is regalloc/schedule -> decomp-permuter is the byte-closer; struct types
  are an enhancer, not the sole gate (S3/GATE-B measures the lift). ML parked (owner).
- common.h: add s64/u64/f64 + M2C_UNK* typedefs + byte-faithful M2C_FIELD/M2C_BITWISE
  macros (non-faithful m2c macros left UNDEFINED = early 'defer' signal). Byte-neutral:
  main 143dbb89 (clean rebuild, R22), resident 8e17e02f, ov_SC01_077 d19c9580 all OK.
- CURRENT_PHASE.md: Phase 16 plan + S0-S9 gated tasks + Sun-afternoon timeline +
  known-answer oracle test method.
2026-06-18 22:32:03 -06:00
Drew T 964cec8b61 docs(phase-15): close — PhaseEnd v1.14.0 (fleet 54.48%), continuation backlog -> Phase 16
- PhaseEnd_Phase15.md: synthesis of the open-ended overlay long-tail phase (136 binaries
  byte-identical from clean; fleet 3.82% -> 54.48%); CURRENT_PHASE.md archived -> logs/Phase15.md (R19)
- the final-session finding: deterministic recovery (sig_unify + find_site fix) beat a 50-agent
  wave ~7x/token (+2.67% vs +0.36%); cookbook §14d (the recovery) + §14e (() / m2c-struct dead-ends)
- Continuation Backlog -> Phase 16 'Crack the struct-heavy shared core': the actor-struct ->
  m2c-context -> permuter compute pipeline (+ multi-day autonomous run), the 28 giants, decomp.me,
  emulator capture, ML/CUDA wildcard, the arity-conflict dead-end
- SETUP tool inventory (sig_unify + recovery tools); gen2-roadmap Phase-15 CLOSED + Phase-16 added
- bumps project version 1.13.0 -> 1.14.0
2026-06-18 21:01:38 -06:00
Drew T ab8b857cd3 feat(phase-15): engine_types follow-up — +1 struct-using shared fn; fleet 54.44% -> 54.48%
- additive engine_types.h: +1 named type (43 total); 12 local-type skips remain
  (anonymous/typedef'd types the extractor can't lift)
- propagated 1 more struct-using shared fn fleet-wide; dedup-check 1395/0
- R22 clean fleet rebuild 136/136 byte-identical
2026-06-18 20:23:21 -06:00
Drew T a10f7f8a1a feat(phase-15): sig-unify recovery + find_site brace-fix — fleet 52.08% -> 54.44%
- tools/sig_unify.py (NEW): unifies a draft's FULL signature set to the banked-canonical
  decls — both callee externs AND the draft's OWN definition signature (return + param
  types, body param-names preserved). Recovery for the standalone-MATCH residual: a probe
  found 30/30 sampled failures were type conflicts, 0 false-positives. Gated 191 -> 32 verified.
- tools/dedup_propagate.py find_site FIX: the inline-def detector required the opening brace
  ON THE SAME LINE as the signature, silently dropping every next-line-brace def from
  propagation (sig_unify/permuter outputs + ~stragglers all session). Now accepts brace on
  the same OR next line -> unlocked a 61-function propagation backlog.
- propagated 61 fns fleet-wide (incl. 32 sig-unify + the permuter win func_801508F8 +
  earlier-dropped next-line-brace matches), all 134 byte-identical; dedup-check 1394/0
- R22 CLEAN fleet rebuild: 136/136 byte-identical. REAL 177501 -> 185646. Zero agent tokens.
2026-06-18 20:00:50 -06:00
Drew T 4b0f4d1003 feat(phase-15): #3 types-header propagation — +8 struct-using shared fns; fleet 51.77% -> 52.08%
- fix tools/build_engine_types.py to be ADDITIVE: merge new source types with the
  types already in engine_types.h (a re-run after a prior --strip was destructive —
  it dropped the ~34 already-migrated types and broke the build; caught + reverted)
- engine_types.h 34 -> 42 named types (the 8 from wave-1's struct-using matches);
  inline defs stripped from ov_SC01_077.c (byte-neutral)
- dedup_propagate --auto-from: 8 of 15 struct-blocked matches now self-contained ->
  propagated across all 134 overlays (byte-gated); 7 remain (anonymous/typedef'd types)
- R22 CLEAN fleet rebuild: 136/136 byte-identical; dedup-check 1333/0
- zero agent tokens (deterministic)
2026-06-18 18:03:44 -06:00
Drew T be0ceae55d feat(phase-15): T6 wave-1 (50-agent) harvest — 27 shared fns matched, 9 propagated fleet-wide; fleet 51.41% -> 51.77%
- 50-agent Ultracode callee-sig-aware harvest of 300 reach-134 shared stubs in
  ov_SC01_077; whole-binary byte-gate verified 27 (26 + 1 canon-recovery), 273
  genuine compiler-internal residual (recovery recovered only 1 -> confirmed permuter-class)
- dedup_propagate --auto-from: 9 self-contained matches propagated across all 134
  overlays (byte-gated); 15 verified use overlay-local types -> pending engine_types.h
- R22 CLEAN fleet rebuild: 136/136 byte-identical, 0 extract fails; dedup-check 1325/0
- NOTE: blind-draft shared-core harvest has hit diminishing returns (~9% gate yield);
  next work pivots to giants (match_one) + permuter + deterministic types-header propagation
2026-06-18 17:21:54 -06:00
Drew T 85b3599e5b feat(phase-15): T6 groups-of-10 missing harvest — fleet 48.02% -> 51.41% (over half)
- Drew's "groups of 10 instead of 100+": rebuilt the harvest workflow to process the 375
  never-drafted shared stubs (leaf-first) in SEQUENTIAL WAVES of <=10 agents (intra-wave
  retry). Result: 0 dead batches (vs 33 from a 48-batch burst), ~42 drafts/60s (vs ~1/45s)
  under the sustained server-side throttle; 374/375 drafted (+1 gap-fill found).
- gate: 85 verified -> 79 propagated fleet-wide (7 struct/local skipped), 134 overlays
  byte-identical; dedup 1237 -> 1316 groups, dedup_integrate --check 1316 validated / 0 failed.
- fleet REAL substantive ~164k -> 175,212; byte-identical 48.02% -> 51.41% (OVER HALF the
  matchable code across all 136 binaries rebuilds byte-identical from source).
- R22 clean rebuild: 136/136 byte-identical, 0 extract failures.
- cookbook §12: the rate-limit-gentle sequential-waves-of-10 pattern + leaf-first ordering.
2026-06-17 18:38:03 -06:00
Drew T 5c5e9fb973 feat(phase-15): T6 struct follow-up — shared engine_types.h unblocks 37 struct-using fns; fleet 46.27% -> 47.70%
- tools/build_engine_types.py -> src/shared/engine_types.h: extract the 34 named struct/union
  types from ov_SC01_077.c (forward decls + defs in source order; consumes trailing
  __attribute__((packed)) + aliases through the ';'). 0 same-name-different-layout collisions.
- engine_core.h includes engine_types.h; the 34 inline defs stripped from ov_SC01_077.c
  (byte-neutral — type defs emit no code; verified byte-identical).
- dedup_propagate.py: relax the struct guard to skip only inline named-struct/typedef
  DEFINITIONS (header-type USAGES + anonymous local structs now propagate); add engine_types.h
  to the compile pre-filter so struct-using bodies resolve.
- 37 struct-using shared fns propagated fleet-wide (skip 41 -> 4 overlay-local typedef'd types),
  134 overlays byte-identical; dedup 1183 -> 1220 groups, 1220 validated / 0 failed.
- fleet REAL substantive 157,541 -> 162,462; byte-identical 46.27% -> 47.70%.
- R22 clean rebuild: 136/136 byte-identical, 0 extract failures.
2026-06-17 15:25:44 -06:00
Drew T 57a0a88f37 feat(phase-15): T6 tail — quarantine decl-recovery propagates 42 more; fleet 44.64% -> 46.27%
- canon_draft_decls recovery on the combined 505 quarantined drafts (285 small + 220 medium),
  now canonicalizing against the much-larger banked symbol set: 47 verified (no API), 42
  propagated fleet-wide (struct/local-type skipped), 134 overlays byte-identical; dedup
  1141 -> 1183 groups, dedup_integrate --check 1183 validated / 0 failed.
- fleet REAL substantive 151,908 -> 157,541; byte-identical 44.64% -> 46.27%.
- R22 clean rebuild: 136/136 byte-identical, 0 extract failures.
- scoped the struct-using-shared-fn lever (read-only): 34 named struct/union types in 077,
  ZERO same-name-different-layout collisions -> a shared-types-header is a clean path to
  propagate the ~100 struct-using fns (next).
2026-06-17 15:06:29 -06:00
Drew T db4fddc44e feat(phase-15): T6g medium band — harvest+propagate 65 shared fns; fleet 42.14% -> 44.64%
- medium harvest (callee+data-sig-aware) on the 293 still-stub call-heavy fns (nins 41-150):
  30-agent Workflow + a 3-target gap-fill (mandatory produced-vs-expected reconcile). Gate:
  73 verified (25% — these are the harder GTE/matrix/regalloc functions; 220 quarantined to
  .run/drafts-T6c-fail for a later recovery pass).
- dedup_propagate.py: broaden the struct/union guard to skip ANY struct/union-touching body
  (not just definitions) — agents used colliding generic struct names in params/casts/externs
  too. 37 skipped; 65 propagated fleet-wide, 134 overlays byte-identical; dedup 1076 -> 1141
  groups, dedup_integrate --check 1141 validated / 0 failed.
- fleet REAL substantive 143,322 -> 151,908; byte-identical 42.14% -> 44.64%.
- R22 clean rebuild: 136/136 byte-identical, 0 extract failures.
- open tail (paused here): 285+220 quarantined drafts (regalloc/struct/§10 residuals), the
  struct-using shared fns (shared-types-header follow-up), 077-unique remainder, T7 giants.
2026-06-17 13:21:36 -06:00
Drew T bdfb86dc4f feat(phase-15): T6 v2 — data-sig-aware harvest + struct-guarded propagate; fleet 31.22% -> 42.14%
- gen_harvest_targets.py: now also resolves canonical DATA-symbol declarations per target
  (scan the .s for D_XXXX refs -> `extern <type> D_XXXX;` from banked code) in addition to
  callee function sigs — the §14c(c) fix at the source, so agents declare both functions and
  data correctly and avoid the dominant remaining conflict class.
- v2 harvest (callee+data-sig-aware) on the 591 small still-stub call-heavy fns + a gap-fill
  agent for 6 targets dropped by a connection-closed-mid-response failure (the retry-wave
  misses truncated-non-null results). Gate: 306 verified (ov_SC01_077 1554 -> 1248 stubs).
- dedup_propagate.py: skip any struct/union-touching body — agents named structs with colliding
  generic names (`struct S`/`struct vec`) inline, so two macros' types redefine/conflict when
  instantiated in one overlay (ov_SC01_000 abort). 34 skip; struct-using shared fns stay banked
  in 077 (shared-types-header follow-up).
- 281 functions propagated fleet-wide (134 overlays each, every overlay byte-gated); dedup
  795 -> 1076 groups, dedup_integrate --check 1076 validated / 0 failed.
- fleet REAL substantive 105,764 -> 143,322; byte-identical 31.22% -> 42.14%.
- R22 clean rebuild: 136/136 byte-identical, 0 extract failures.
- cookbook §12: gap-fill is now a MANDATORY post-step for every multi-agent run (reconcile
  produced-vs-expected: missing + truncated drafts) before gating.
2026-06-17 11:59:33 -06:00
Drew T 1d94f9ec96 feat(phase-15): T6d — deterministic decl-canonicalization recovers 19 more shared fns; fleet -> 31.22%
- tools/canon_draft_decls.py: rewrites a quarantined harvest draft's extern/data
  declarations to the banked-consistent set (functions from engine_core.h DEFINE
  bodies / extern decls / inline defs; data from existing `extern <type> D_XXXX;`),
  so a draft whose BODY is byte-correct (passes match_one) but whose DECLARATION
  collided with already-banked code can re-gate cleanly. The whole-binary
  harvest_verify byte-gate stays the sole arbiter — a semantics-changing
  canonicalization just fails and reverts.
- recovered 19 of the 90 match_one-MATCH-but-conflicting quarantined failures
  (no API — immune to the rate limiting), propagated fleet-wide, all 134 overlays
  byte-identical; dedup 776 -> 795 groups, 0 failed.
- fleet byte-identical 30.48% -> 31.22%; ov_SC01_077 1574 -> 1535 stubs.
- R22 clean rebuild: 136/136 byte-identical, 0 extract failures.
- the remaining ~70 match_one-MATCH residual needs definition-widening (§14c(d),
  narrow-return) or true data-type resolution — queued for the next pass, with the
  un-started medium band (430) and the 54 genuine instruction-misses (permuter/§3a).
2026-06-17 00:30:45 -06:00
Drew T ef1cf9f05e feat(phase-15): T6 pass-1 — callee-sig-aware harvest of the call-heavy shared core; fleet 25.38% -> 30.48%
- tools/gen_harvest_targets.py: callee-signature-aware target manifest (the §14b
  extern-conflict wall-breaker). Pre-resolves each callee's EXACT signature from
  engine_core.h DEFINE bodies + extern declarations + inline defs, so drafts never
  emit a conflicting extern. Lifted call-heavy gate yield from the §14b-naive 16%
  to 60-67%.
- ov_SC01_077: 142 functions banked (1716 -> 1574 INCLUDE_ASM stubs) via the
  Ultracode parallel-draft + harvest_verify byte-gate loop (cookbook §12). The
  draft Workflow was throttled by server-side API rate limiting (stopped at
  ~246/616); the incremental gate -> dedup_propagate loop is deterministic and
  throttle-immune, so the wins banked steadily regardless.
- dedup_propagate --auto-from ov_SC01_077: ~132 functions propagated fleet-wide
  (134 overlays each), every round per-overlay byte-gated; dedup 644 -> 776 groups,
  dedup_integrate --check 776 validated / 0 failed.
- fleet REAL 85,651 -> 103,217; byte-identical 25.38% -> 30.48%.
- R22 clean rebuild: make clean + extract all 136 + check-all = 136/136 byte-
  identical, 0 extract failures.
- cookbook §14c: the wall-breaker + the 4 conflict flavors (defined / declared /
  DATA-symbol / narrow-return-widening) + the never-git-checkout-mid-harvest
  hazard + the rate-limit-resilient incremental loop. Residual = the data-symbol
  conflict class (structural canonical-decls fix queued for next pass) + the
  un-started medium band (430).
2026-06-17 00:12:23 -06:00
Drew T 9d5c087054 feat(phase-15): T5b pass-2 leaf-first harvest (+34 shared fns); fleet 25.38%
- leaf-first pass: 52 pure-LEAF unmatched-shared funcs (no jal/%hi/%lo -> match_one is an
  exact gate); 5-agent Ultracode Workflow -> 36/52 verified (69% yield, vs 16% mixed) ->
  34 propagated fleet-wide (644 groups, dedup-check 0 failed); R22 clean 136/136
- fleet REAL 81,093 -> 85,651; byte-identical 24.05% -> 25.38%
- pure leaves now ~exhausted; remaining shared core is call-heavy (extern-conflict wall)
- CURRENT_PHASE.md: RESUME HANDOFF for a fresh session (T6 callee-aware harvest, T7 giants
  + per-overlay unique, then T8 PhaseEnd) — no PhaseEnd this session (Drew)
- ghidra/ churn NOT staged (R23)
2026-06-16 22:18:06 -06:00
Drew T 2ac97878b2 feat(phase-15): T5b — Ultracode harvest pass 1 (+49 shared fns); fleet 24.05%
- 25-agent Workflow drafted + match_one-verified 300 small unmatched-shared functions;
  harvest_verify byte-gate in ov_SC01_077 verified 49 (byte-identical d19c9580);
  dedup_propagate spread them fleet-wide (610 groups, dedup-check 0 failed)
- fleet REAL 74,527 -> 81,093; byte-identical 22.14% -> 24.05%; R22 clean 136/136
- yield 16% = the call-heavy hard tail: match_one masks jal/HI16/LO16 (false MATCH on
  call-heavy fns); real misses are the extern-type-conflict wall (draft callee extern
  != the callee real macro signature). Leaf fns matched; call-heavy = open-ended tail.
- cookbook 14b documents the wall + the path forward (leaf-first, callee-signature-aware
  drafting, link-gated per-fn check)
- ghidra/ churn NOT staged (R23)
2026-06-16 21:16:46 -06:00
Drew T aefe2eac18 feat(phase-15): T5a — bulk-propagate 553 shared functions fleet-wide (3.82% -> 22.14%)
- dedup_propagate --auto-from ov_SC01_077: propagated 553 already-matched, self-contained
  shared engine functions across all 134 overlays, each byte-gated. 9 functions skipped
  (use 077-local struct types -> not mechanically liftable; honest, P9). One R22 CLEAN
  rebuild: 136/136 byte-identical.
- fleet REAL 947 -> 74,527; byte-identical 13,132 -> 76,174 / 344,010 = 22.14%; 561 dedup
  groups, dedup-check 561 validated / 0 failed
- tool hardening for fleet scale: registry SHORTHAND (vram + binaries; dedup.us.yaml ~4k
  lines vs ~77k verbose); per-overlay apply (one read/write per file); gate-only-changed;
  skip already-registered (additive/resumable); compile pre-filter (body must build with
  common.h alone); group_members() reader (both forms) in dedup_integrate + progress;
  progress _DEDUP_CACHE (fleet 6m -> 7s)
- the first bulk attempt fail-closed-reverted on a local-typed body (byte-gate working) ->
  added the compile filter; cookbook 14a documents the 5 fleet-bulk lessons
- ghidra/ churn NOT staged (R23)
2026-06-16 20:35:39 -06:00
Drew T c716eb15e1 feat(phase-15): T4 — fleet progress roll-up + fix cross-report double-count
- progress.py: refactor to report(binary) + set_binary() + a per-binary .s index
  (fleet run 6m38s -> 7s); add --fleet -> docs/progress.fleet.md (deterministic,
  source-derived per-binary table + fleet totals). Single-binary output byte-unchanged.
- fleet now: 947 REAL / 959 LINKED / 13132 byte-identical / 344010 matchable = 3.82%
  across 136 binaries (main + resident + 134 overlays)
- dup_report --cross: HONESTY FIX (R14) — an onboarded overlay is both a named BINARIES
  entry AND a .run/sig.ov_* glob hit; it was counted twice, inflating collapsible bytes
  to 58.7M once the fleet was onboarded. Dedupe by alias -> accurate 9366 h_exact groups
  / 28.6M collapsible (matches the Phase-11 figure)
- Makefile: wire progress.py --fleet into make report (main-only block)
- docs: progress.fleet.md (new), duplicates.cross.md regenerated, SETUP inventory
- make report green; dedup-check 8 validated / 0 failed
- ghidra/ churn NOT staged (R23)
2026-06-16 20:00:19 -06:00
Drew T 0c7619231d feat(phase-15): T2 — dedup_propagate.py (match-once -> propagate-many) proven on wave
- tools/dedup_propagate.py: lift a matched body -> DEFINE_func_<ADDR>() macro in
  src/shared/engine_core.h -> instantiate in place at every onboarded overlay sharing
  that h_exact -> snapshot + per-overlay byte-gate (fail-closed revert) -> register in
  config/dedup.us.yaml. Keyed by addr-int (sig lowercase vs splat func_%08X).
- proof: 4 medium funcs propagated across all 16 onboarded overlays; clean check-all
  18/18 byte-identical; dedup_integrate 8 validated/0 failed; idempotent; negative test
  (corrupt shared body) -> make check FAILS then restores
- Makefile: header-dependency tracking (cpp -MMD -MP + -include ) so editing a
  shared header recompiles dependents — closes a stale-build/false-pass gap the negative
  test exposed; output-neutral (R22 clean 18/18)
- structural self-check: a leftover INCLUDE_ASM stub is byte-identical, so the byte-gate
  can't catch under-application -> assert DEFINE present + stub gone
- FINDING: 577 of ov_SC01_077's 785 matches are h_exact across all 134 overlays
  (2.19 MB collapsible, already matched) -> T5 = bulk-propagate these + harvest the rest
- cookbook §14 (the propagation runbook + gotchas), SETUP tool inventory
- ghidra/ churn NOT staged (R23); build/asm/.run gitignored
2026-06-16 19:24:08 -06:00
Drew T 324ad1c3a6 docs(phase-15): T0 — defer Phase 14 to Gen3+; Phase 15 is the active phase
- gen2-roadmap: mark Phase 14 (public flip) DEFERRED to Gen3+ (Drew 2026-06-16)
  across header rev, phase table, Phase-14 detail, EXIT criteria (crit 5 parked),
  critical-path, and Phase-15 (now ACTIVE) detail/deps — additive, text preserved (H5)
- CURRENT_PHASE.md: Phase 15 kickoff log (approved plan, verified ground truth,
  task list T0-T8, milestone, strategy: match-once -> propagate-many)
- ghidra/ DB churn deliberately NOT staged (R23 noise; Ghidra-free phase)
2026-06-16 18:57:06 -06:00
Drew T 52514b5f45 docs(phase-13): T6 docs — cookbook §13 overlay runbook + SETUP/gen2-roadmap + digests
- cookbook §13: the canonical add-an-overlay runbook (new_overlay.sh, the flat-blob
  config, the non-4-aligned bin-carve/asset/trim gotcha, A->B->C workflow, dedup-credit
  two shapes, build-all/check-all) — the Phase-15 fleet recipe
- SETUP tooling inventory: tools/new_overlay.sh (R21)
- gen2-roadmap Phase-13 milestone: ACHIEVED amendment (6 binaries byte-identical,
  704 harvested, dup-pair collapse, T7 effort finding)
- regenerated per-overlay progress/difficulty/duplicates digests + cross report
2026-06-16 17:56:38 -06:00
Drew T 7622ea7609 feat(phase-13): T7 — effort experiment (Max vs Ultracode yield = noise) + bank 14
Controlled: 80 fixed SC01/077 fns (nins 8-15), identical blind-draft Workflow,
only session effort varied. Arm A (Ultracode/xHigh) 13/80, Arm B (Max) 14/80;
A∩B=12. 13-vs-14 = noise -> per-agent depth does NOT change blind-draft harvest
yield; the 'pass 1 Max did better' observation was difficulty-confounded.
DECISION: prefer Ultracode for breadth harvests (same yield + orchestration),
Max for deep synthesis. Banked Arm B's 14 -> ov_SC01_077 REAL 704 (byte-identical).
(scriptPath re-invoke didn't forward args -> Arm B overwrote Arm A's drafts dir;
Arm A was already gated/recorded, so the comparison stands; 1 A-only fn unbanked.)
finding -> docs/effort-map.md (Evidence section)
2026-06-16 17:50:31 -06:00
Drew T b2773874d0 docs(effort-map): per-task effort mapping + pause-at-every-transition discipline (Drew) 2026-06-16 17:23:07 -06:00
Drew T 67592993ea feat(phase-13): T3+T4 — new_overlay.sh + dup-pair & free-roam onboarded byte-identical
- tools/new_overlay.sh: one-command overlay onboarding (template instantiate +
  @TRAILING@ carve + overlays.mk + 4-dict sentinel-insert + extract/build/check);
  idempotent (re-run = no-op, no dupe entries)
- T3: ov_SC03_001 (free-roam, 815,887 B) byte-identical f8fd92f5
- T2 (onboard): ov_SC01_005 + ov_SC01_006 (byte-identical pair) both 56760dbe
- template tokens unquoted (correct YAML int types); SETUP §2.8 MCP-reconnect note (R21)
- 6 binaries now build byte-identical (main, resident, 4 overlays)
2026-06-16 16:44:01 -06:00
Drew T b7b34f007e docs(phase-12): PhaseEnd — key engine systems complete; resident 1.4%->85.6% (v1.12.0)
Phase 12 close (milestone confirmed by Drew, gate 2):
- resident engine REAL 1 -> 123/146 = 85.62% byte-identical, 0 NON_MATCHING; both binaries
  byte-identical from a clean rebuild (resident 8e17e02f, main 143dbb89)
- pivots (byte-driven, Drew-approved): T1 the resident has NO PsyQ library footprint (all
  custom engine code, REAL not LINKED); T4 NO bytecode VM (script/event = compiled-MIPS
  fn-ptr-table dispatch, byte-backed); T5 save format documented, deep data + SaveLoadRoutine
  code-match honestly deferred (Gen3/P9)
- method: Ultracode harvest = swarm parallel-draft + incorruptible byte-gate (5 passes) +
  match_one iteration loop + extern-conflict recovery; tools harvest_verify.py + match_one.py
  (-> Phase 13). cookbook §12, R26 (prompt for ultracode on breadth)
- gen2-roadmap milestone + EXIT criterion #2 AMENDED (script/event resolved; save documented)
- PhaseEnd_Phase12.md; CURRENT_PHASE.md archived -> logs/Phase12.md (R19); README status
- rule R26; bumps project version 1.11.0 -> 1.12.0
2026-06-16 14:42:52 -06:00
Drew T 373418dc8d docs(phase-12): T5 — save trace findings (memcard path + directory confirmed; deep data deferred)
Live save-to-slot-1 trace via the PCSX-Redux web API confirmed the memcard path
bu00:BASLUS-00726MUSASHI (libmcrd) + the directory/title-frame staging in low RAM. The
save-DATA serialization couldn't be isolated from a live before/after diff (running-game
churn; the one big changed region @0x8007CD28 is an unrelated UI list). Clean route = the
.mcd file / a paused capture -> deferred as Gen3-repack territory, NOT needed for the
SaveLoadRoutine byte-match (code-level). SaveLoadRoutine stays the documented hard-defer
(1139-ins multi-entry, Gen1 precedent, P9).
2026-06-16 14:33:54 -06:00
Drew T d443cdf433 docs(phase-12): T5 (static start) — save/memcard format: saveHeaderTemplate + handler table (Q#5)
formats.md §6: SaveLoadRoutine @0x8002B154 = multi-entry save/load blob driving the linked
PsyQ libmcrd primitives; saveHeaderTemplate @0x80072DF0 decoded — memcard filename
"BASLUS-00726MUSASHI", SJIS title "BRAVE FENCER MUSASHI", and a @+0x54 handler DISPATCH
TABLE of 0x8002Bxxx pointers (the "multi-entry blob" IS this table of save/load sub-handlers).
Static layout VERIFIED. TBD (needs Ghidra-on-EXE + a Drew-operated PCSX-Redux save trace +
PsyQ-memcard CRC research): the save-DATA serialization (player/progress state 0x80078Exx +
checksum) + matching the tractable handlers. ram_savescreen.bin holds the live header.
2026-06-16 14:18:47 -06:00
Drew T 9a70f7179c docs(phase-12): T4 — script/event system + SQV driver determinations (byte-backed)
- memory-map.md: RESOLVE the "Script VM instruction set" open question — BFM has NO bytecode
  VM. "Scripting" is compiled-MIPS state machines dispatched via function-pointer tables
  indexed by game-state vars, proven by the matched resident dispatchers (D_800D3430[
  D_800B99F0](), D_800D3480/3488/3490[state](), the func_800D2Fxx cluster) mirroring the EXE's
  GameModeDispatch[gameMode](). Overlays = compiled MIPS that call the resident, not bytecode.
  Basis for the gen2-roadmap criterion #2 amendment (T6).
- formats.md §5: SQV driver = semi-custom — thin Square wrappers/glue over stock PsyQ libsnd;
  DsMix @0x800D1BD8 is a custom 2-line wrapper (NOT stock libsnd; the 4.7 sig was coincidental,
  T1). Bytes matched in the harvest; deep playback semantics deferred (Gen3, not needed for the
  byte-match).
2026-06-16 14:14: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 e3d86e6077 docs(phase-12): cookbook §12 (ultracode harvest pattern) + effort-map ultracode-prompting (R16/R21)
- matching-cookbook.md §12: the parallel-draft + deterministic byte-gate + match_one
  iteration loop that took the resident 1.4%->71.7% in one session. The pipeline (Workflow
  draft -> harvest_verify.py gate -> redraft passes -> match_one.py iterate), retry-wave
  resilience, the two TU gotchas (inline-typedef strip; standalone-MATCH-but-build-FAIL =
  extern-type conflict -> unify types), and the idioms the swarm surfaced (void-dispatcher-
  is-s32, struct-copy prologue, *10->2x+8x, masked-andi-range, callee-return-type-forces-cast).
- effort-map.md: standing instruction to PROACTIVELY prompt Drew to enable /effort ultracode
  on breadth-shaped stretches during a Max session (with the Phase-12 evidence), keeping the
  deep single-thread tasks at Max. Memories: ultracode-harvest-pattern, effort-prompt-
  ultracode-on-breadth.
2026-06-16 13:28:46 -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