Drew T f4502f11bb fix(phase-26a): A3c — the recovery passes were reconciling 95% of drafts against the WRONG TU
FIRST CONSUMER MIGRATION onto the cdecl oracle — and the compiler taught me two things I had
wrong, one of which reopens a wall that has been closed since Phase 15.

1. cdecl.compatible() — "will cc1 accept these two declarations of one name?"
   The predicate four tools each half-implement and get wrong: norm_sig / _norm_type collapse the
   int family to ONE token, so a SIGNEDNESS change reads as "already compatible" and gets no
   rewrite -- while cc1 REJECTS that redeclaration. Right about codegen, wrong about the front end,
   which never reaches codegen.

2. THE ADJUDICATOR MUST BE THE COMPILER THAT COMPILES YOUR CODE (cookbook §51g LAW 9).
   I wrote the rules from the C standard, then let a compiler judge. It contradicted me -- and then
   the RIGHT compiler contradicted the first one. Three different answers:

       declarations in one TU        | standard | modern gcc | gcc-2.7.2 cc1
       typedef int X;  twice         | error    | ACCEPTS    | ERROR
       extern u16 X; + volatile u16 X| error    | error      | ACCEPTS
       void X(s16);  then  void X(); | error    | error      | ACCEPTS
       void X();     then  void X(s16)| error   | error      | ERROR

   --compat now adjudicates with tools/bin/gcc-2.7.2-psx/cc1, the front end that actually
   arbitrates the build: 1,485/1,485 live corpus pairs agree, 0 disagree, 0 skipped.

3. THE PRIZE: the Phase-15 narrow-param wall rests on a false premise.
   The no-prototype rule is ORDER-DEPENDENT. `void X(s16); void X();` COMPILES; only the reverse
   fails. Phase 15 closed "the 159 arity/narrow-param conflicts" as "no clean deterministic fix --
   it is simply C's default-promotion rule". cc1 does not enforce that rule in the direction the
   wall assumed. Four three-line probes, 90 seconds, zero tokens. -> A10 RE-TEST TARGET.
   Probe the compiler for FACTS; read its source only for LEVERS; byte-validate both. (We read
   gcc-papermario for five phases believing it was 2.7.2. It was 2.8.1.)

4. THE MIGRATION: cast_call_sites canonicalized 95.1% of drafts against a TU that would never
   compile them. `--src-file` is an OPTIONAL HAND-PASSED flag defaulting to src/<ov>/<ov>.c, and no
   caller knows about the Phase-26 _jr_<ADDR> carves: ov_SC01_077 has 263 open stubs across 12 TUs
   and only 13 are in the main .c -- while harvest_verify (A3) correctly splices into the real one.
   Now DERIVED from corpus.stubs() (the INCLUDE_ASM line is self-describing), with the canonical map
   derived from cdecl.tu_scope() (cpp -- so macro-injected DEFINE_func_* decls are finally visible).
   Callee-conflict repair reach: 8 -> 58 of 196 drafts (7x).

