17 Commits

Author SHA1 Message Date
Drew T 1e843c607a feat(phase-32): T2b (4) — SC03/56 ONBOARDED as md_SC03_056 @0x801CBB50 (ov_SC03_002's DESTPTR), byte-identical bc768a6b; ALL FIVE parked payloads are now binaries (fleet 213 -> 218); evidence tool v2
- md_SC03_056 (TEXT_LO 0x4, 4 stubs / 61 ins): 15/17 pointers cluster inside at 0x801CBB50; one outward call
  (0x8018151C) hits a function only 3 overlays have, ov_SC03_002 among them; req_fit 9/9 for ov_SC03_002
- payload_base_evidence.py v2 (controls 7/7 throughout): (a) STRONG = internal jals + fn-ptr-table entries on the
  module's own starts >= 2 (SC03/53 STRONG); (b) OUTWARD-EXPLAINED — a pure jal-vote base whose "internal" targets
  are function starts of the fleet's overlays is downgraded: SC03/56's 0x80178C8C was two SHARED-engine functions
  spaced like two of its five starts (and nobody's DESTPTR), a false STRONG; (c) the requester cross-check is
  informational only — shared engine code makes every requester fit (an R39 control caught it scoring: 6/7)
- memory-map §S45 p7 amended: all five rows ONBOARDED + the two instrument findings (the first build is a NULL
  oracle for FINE base errors — +8 builds byte-identical, +0x1000 fails the link; outward-explained vote bases);
  SETUP row amended. The parked-for-L3 ledger is EMPTY pending `make audit-disc` (T2c).
2026-09-04 23:52:58 -06:00
Drew T b52d67be0b feat(phase-32): T2b (3) — SC03/53 + SC03/54 ONBOARDED as md_SC03_053 / md_SC03_054 @0x801EF468 (the script slot), byte-identical c0848f30 / 06bd73df
- md_SC03_053 (TEXT_LO 0x4, 15 stubs / 372 ins) and md_SC03_054 (TEXT_LO 0xF0 — a 19-entry fn-ptr header, 7 stubs
  / 764 ins) share ov_SC03_001's DESTPTR slot 0x801EF468, the slot the S45 tracer watched other SC03 scripts load into
- BASE EVIDENCE (memory-map §S45 p7, static-derived STRONG at 0x801EF468 and nowhere else): SC03/53 — 52/75 absolute
  pointers inside, 3 of them + its one internal jal exactly on its own function starts (0 at every rival); SC03/54 —
  106/115 pointers inside, 5 header-table entries exactly on starts (0 at every rival); lui 0x801F ×18 / ×46
- first builds byte-identical (base-lenient, R34 — the base rests on the alignment; the first internal-call C bank
  byte-proves it); the §S45 p6 "onboard at 0x801EF468, let the first build decide" step, finally run
2026-09-04 23:51:45 -06:00
Drew T 10aaf5c296 feat(phase-32): T2b (2) — MAIN/9 ONBOARDED as md_MAIN_009 @0x800CD348 (TEXT_LO 0x3C), byte-identical d270f695; the OPDEMO1 module leaves the parked ledger
- tools/new_binary.sh md_MAIN_009 extracted/retail/MAIN.CD.dir/FILE_009.dir/0.1 0x800CD348 0x3C -> first build
  BYTE-IDENTICAL sha d270f695b793b5c03db159b7aabcc066daa87eda; 11 stubs (609 ins); window 0x800CD348..0x800CDD38
  lies below the resident's symbol region, so the default symbol stack stands (no A4 edit)
- BASE EVIDENCE (memory-map §S45 p7, static-derived STRONG): 6/6 internal jals and 9/9 absolute pointers land
  on the module's own function starts at exactly ONE base, 0x800CD348 — inside slot B's region (+0x82C from
  0x800CCB1C), not a previously known slot; lui 0x800C/0x800D ×51. Same caveat as md_MAIN_007: the first build
  is base-lenient (R34), the base rests on the alignment and will be byte-proven by the first internal-call C bank.
2026-09-04 23:51:08 -06:00
Drew T 1a696a851a feat(phase-32): T2b (1) — MAIN/7 ONBOARDED as md_MAIN_007 @0x800CEDF8 (TEXT_LO 0x34), byte-identical 2ff702b6; the OPDEMO0 module leaves the parked ledger
- tools/new_binary.sh md_MAIN_007 extracted/retail/MAIN.CD.dir/FILE_007 0x800CEDF8 0x34 -> first build
  BYTE-IDENTICAL sha 2ff702b605ab5cfc18474c464c4c07e5f8ffd48c; A4 applied (symbols.resident.txt not stacked —
  the window lies inside the resident's symbol region), re-extract + rebuild byte-identical; 19 stubs (802 ins)
- BASE EVIDENCE (memory-map §S45 p7, static-derived): STRONG — 9/9 internal jals and 14/16 absolute pointers
  land on the module's own function starts at 0x800CEDF8 (the boot slot of md_MAIN_001/008/011); lui 0x800C/0x800D
- HONEST CAVEAT (R34, measured 2026-09-05): the all-INCLUDE_ASM first build is a NULL oracle for FINE base
  errors — the same payload builds byte-identical at 0x800CEE00 (+8) — and catches only GROSS ones (at +0x1000
  two internal jal targets leave the window: `undefined reference to func_800CEEA4/func_800CF3F4`, link fails).
  The base therefore rests on the static alignment, and will be byte-proven by the first C bank that calls an
  internal sibling. Controls: .run/P32/t2b/{control_full,control_fine}.log
- registered in modules.mk + the report/diff dicts (R36 citizenship asserted by tools-health at T2c)
2026-09-04 23:49:05 -06:00
Drew T 788f33d523 feat(phase-30 S45 L3-p3): SC02/9 = the Steam Knight boss module — decoded, captured, retro-verified, onboarded; parked = 5
- the gate DECODED from matched C (func_8012832C case 0x300E -> func_80128998 -> streaming
  API with &cdFileLocTable[144]) -> scene arithmetic named the 1ST-BOSS arena -> ONE targeted
  load captured it at 0x801E4C60
- RETRO-VERIFIED: Phase-3's dumps/ram_castle.bin (2026-06-14) holds it at the SAME address,
  same 6,764-B exact prefix — R10 two independent datapoints two months apart;
  bossHp_SteamKnight (0x801E4398) lives inside this module's image
- onboarded md_SC02_009 (id 0x3E, TLO 0x4): BYTE-IDENTICAL first build; fleet 213;
  R22 213/213; tools-health OK; audit-disc UNCLAIMED 6 -> 5, residue 0
- the last 5 (MAIN/7, MAIN/9, SC03/53/54/56) reclassified emulator->STATIC-RE targets with
  decoded leads (memory-map §S45 p3); loc-id map appended to docs/debug-menu-list.txt
- negatives banked: pause menu, memory-box prompt, new-game intro, high/low game, Minku
  spawn (slot-A actor 0x15 = md_MAIN_015 candidate naming)
2026-08-07 15:07:55 -06:00
Drew T fa7b9d4c71 feat(phase-30 S45 L3): the emulator tour — all 28 script modules + MAIN/3 onboarded; fleet 212, R22 212/212
- THE TOUR (Drew driving the retail debug menu; mode-7 hammer over the Redux web API):
  all 28 script modules captured live at four byte-verified per-chapter slots
  (SC03/73-79 @0x801EF468 ch2-period, SC03/132-138 @0x801E25E8 ch3, SC04/24-30
  @0x801E7B28, SC05/23-29 @0x801ED988); the routing law: debug-menu AREA selects the
  chapter, each CITY interior streams its own module (member k <-> interior k).
  md_MAIN_011/DISELECT byte-proven 24,236/24,240 in RAM; slots A/B/boot R34-verified live.
- MAIN/3 DISCOVERED: the main-menu module (id 0x39, 121,884 B), mis-bucketed as data by
  BOTH audit oracles; live byte-proven @0x800CEDF8 (42,632-B exact prefix); onboarded.
- 29 onboardings BYTE-IDENTICAL on first build -> fleet 212; R22 212/212 after three
  md_MAIN_003 catches: the A4 DsMix leak; an extract-order-sensitive splat boundary
  (bytes: a 1-word data sentinel in .text + fn at +4 -> pinned in symbols file);
  corpus.stubs now treats D_*/jtbl_* INCLUDE_ASM as blob includes (mirrors progress.py)
- module-id census (offline, disc-wide): 77 id-law code payloads, 0 further misses;
  SC03/55 = confirmed DATA. audit-disc: UNCLAIMED 34 -> 6, residue 0 — the 6 carry
  byte-checked negative evidence; next tier = the CD-read tracer
- docs: memory-map §S45 (slots + routing + debug-menu ops), disc-completeness S45
  addendum, decision-log R31 entry, docs/debug-menu-list.txt (Drew's transcription)
- .run/s45 evidence allowlisted (tour logs/scripts/rosters); 104 ram dumps LOCAL-ONLY
- new baseline: 93.8% instr / 95.68% fn / 87.2% distinct over 212
2026-08-07 14:03:51 -06:00
Drew T b15dae1077 feat(phase-30 S45 II.1b): SC07 module pair onboarded byte-identical at 0x801A00D8
- md_SC07_003 (345,132 B, text-lo 0xFC, 100 fns) + md_SC07_004 (365,152 B, text-lo 0x158,
  315 fns) — both BYTE-IDENTICAL on first build at the header-derived own slot
- independent first-prologue scan reproduced the plan's documented TLOs exactly
2026-08-06 12:37:24 -06:00
Drew T 85b526cddd feat(phase-30 S45 II.1a): all 38 MAIN modules onboarded byte-identical at the §S44 static addresses
- slot A 29/29 (md_MAIN_013..041 @ 0x800CAE08), slot B 6/6 (md_MAIN_042..047 @ 0x800CCB1C),
  boot trio 3/3 (md_MAIN_001 [=MAIN/0 twin], md_MAIN_008, md_MAIN_011 @ 0x800CEDF8) — every one
  BYTE-IDENTICAL on its FIRST build (byte-corroborating the §S44 loader table for slots A/B/boot)
- TLO roster derived from the §154 id-word law (.run/s45/derive_tlo.py): 0x4 default;
  011=0x7C, 025=0xC, 034=0x80, 039=0xC (first-prologue scan)
- new_binary.sh: module hdr carve is now a dot-typed .rodata PAIRED with the c segment —
  a header can hold a function's jump table (md_MAIN_034), and standalone rodata emits
  .L locals that don't cross objects; bin links in the data block (both refuted by bytes)
- A4 law: symbols.resident.txt dropped from the boot trio's stacks (windows inside the
  resident region; DsMix @0x800D1BD8 had minted a phantom fn boundary in md_MAIN_011) —
  re-extracted clean, all three byte-identical, phantom gone
2026-08-06 12:36:49 -06:00
Drew T f6bbe7272a feat(phase-30 S44 I.2a): the big 3 onboarded BYTE-IDENTICAL — ov_MAIN_012, ov_SC02_037, ov_SC03_107
- Three uncompressed (PAC type-1) overlays at the standard 0x80128158 slot, onboarded via the new
  tools/new_binary.sh, each byte-identical at 100% INCLUDE_ASM on the FIRST build:
    ov_MAIN_012  d6b3e8b9  (383,783 B, 2,324 fns)
    ov_SC02_037  b0c5394a  (661,903 B, 2,434 fns)
    ov_SC03_107  87d02b57  (474,087 B, 2,414 fns)
  This also BYTE-PROVES the statically derived base (the §S44 loader table + the 500:1 h_exact
  vote): a wrong vram could not have produced byte-identical images once symbols resolve.
- Fleet: 140 -> 143 binaries. audit-binaries currently FAILS on all three by design (no
  engine_core.h include yet — the SC07-blindness check working as built); dedup_extend is the fix
  and the next commit.
- Registered by the script: overlays.mk blocks, check.sha, symbols seeds, the 3 BINARIES dicts.
  family map regenerated (3,577 target families / 279 with a matched sib — the new binaries'
  members now visible).
2026-08-06 11:12:19 -06:00
Drew T 264fe6c115 feat(phase-27 T7): disc-completeness audit — onboard 4 hidden SC07 overlays (136->140) + the type sweep
The whole-binary byte-gate is structurally blind to code nobody onboarded (R34): check-all is
green over the onboarded set no matter what code sits unbuilt on the disc. This reconciles the
onboarded set against every code-bearing PAC payload.

- new_overlay.sh: optional [ENTRY] arg (default 0.4) reaches a non-0.4.dec payload. Onboarded
  ov_SC07_{006,007,010,011} from 1.4.dec (they put graphics at PAC entry 0, the code overlay at
  entry 1 — invisible to the 0.4 hardcode for a month). Each byte-identical (7ca772be / b3b95547 /
  d7b5875d / 9885af74). FLEET 136 -> 140; check-all 140/140 (T2's pass==N re-baselined cleanly).
  difficulty.py NOT in the insertion set anymore (it derives, T6) -> only 3 tool dicts touched.
- tools/disc_code_sweep.py: decode every payload (reusing sig_image.make_insn) and gate code on
  BOTH valid>=0.90 AND jr_$ra density>=0.01. The jr_$ra gate is decisive: isValid() alone flags
  389 false hits (type-0/2 structured data decodes ~100% valid but has ZERO returns); jr_$ra
  separates code (~2.9-3.4%) from data (0.000%), validated on positive+negative controls.
- FINDING (docs/disc-completeness.md): type-4 location overlays are COMPLETE (138/138). All other
  types are data EXCEPT type-1 = 40 code payloads, 1 onboarded (the resident), 39 HIDDEN
  resident-class modules (mostly MAIN.CD/FILE_XXX/1.1). They load at UNKNOWN addresses (not the
  shared overlay slot), so they are NOT mechanically onboardable — byte-verifying a build binary
  needs its load address (P9), knowable only by runtime RE (the Phase-3 method). Deferred with
  evidence, NOT force-onboarded at a guess.
- CONSEQUENCE: game-code TRUE 100% now spans 140 onboarded binaries PLUS ~39 type-1 modules
  pending load-address RE. The roadmap assumed 136 — this is a real re-baselining (the +4 overlays
  also add ~2.45 MB to the denominator; every family propagation is now x138). Flows to T10/T11.
- SETUP §6.3 tool inventory updated (R21).
2026-07-15 18:33:37 -06:00
Drew T 87136a024e feat(phase-15): T3 — onboard the remaining 118 overlays; full fleet 136/136 byte-identical
- onboarded all 118 not-yet-onboarded overlays via tools/new_overlay.sh (0 failed)
  -> fleet = 134 location overlays + main + resident = 136 binaries
- R22 CLEAN rebuild (make clean -> extract all 136 -> make check-all):
  136 passed, 0 failed of 136 -- every overlay byte-identical at 100% INCLUDE_ASM
  from a fully clean tree, 0 extract failures
- per-overlay config (splat.ov_*.yaml / check.ov_*.sha / symbols.ov_*.txt) +
  config/overlays.mk var blocks + the 4 report/diff BINARIES dicts auto-registered
  (sentinel-anchored, idempotent); src/ov_*/ stub records committed (harvest_verify
  reverts via git checkout, so the records must be tracked before any harvest)
- ghidra/ churn NOT staged (R23); build/asm/assets/.run gitignored
- report-digest regen (fleet-wide duplicates.cross.md + progress.fleet.md) is T4
2026-06-16 19:41:37 -06:00
Drew T e5a2bd4083 feat(phase-15): T1 — onboard diverse wave-1 (12 overlays); fleet 18/18 byte-identical
- onboarded ov_{SC01_000,SC01_001,SC02_000,SC02_003,SC03_002,SC03_006,
  SC04_000,SC04_018,SC04_019,SC05_000,SC06_000,SC07_000} via tools/new_overlay.sh
  — spans all 7 SC areas + 2 full duplicate pairs (SC02_000≡003, SC04_018≡019)
- each byte-identical at 100% INCLUDE_ASM (non-4-aligned auto-handled); no
  position-lock anomalies — the cross-shape risk is retired before the full onboard
- make check-all = 18/18 passed (main + resident + 4 prior + 12 new)
- config/overlays.mk + 4 report dicts auto-registered (sentinel, idempotent)
- ghidra/ DB churn NOT staged (R23); asm/build/assets/.run gitignored
2026-06-16 19:02:14 -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 144839f24b feat(phase-13): T1a/T1b — SC01/077 onboarded + all-asm byte-match (d19c9580)
- ov_SC01_077 scaffolded: config/overlays.mk (OVERLAY_BINARIES + var block),
  config/splat.ov_SC01_077.yaml (from template), check.sha, empty symbols, +
  ov_SC01_077 entry & sentinel anchor in the 4 Python BINARIES dicts
- GATE T1b: make check BINARY=ov_SC01_077 -> d19c9580 BYTE-IDENTICAL @ 100%
  INCLUDE_ASM; clean rebuild leaves main 143dbb89 + resident 8e17e02f unregressed
- reusable non-word-aligned-overlay handling (~75% of fleet) added to the
  template + Makefile: (1) [word_floor, bin, trailing] carve for the final 1-3
  bytes spimdisasm drops; (2) build/assets/%.o incbin rule (+ .data align=1) for
  splat bin assets (asset_path scoped per-alias); (3) objcopy end-align TRIM
  (shrink-only, <=3 B) removing the .ld's segment-end ALIGN(.,4) pad
- .gitignore /assets/ (regenerable splat output); clean removes assets/
2026-06-16 15:39:52 -06:00
Drew T cc73951128 feat(phase-10): T3 — per-binary reports/diff/expected for the resident binary
- diff_settings.py + progress.py/difficulty.py/dup_report.py: add the `resident` BINARIES entry
  (build/resident/, config/check.resident.sha, src/resident, asm/resident/nonmatchings, per-binary docs)
- dup_report.py: degrade gracefully when the Ghidra sig (.run/sig.resident.jsonl) is absent —
  write a placeholder + exit 0 instead of crashing the whole `make report` (sig is a T4 export)
- progress.py: scope linked_subsegs() to BINARY==main — PsyQ library linking is the EXE's layout
  (Phase 8, gated ifeq BINARY,main), so a second binary has 0 LINKED (was: listed main's libs)
- Makefile expected: per-binary-safe — drop `rm -rf expected/build` (clobbered every sibling
  baseline); refresh only the active binary's image dir + merge-copy (cp never deletes siblings)
- reports: resident = 0 REAL / 143 INCLUDE_ASM stubs / 100% stub (correct); main UNCHANGED
  (52 REAL / 959 LINKED / 50.24%); both expected/ baselines coexist (verified)
2026-06-15 23:06:25 -06:00
Drew T 3b2093dfde refactor(phase-9): T9 — BFM_BINARY env-var selector for diff_settings.py
- asm-differ calls apply(config, args) with a fixed signature, so the active binary
  is selected via the BFM_BINARY env var (default main = the EXE images); BINARIES
  table -> {baseimg, myimg, mapfile}; unknown BFM_BINARY errors loud
- main keeps expected/build/us/SLUS_007.26.{elf,map} (no-op for the EXE workflow)
- gate: apply() unit test (main->EXE paths; bogus->error); asm-differ -o func_80018F20
  --format json -> current_score=0 (MATCH) through the parameterized config
2026-06-15 21:02:43 -06:00
Drew T 5f937bdda5 feat(phase-6): compiler pinned + matching loop proven (14 matches) — LZSS to Phase 7
- splat.us.exe.yaml: text subseg asm->c (INCLUDE_ASM scaffold); include/common.h
  (committed prelude); Makefile c-rule cpp->cc1->maspsx->as + -Map
- PIN (G8): gcc-2.7.2-psx -O2 -G0 -mips1 -mcpu=3000 -mgas -msoft-float -fgnu-linker
  + maspsx --aspsx-version=2.56 --expand-div; byte-exact on func_80018F20 +
  instruction-identical across 3 idiom classes; --expand-div REQUIRED for div/rem
  (SETUP.md §5.4 PINNED, Makefile MASPSX_FLAGS)
- harness: diff_settings.py (asm-differ mipsel object mode), tools/decompile.py
  (m2c wrapper), tools/permuter/ (decomp-permuter harness + objdump shim), expected/
- 14 real functions matched (asm-differ score 0): func_80018F20 + 13 accessors;
  +14 splat-auto empty no-ops; make check BYTE-IDENTICAL throughout
- 2 instruction-identical near-misses guarded NON_MATCHING (func_80015A74 scheduling,
  func_80016714 phantom frame) -> decomp-permuter candidates
- flywheel: docs/matching-cookbook.md, memory + CLAUDE.md step 5 (consult+evolve), R16
- requirements-python.txt: venv freeze (pycparser<3.0 pinned — permuter needs plyparser)
- LZSS spike: needs jump-table-in-rodata workflow (102 tables, mixed blob) -> Phase 7
- venv: asm-differ + permuter deps installed
- bumps project version 1.5.0 -> 1.6.0
2026-06-14 14:47:01 -06:00