- 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)
- 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)
- 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
- tools/psyq/CHECKSUMS.sha256: integrity record for psyq-4.7-converted.zip (R20) + Phase-12
provenance (the resident is 4.7 -> link from conv47/, not the EXE's 4.0 libs; R24)
- cookbook §11: the cross-binary dedup & code-share workflow — source-level macro share (NOT an
object swap; game fns are interior to one object/binary, D1), the byte-gate, sig_image notes
(h_exact workhorse / self-consistent h_norm D2 / linear-partition+code-end overlay boundaries),
the cross-report as the Phase-12/13 work queue, per-binary SDK provenance (R24)
- SETUP §6.8 + tooling inventory: sig_image.py, dedup_integrate.py, dup_report --cross,
make sig-overlays, config/dedup.us.yaml + src/shared/ (R21)
- docs/psyq-worklist.md: resident PsyQ is 4.7 (Phase-12 linking note)
- README: Gen2 status — resident is the 2nd byte-identical binary; cross-binary dedup live
(~9000 cross-binary groups / ~28 MB collapsible; one engine fn byte-identical in all 134 overlays)
- PhaseEnd_Phase10.md: resident engine blob byte-identical from source (8e17e02f) at 100%
INCLUDE_ASM; the binary-agnostic toolchain proven on a real 2nd binary; main still 143dbb89
- docs/SETUP.md §6.7: the resident first-instantiation + the reusable flat-blob <bin> recipe
(per-binary OBJS prune, build_path=build, flat config, leading-data-word-as-rodata); 2 new
Ghidra tools in the inventory (R21)
- rule R24 (per-binary compiler/SDK provenance — resident is PsyQ 4.7 vs EXE 4.0)
- worklog archived CURRENT_PHASE.md -> phase-ends/logs/Phase10.md (R19)
- bumps project version 1.9.0 -> 1.10.0
- matching-cookbook §9.6 "Scaling library linking to the whole EXE": the survey-first
approach, gen_lib_subsegs.py + the section-size boundary gotcha, the combined-region
pattern for interleaved libs (make_snd_used/make_apicard_used, alias dedup by byte-match),
scattered-.bss cross-object exclusion (by address), the incremental-.ld clean-rebuild
gotcha, and the LINKED honest-metric note
- SETUP.md: add the 3 new Phase-8 tools to the tool inventory (R21)
- docs/gen2-roadmap.md: approved Gen2 plan (phases 8-15; finish-EXE-first,
two-repo LATE public flip, substantial exit) + Backup & disaster-recovery policy
- back up irreplaceable / hard-to-re-source artifacts to the private remote (R20):
- track ghidra/ (the RE database; *.lock/tmp*.ps transients excluded)
- tools/psyq/ working libs/tools (minus the two >100MB raw source archives)
- tools/bin/*.tar.gz (old-gcc cc1 compiler sources; extracted binaries stay regenerable)
- tools/ghidra-ext/ (GhidrAssistMCP 2.8.0 + ghidra_psx_ldr 2026.06.04 installer zips)
- .claude/settings.json: SessionStart + SessionEnd hooks (auto-start / clean-save the
headless Ghidra MCP); moved out of the gitignored settings.local.json so they are backed up
- docs/SETUP.md: document the MCP server lifecycle + persistence model + session hooks (§2.8),
a tooling inventory, .run/ runtime scratch (§1a), and the backup posture (§ Backup) — R21
- .gitmodules: ignore=dirty on the 4 submodules (maspsx/asm-differ/m2c/decomp-permuter) —
silences the phantom "modified" state from generated pycache + cross-filesystem filemode;
gitlinks unchanged (still at the pinned commits)
- rules R20 (back up irreplaceable work + gathered tooling; loosens R8) and R21 (keep
SETUP.md current) recorded in memory; to be formalized at the next PhaseEnd
- tools/ghidra_scripts/ImportPsyqGdt.java: opens psyq400.gdt and resolve()s
all 2599 PsyQ 4.0 types into the program DTM (205 -> 2609), registering
psyq400 as a SourceArchive; saved to ghidra/bfm.rep
- verified over MCP: types get DRAWENV -> full 92-byte struct (/LIBGPU.H),
SVECTOR (/LIBGTE.H) -> the .gdt "attach" is doable headlessly, no GUI
- docs/SETUP.md: ledger #2 RESOLVED; §2.5 step 5 answered (import types into
the program; MCP type tools then resolve them)