5. AND THE NULL RESULT, REPORTED AS SUCH (P9/R14). Those 58 banked ZERO functions. The historical
   draft tail fails on CODEGEN, not plumbing -- func_801387B8, which the audit blames on a single
   unparsed `[4]`, is really 67/100 instructions off with a $s0/$s1 swap (that claim does not
   reproduce on today's tree). The real gain is narrower and still worth having: 52 drafts moved
   from "won't compile" to "compiles, N instructions off" -- from an INVISIBLE failure that reads as
   a compiler wall into a SCORED near-miss the permuter and the §47/§48 dials can act on. That is
   the audit's thesis, not a bank. THREE times in one session a confirmed mechanism produced a null
   consequence.

Also: my own new audit printed "ALL ORACLES GREEN" while silently skipping 100% of its corpus (a
missing -Isrc). The exact bug class, in the tool written to hunt it. An unadjudicable check is not
a passed check.

  R22 clean-fleet: make clean + extract-all + check-all -> 136 passed, 0 failed of 136
  src/ untouched (0 changes)   make audit-cdecl: green   --compat: 1485/1485
  NEXT: sig_unify + reconcile_decls carry the SAME wrong-TU bug (same --src-file flag).
2026-07-14 12:26:01 -06:00
2026-06-10 22:02:07 -06:00
2026-06-10 22:02:07 -06:00

BFM-decomp

A matching decompilation of Brave Fencer Musashi (PlayStation, SLUS-00726, USA 1998) — the first public decompilation effort for this game.

What "matching" means

The goal is C source code that, compiled with the original-era toolchain (PsyQ 4.x / GCC 2.7.2-family + ASPSX via maspsx), produces a byte-for-byte identical SLUS_007.26 and, eventually, byte-identical overlay binaries. SHA1 checksums are the ground truth; "functionally equivalent" does not count.

No ROM content

This repository contains no game assets, no disassembly output, and no ROM-derived data — only source code, build configuration, symbol names/addresses, hashes, and documentation. To build or contribute you must provide your own dump of the game disc (4-track BIN/CUE, redump layout). See .gitignore for the firewall.

Project status

Latest (Phase 19, 2026-06-20): the project builds 136 binaries byte-identical from a clean tree (the EXE + the resident engine + all 134 location overlays); make check-all → 136/136. Fleet byte-identical-from-source is 58.0% (function-instance-weighted; see the PhaseEnds for the byte-weighted ~30% figure and what it includes). Shared engine functions are matched once in ov_SC01_077 and propagated ×134 via tools/dedup_propagate.py. (The narrative below is Phase-11/12-era; a full refresh is part of the public-flip prep.)

Gen1 (foundation) complete — the matching pipeline is proven end-to-end. make extract && make build && make check rebuilds SLUS_007.26 byte-for-byte identical (SHA1 143dbb89…) from C + assembly, reproducibly across many sessions.

  • Compiler pinned by evidence: gcc-2.7.2-psx -O2 -G0 -mips1 -mcpu=3000 + maspsx --aspsx-version=2.56 --expand-div.
  • 52 functions hand-matched to byte-identical machine code — including the LZSS streaming decompressor — with a decomp-permuter + matching-cookbook "flywheel" to accelerate the next.
  • 959 PsyQ SDK functions linked byte-identical (libcd, libgs, libgte, libspu/libsnd, libgpu, libc2, libmcrd, libapi/libcard, libetc) straight from the real PsyQ 4.0 libraries instead of re-decompiling them — bringing byte-identical-from-source coverage of the EXE to ~50%.
  • File-loader / overlay system reverse-engineered, with the resident engine blob + location overlays' load addresses proven byte-identical against a live PCSX-Redux RAM dump.

About half the EXE is still INCLUDE_ASM stubs (correct bytes, not yet C), and the bulk of the game lives in compressed overlays inside the .CD archives — Gen2 (overlays & engine at scale) is underway:

  • The build toolchain is binary-agnostic (one parameterized pipeline builds any binary), and the always-resident engine blob rebuilds byte-for-byte from source (SHA1 8e17e02f…) — the second binary reconstructed exactly, after the EXE — and is now 86% hand-matched C (123 / 146 functions, up from 0): its scripting turned out to be compiled-MIPS state/mode dispatch, not a bytecode VM, and the save-file + sound (SQV) formats are documented. The harvest used a reusable swarm-of-agents + bit-for-bit byte-gate method (a wrong match can't be accepted) — tools/harvest_verify.py + tools/match_one.py, which carry straight into the overlay phase.
  • A cross-binary deduplication pipeline is live: a Ghidra-free signer fingerprints all 134 location overlays, and the report finds ~9,000 byte-identical function groups shared across binaries (~28 MB of collapsible code) — a single engine function is byte-identical in all 134 overlays. This is "one match unlocks many": each engine match will be auto-credited across the overlay fleet.

Current phase and detailed progress live in phase-ends/ (newest PhaseEnd_*.md = current state); methodology, rules, and the full roadmap are in PROJECT_CONTEXT.md; environment setup in docs/SETUP.md.

This project is developed primarily by Claude Code driving Ghidra through an MCP server; see CLAUDE.md.

License

Private repository for now. AGPL-3.0 is planned at public release, modeled on sotn-decomp. tools/brave-CUE/ is CUE's BRAVE extractor (GPL, source included) and retains its own license.

S
Description
No description provided
Readme AGPL-3.0 492 MiB
Languages
C 96.6%
Python 3%
Makefile 0.2%
Shell 0.1%