diff --git a/.gitignore b/.gitignore index d0b0821c38..24a9020322 100644 --- a/.gitignore +++ b/.gitignore @@ -252,6 +252,7 @@ unsloth_compiled_cache/ !/.run/P32/t3/verdicts.jsonl !/.run/P32/t3/pending_launch.txt !/.run/P32/t3/harvest_notes.md +!/.run/P32/t3/PROMPT_TEMPLATE.md !/.run/P32/t3/haiku/ /.run/P32/t3/haiku/* !/.run/P32/t3/haiku/func_*.c diff --git a/.run/P32/t3/PROMPT_TEMPLATE.md b/.run/P32/t3/PROMPT_TEMPLATE.md new file mode 100644 index 0000000000..d862d896a3 --- /dev/null +++ b/.run/P32/t3/PROMPT_TEMPLATE.md @@ -0,0 +1,40 @@ +# T3 agent prompt templates (extracted verbatim from the launching session c6a5fb71 on 2026-09-05 by the successor session) + +Use these to launch the 17 queued rows in `pending_launch.txt` (substitute fn / binary / nins / sub / paths; keep the arm). +AMENDED CONTRACT (playbook §S80 addendum-2, already in BRIEF.md): the final message is the JSON line ONLY; scratch only under +`.run/P32/t3/work//`; never find/rm/mv in a shared dir. Add one sentence to each prompt saying so. + +## Haiku, never-drafted row (func_801F0048, md_SC03_054) — model=haiku — desc: Draft func_801F0048 (md_SC03_054) +``` +Byte-match ONE function for the Brave Fencer Musashi matching decomp. Repo: /home/musashi/bfm-decomp (run every command from there). Target: func_801F0048 in binary md_SC03_054 (20 instructions, never drafted). Arm: haiku. READ FIRST, in order: .run/P32/t3/BRIEF.md, .run/P32/t3/SYS.md, .run/P32/t3/packs/func_801F0048.md. Target asm (read IN FULL): asm/md_SC03_054/nonmatchings/md_SC03_054/func_801F0048.s. Destination TU: src/md_SC03_054/md_SC03_054.c (read its banked siblings, e.g. func_801F0098, for house style). sub = md_SC03_054. Write your best draft to .run/P32/t3/haiku/func_801F0048.c. Check with `.venv/bin/python tools/match_one.py func_801F0048 --c --asm-subdir asm/md_SC03_054/nonmatchings/md_SC03_054 --work .run/P32/t3/work/func_801F0048`, then `.venv/bin/python tools/rtu_match.py func_801F0048 --split md_SC03_054 --source md_SC03_054 --c --asm-subdir asm/md_SC03_054/nonmatchings/md_SC03_054 --work .run/P32/t3/rtu/func_801F0048`. Do NOT edit anything under src/ or config/. End your final message with the single-line JSON verdict specified in BRIEF.md. +``` + +## Haiku, row with a twin hint (func_800CF068, md_MAIN_007 ← md_MAIN_008:0x800cee44 d=5) — model=haiku — desc: Draft func_800CF068 (md_MAIN_007) +``` +Byte-match ONE function for the Brave Fencer Musashi matching decomp. Repo: /home/musashi/bfm-decomp (run every command from there). Target: func_800CF068 in binary md_MAIN_007 (21 instructions). A near twin exists: md_MAIN_008:0x800cee44 (edit distance 5). Start from `.venv/bin/python tools/family_remap.py --addr 0x800cee44 --from md_MAIN_008 --to md_MAIN_007 --to-addr 0x800cf068 --out .run/P32/t3/haiku/func_800CF068.c` (it remaps the per-binary symbols; if it refuses, write the body from the .s using the twin's C in src/md_MAIN_008/md_MAIN_008.c as the shape), then fix the structural differences the real-TU diff shows. Arm: haiku. READ FIRST, in order: .run/P32/t3/BRIEF.md, .run/P32/t3/SYS.md, .run/P32/t3/packs/func_800CF068.md. Target asm (read IN FULL): asm/md_MAIN_007/nonmatchings/md_MAIN_007/func_800CF068.s. Destination TU: src/md_MAIN_007/md_MAIN_007.c. sub = md_MAIN_007. Draft path: .run/P32/t3/haiku/func_800CF068.c. Check with `.venv/bin/python tools/match_one.py func_800CF068 --c --asm-subdir asm/md_MAIN_007/nonmatchings/md_MAIN_007 --work .run/P32/t3/work/func_800CF068`, then `.venv/bin/python tools/rtu_match.py func_800CF068 --split md_MAIN_007 --source md_MAIN_007 --c --asm-subdir asm/md_MAIN_007/nonmatchings/md_MAIN_007 --work .run/P32/t3/rtu/func_800CF068`. Do NOT edit anything under src/ or config/. End your final message with the single-line JSON verdict specified in BRIEF.md. +``` + +## func_801EF734 (Haiku first launch, then the Sonnet ESCALATION with the shape hint) — model=haiku — desc: Draft func_801EF734 (md_SC03_053) +``` +Byte-match ONE function for the Brave Fencer Musashi matching decomp. Repo: /home/musashi/bfm-decomp (run every command from there). Target: func_801EF734 in binary md_SC03_053 (44 instructions, never drafted). Arm: haiku. READ FIRST, in order: .run/P32/t3/BRIEF.md, .run/P32/t3/SYS.md, .run/P32/t3/packs/func_801EF734.md. Target asm (read IN FULL): asm/md_SC03_053/nonmatchings/md_SC03_053/func_801EF734.s. Destination TU: src/md_SC03_053/md_SC03_053.c. sub = md_SC03_053. Write your best draft to .run/P32/t3/haiku/func_801EF734.c. Check with `.venv/bin/python tools/match_one.py func_801EF734 --c --asm-subdir asm/md_SC03_053/nonmatchings/md_SC03_053 --work .run/P32/t3/work/func_801EF734`, then `.venv/bin/python tools/rtu_match.py func_801EF734 --split md_SC03_053 --source md_SC03_053 --c --asm-subdir asm/md_SC03_053/nonmatchings/md_SC03_053 --work .run/P32/t3/rtu/func_801EF734`. Do NOT edit anything under src/ or config/. End your final message with the single-line JSON verdict specified in BRIEF.md. +``` + +## func_801EF734 (Haiku first launch, then the Sonnet ESCALATION with the shape hint) — model=haiku — desc: Draft func_801EF734 (md_SC03_053) +``` +Byte-match ONE function for the Brave Fencer Musashi matching decomp. Repo: /home/musashi/bfm-decomp (run every command from there). Target: func_801EF734 in binary md_SC03_053 (44 instructions, never drafted). Arm: haiku. READ FIRST, in order: .run/P32/t3/BRIEF.md, .run/P32/t3/SYS.md, .run/P32/t3/packs/func_801EF734.md. Target asm (read IN FULL): asm/md_SC03_053/nonmatchings/md_SC03_053/func_801EF734.s. Destination TU: src/md_SC03_053/md_SC03_053.c (read its banked siblings for house style). sub = md_SC03_053. Write your best draft to .run/P32/t3/haiku/func_801EF734.c. Check with `.venv/bin/python tools/match_one.py func_801EF734 --c --asm-subdir asm/md_SC03_053/nonmatchings/md_SC03_053 --work .run/P32/t3/work/func_801EF734`, then `.venv/bin/python tools/rtu_match.py func_801EF734 --split md_SC03_053 --source md_SC03_053 --c --asm-subdir asm/md_SC03_053/nonmatchings/md_SC03_053 --work .run/P32/t3/rtu/func_801EF734`. Do NOT edit anything under src/ or config/. End your final message with the single-line JSON verdict specified in BRIEF.md. +``` + +## func_801EF734 (Haiku first launch, then the Sonnet ESCALATION with the shape hint) — model=sonnet — desc: Escalate func_801EF734 (md_SC03_053) to Sonnet +``` +Byte-match ONE function for the Brave Fencer Musashi matching decomp. Repo: /home/musashi/bfm-decomp (run every command from there). Target: func_801EF734 in binary md_SC03_053 (44 instructions). ESCALATION: a Haiku drafter plateaued at 47 instructions with its draft at .run/P32/t3/haiku/func_801EF734.c — its three if-arms each emit their OWN `jal` where the target CONVERGES on one shared tail call (44 ins). That is a C structure question, not a compiler wall: make the arms only compute/assign the arguments and FALL THROUGH (or `goto` one shared label) to a SINGLE call site so gcc emits one jal; read the target's branch structure to see which arm is the fall-through and which ones jump to the shared tail. Arm: sonnet. READ FIRST, in order: .run/P32/t3/BRIEF.md, .run/P32/t3/SYS.md, .run/P32/t3/packs/func_801EF734.md, then the Haiku draft above (correct semantics, wrong shape). Target asm (read IN FULL): asm/md_SC03_053/nonmatchings/md_SC03_053/func_801EF734.s. Destination TU: src/md_SC03_053/md_SC03_053.c (read its banked siblings — several are the same script-module shape). sub = md_SC03_053. Write your best draft to .run/P32/t3/sonnet/func_801EF734.c. Check with `.venv/bin/python tools/match_one.py func_801EF734 --c --asm-subdir asm/md_SC03_053/nonmatchings/md_SC03_053 --work .run/P32/t3/work/func_801EF734s`, then `.venv/bin/python tools/rtu_match.py func_801EF734 --split md_SC03_053 --source md_SC03_053 --c --asm-subdir asm/md_SC03_053/nonmatchings/md_SC03_053 --work .run/P32/t3/rtu/func_801EF734s`. Do NOT edit anything under src/ or config/. End your final message with the single-line JSON verdict specified in BRIEF.md (arm "sonnet"). +``` + +## Opus, old near/far row (func_800CD92C, md_MAIN_009) — model=opus — desc: Draft func_800CD92C (md_MAIN_009) +``` +Byte-match ONE function for the Brave Fencer Musashi matching decomp. Repo: /home/musashi/bfm-decomp (run every command from there). Target: func_800CD92C in binary md_MAIN_009 (247 instructions, never drafted before; md_MAIN_009 is a freshly onboarded module at 0x800CD348). Arm: opus. READ FIRST, in order: .run/P32/t3/BRIEF.md, .run/P32/t3/SYS.md, .run/P32/t3/packs/func_800CD92C.md. Target asm (read IN FULL): asm/md_MAIN_009/nonmatchings/md_MAIN_009/func_800CD92C.s. Destination TU: src/md_MAIN_009/md_MAIN_009.c. sub = md_MAIN_009. Write your best draft to .run/P32/t3/opus/func_800CD92C.c. Check with `.venv/bin/python tools/match_one.py func_800CD92C --c --asm-subdir asm/md_MAIN_009/nonmatchings/md_MAIN_009 --work .run/P32/t3/work/func_800CD92C`, then `.venv/bin/python tools/rtu_match.py func_800CD92C --split md_MAIN_009 --source md_MAIN_009 --c --asm-subdir asm/md_MAIN_009/nonmatchings/md_MAIN_009 --work .run/P32/t3/rtu/func_800CD92C`. Do NOT edit anything under src/ or config/. End your final message with the single-line JSON verdict specified in BRIEF.md. +``` + +## Sonnet, mid-size row (func_800CEE2C, md_MAIN_007) — model=sonnet — desc: Draft func_800CEE2C (md_MAIN_007) +``` +Byte-match ONE function for the Brave Fencer Musashi matching decomp. Repo: /home/musashi/bfm-decomp (run every command from there). Target: func_800CEE2C in binary md_MAIN_007 (52 instructions, the module's first function, never drafted). Arm: sonnet. READ FIRST, in order: .run/P32/t3/BRIEF.md, .run/P32/t3/SYS.md, .run/P32/t3/packs/func_800CEE2C.md. Target asm (read IN FULL): asm/md_MAIN_007/nonmatchings/md_MAIN_007/func_800CEE2C.s. Destination TU: src/md_MAIN_007/md_MAIN_007.c (a boot-slot module TU that stacks only config/symbols.us.txt). sub = md_MAIN_007. Write your best draft to .run/P32/t3/sonnet/func_800CEE2C.c. Check with `.venv/bin/python tools/match_one.py func_800CEE2C --c --asm-subdir asm/md_MAIN_007/nonmatchings/md_MAIN_007 --work .run/P32/t3/work/func_800CEE2C`, then `.venv/bin/python tools/rtu_match.py func_800CEE2C --split md_MAIN_007 --source md_MAIN_007 --c --asm-subdir asm/md_MAIN_007/nonmatchings/md_MAIN_007 --work .run/P32/t3/rtu/func_800CEE2C`. Do NOT edit anything under src/ or config/. End your final message with the single-line JSON verdict specified in BRIEF.md. +``` diff --git a/CLAUDE.md b/CLAUDE.md index e7890d6645..90a9def88c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,24 +4,33 @@ Matching decompilation of **Brave Fencer Musashi** (PS1, SLUS-00726 USA). Goal: ## Session Start Protocol — Do This First, Every Session -Before doing any work, read these files in this order: +**Budget: the whole protocol should cost about 100k tokens plus the verbatim checkpoint block** (Drew, 2026-09-05; R64 +candidate). Read these files in this order — nothing else at session start: 1. Read `PROJECT_CONTEXT.md` in full (the permanent constitution: rules, protocols, roadmap). -2. Read every `phase-ends/PhaseEnd_*.md` in numeric order (the build history). **Do NOT read `phase-ends/logs/`** — those are on-demand worklog archives (R19), deliberately out of the load order; consult one only when researching a past mechanism (see the `phase-worklogs-reference-only` memory). -3. Read `phase-ends/CURRENT_PHASE.md` if it exists (the in-phase state). -4. Then follow the **Session Start Protocol** in `PROJECT_CONTEXT.md` — state phase, completed tasks, the single next task, and acknowledge the rules before working. -5. **For matching phases (Phase 6+):** before any function matching, also read `docs/matching-cookbook.md` (reusable compiler idioms asm↔C + techniques) and `docs/SETUP.md` §5.4 (the pinned triple). The matching knowledge base is a **compounding flywheel** — consult it before each match, and after each match (especially a hard-won near-miss) feed the generalizable lesson back into BOTH the cookbook AND the tooling (`tools/permuter/` PERM_ recipes/weights, the m2c `--context`) so future similar functions one-shot. +2. Read `phase-ends/DIGEST.md` in full — every phase's synopsis, every rule's full text (R1–R64), the corrections that + supersede parts of PROJECT_CONTEXT.md, and the doc map. It REPLACES reading every PhaseEnd (the PhaseEnds are still + kept forever — read an older one on demand when a synopsis is not enough; **never** read `phase-ends/logs/` at + session start, R19). +3. Read the **three most recent** `phase-ends/PhaseEnd_*.md` in full, in numeric order. +4. Read `phase-ends/CURRENT_PHASE.md` in full if it exists (the in-phase state). +5. For matching phases (Phase 6+): read `docs/matching-cookbook.md`'s first ~120 lines (the pinned triple + §1–§3) and its + most recent § only, and `docs/SETUP.md` §5.4 (the pinned triple). The cookbook is 3.5 MB and `docs/cookbook-index.md` + is 566 KB: grep them by §/symptom during matching, never read them whole. The knowledge base is a **compounding + flywheel** — consult it before each match, and after each match feed the generalizable lesson back into BOTH the + cookbook AND the tooling (`tools/permuter/` recipes, the m2c `--context`) so future similar functions one-shot. -After reading, state the following and nothing else: -- Current phase number and name -- Which tasks in the current phase are already complete -- Which single task is NEXT -- The recommended **effort level** for that NEXT task per `docs/effort-map.md`, and confirm the developer has it set (Effort-map check) -- Every AI Collaboration Rule from the context file plus every rule added in any PhaseEnd file's "Rules Added This Phase" section +After reading, state the following and nothing else, in this order: +- Current phase number and name; which tasks in the current phase are already complete; which single task is NEXT +- The recommended **effort level** for that NEXT task per `docs/effort-map.md`, and confirm the developer has it set +- Every AI Collaboration Rule from `PROJECT_CONTEXT.md` (P/G/H/X) plus every R-rule, **in full text**, transcribed from + `phase-ends/DIGEST.md` §3 +- **The last `## 🛑 SESSION CHECKPOINT` block of `phase-ends/CURRENT_PHASE.md`, reproduced VERBATIM and in full** — not + summarized. That block is written to be replayed: it is the complete seed for this session and it is the ONLY in-phase + context this session inherits from the previous one. -Then wait for the developer to confirm before doing anything. - -Do not summarize the project. Do not list all remaining tasks. Do not start working. State what is next, list the rules, and wait. +Then wait for the developer to confirm before doing anything. Do not summarize the project. Do not list all remaining +tasks. Do not start working. State what is next, list the rules, replay the checkpoint, and wait. --- @@ -119,6 +128,7 @@ When a phase milestone is confirmed complete: 1. State: "🟡 PhaseEnd creation is a Tier 1 task. Confirm when ready." 2. Wait for confirmation. 3. Create the `PhaseEnd_Phase[N].md` file using the Write tool, taking time to reason carefully about the phase as a whole. +3b. Append the phase's synopsis and its ratified rules to `phase-ends/DIGEST.md` (the session-start digest; a P7 checkbox — a PhaseEnd without its digest entry is not closed). 4. Final message: "PhaseEnd file created. Commit the file and start a new Claude Code session for the next phase." 5. HARD STOP. Do not preview the next phase. Do not continue working. Do not suggest what comes next. diff --git a/docs/SETUP.md b/docs/SETUP.md index 976b4c2d0b..0cde5a7fcc 100644 --- a/docs/SETUP.md +++ b/docs/SETUP.md @@ -647,6 +647,12 @@ The tooling-inventory rows below are the per-tool REFERENCE; the playbook is the ## §7 Session-start ritual +> **Claude Code load order (2026-09-05, R64 candidate):** `PROJECT_CONTEXT.md` → `phase-ends/DIGEST.md` (all phase synopses + all +> rules in full) → the THREE most recent `phase-ends/PhaseEnd_*.md` → `phase-ends/CURRENT_PHASE.md`, then the 🛑 SESSION +> CHECKPOINT block is replayed VERBATIM into the chat. Budget ≈100k tokens + the checkpoint. Never read all PhaseEnds, +> `phase-ends/logs/`, the whole cookbook or `docs/cookbook-index.md` at session start (CLAUDE.md is the authority). +> The Ghidra steps below apply only to RE sessions (G2) — the MCP server now runs headless via the SessionStart hook. + Order is load-bearing — MCP tools fail (sometimes silently) without an open program. 1. **Start Ghidra** (in WSL, under WSLg): `~/ghidra_12.1_PUBLIC/ghidraRun`. diff --git a/phase-ends/CURRENT_PHASE.md b/phase-ends/CURRENT_PHASE.md index a6c0be1fd9..ea1fa447bd 100644 --- a/phase-ends/CURRENT_PHASE.md +++ b/phase-ends/CURRENT_PHASE.md @@ -120,6 +120,7 @@ cookbook before the next drafting step (R16/R30) · no `Co-Authored-By` trailer needed for T0–T2b; if T2d needs it: `tools/ghidra_mcp_start.sh` → pause → Drew runs `/mcp` (R29) → G2 ping. ## Log +- 2026-09-05 (successor session, later) — **Session-start protocol rewritten at Drew's direction (R64 candidate):** `phase-ends/DIGEST.md` created (every phase synopsis + every rule in full + the PROJECT_CONTEXT corrections + the doc map); CLAUDE.md load order = PROJECT_CONTEXT → DIGEST → the three most recent PhaseEnds → CURRENT_PHASE, ≈100k tokens, the 🛑 block replayed VERBATIM; Phase Boundary step 3b maintains the digest (P7); `phase-ends/README.md` + SETUP §7 updated; the two memories (`checkpoint-current-phase-before-pause`, `session-start-list-rules-in-full`) + MEMORY.md updated; `.run/P32/t3/PROMPT_TEMPLATE.md` saved (verbatim agent prompts). The 🛑 block below was REFRESHED to the verbatim-replay standard and SUPERSEDES the 09:30 block. Ratify R64 at PhaseEnd_Phase32. - 2026-09-05 09:30 MDT — **T3 CHECKPOINT by the successor session (Max, Fable 5.1) after the launching session died.** The T3 coordinator (session c6a5fb71) banked 10 functions in 9 commits (T3 (1)–(9), 01:01–01:07 MDT) and then hit "Prompt is too long" at 01:07 MDT; 22 agent completions (07:07Z–08:04Z) arrived into a dead session. Recovered via the recorded route: `agent_verdicts.py` over the 31 task transcripts → `.run/P32/t3/verdicts.jsonl` (20 MATCH / 9 NEAR / 2 FAIL); every unbanked draft re-verified with `rtu_match` in its real TU (10 MATCH confirmed). **Instrument incident (R48 class):** one agent's tidy-up (`find .run/P32/t3/opus -maxdepth 1 -type f ! -name func_800CD674.c -exec mv {} _scratch/`, 07:52Z) had swept 11 sibling Opus deliverables — found in `_scratch/`, moved back, byte-verified at the reported closeness; `tools/agent_drafts_restore.py` (NEW — transcript replay) written as the fallback; `.gitignore` allowlist for `.run/P32/**` so the drafts/ledger/census are committed (R20). Harvest written IN-SESSION (R16/R30): cookbook **§500** (10 banked closers, 10 MATCH closers, 9 NEAR classes, two NEW mechanisms — the pinned-base alias basin and `#line`-equalised ASM_OPERANDS — and the process defects); `docs/wave-playbook.md` §S80 addendum-2 (per-function work dirs, JSON-only final message, the 20-agent cap, the recovery tools); `docs/accelerators.md` P32 T3; `docs/decision-log.md` P32 S82 (R31); SETUP row (R21). Read-only T4 pre-check results from the dead session preserved in the 🛑 block. Effort: this checkpoint at Max; **T3 resumes at xHigh** (R27). - 2026-09-05 — gate 1 approved; T0 opened at HEAD `commit:3900`. - 2026-09-05 — **T3 LAUNCHED** (xHigh): 47 targets = census 54 − 7 pinned walls (`.run/P32/t3/targets.json`, 5,288 ins); packs built (`claude_wave_packs`, 47/47 neighbours, 10 journals); brief `.run/P32/t3/BRIEF.md`. **20 Agent-tool drafters running** (16 Opus: the 11 old near/far rows + resident func_800D06E8 + the 4 largest new bodies · 3 Sonnet · 1 Haiku); **27 Haiku queued** behind the harness's 20-concurrent cap (`.run/P32/t3/pending_launch.txt`, launched one per freed slot). Recovery + per-result route: `.run/P32/t3/LAUNCHED.md`. @@ -129,105 +130,220 @@ cookbook before the next drafting step (R16/R30) · no `Co-Authored-By` trailer - 2026-09-05 — **T1a DONE — `resident:func_800D128C` BANKED (243 ins, byte-identical 8e17e02f, R22 213/213).** The stored S71 closeness-0 draft was byte-correct all along; the whole task was three instrument defects the resident (the fleet's one `common.h`-only, `--pre`-sandwich binary) exposed in overlay-only assumptions: (1) `jr_isolate_all` dropped a file-local typedef whose name engine_types.h also defines (§496 — fixed: provided types derived from the TU's own includes); (2) `jtbl_carve` regenerated `JTBL_INTERLEAVE` without the `--pre hdr.rodata.o` clause → extract refused → the gate linked a stale script and booked the byte-correct draft as DIFF; `harvest_verify` ignored that extract's rc (§498 — both fixed, R49/R61); (3) `interleave_check` read a `--pre` line as n=0 (false DRIFT; fixed). R38 then found two more stored MATCH bodies for T1b/T1c (see their rows). Effort stayed Max. - 2026-09-05 — **T0 DONE.** Baseline reads all green (`.run/P32/t0_baseline.log`): `verbatim_check --strict` 5 bodies == 5 rows; `exclude_audit --assert-fresh` 8 entries, 8 WALL, 0 stale; `frontier_classify` → 21 rows = the S80 census exactly; `make tools-health` OK (sigs fresh, corpus(+resident), cdecl, audit-binaries 213/213, report lint+dedup, cookbook-index, split_indicator 213 OK); `make check-all` 213 passed / 0 failed, rc 0. Harness task list #1–#11 built (R28). NEXT = T1a. -## 🛑 SESSION CHECKPOINT — T3 MID-WAVE (2026-09-05 09:30 MDT; written by the successor session after the launching coordinator overflowed) -Written for a FRESH SESSION with none of this context. Phase 32 plan approved (gate 1, Drew, 2026-09-05, Max, Fable 5.1); -rules R44–R63 ratified. **T0–T2d DONE. T3 (task #9) IN PROGRESS — resume it at xHigh (R27; Drew sets the effort).** -Fleet **218/218** byte-identical at the last R22 (T2c close, `.run/P32/t2c/r22.log`); the 10 T3 banks since were each -built byte-identical in their own binary (main `143dbb89…` ×3 via `gate_main`, resident `8e17e02f…`, md_SC03_053 -`c0848f30…` ×4, md_SC03_054 `06bd73df…`, md_MAIN_007 `2ff702b6…`) — **no fleet R22 has run since those banks: run one -before the first new bank** (R22/R58; a stale `.o` can false-pass). Non-ghidra `git status` was clean at this checkpoint; -`ghidra/` churn is R23 restart-noise — never stage it. +## 🛑 SESSION CHECKPOINT — T3 MID-WAVE, REFRESHED (2026-09-05 10:01 MDT; written by the successor session e40106e1; SUPERSEDES the 09:30 block) -### What happened in T3 so far (the facts a fresh session needs) -- **The wave:** 47 targets = the T2c census (54) minus the 7 pinned walls; packs `.run/P32/t3/packs/.md`, brief - `.run/P32/t3/BRIEF.md`, laws `.run/P32/t3/SYS.md`, targets `.run/P32/t3/targets.json`. Model ladder Haiku ≤50 / - Sonnet ≤120 / Opus >120 + the 11 old near/far rows on Opus. One Agent-tool subagent per function; the harness caps - concurrency at 20, so **31 launched, 17 Haiku rows still queued in `.run/P32/t3/pending_launch.txt`** (with their - twin hints; `md_SC03_054:func_801F00C8` needs a hand-adapt — `family_remap` refused, reloc-count 1≠2). -- **The coordinator (session c6a5fb71) banked 10 functions in 9 commits `commit:3923`..`commit:3931` (01:01–01:07 MDT), - then hit "Prompt is too long" at 01:07 MDT.** 22 agent completions (07:07Z–08:04Z) arrived into the dead session. - This checkpoint harvested them: `.run/P32/t3/verdicts.jsonl` (31 rows: **20 MATCH / 9 NEAR / 2 FAIL**), rebuilt with - `tools/agent_verdicts.py /tmp/claude-1000/-home-musashi-bfm-decomp/7beebba8-05e9-4d18-98ea-ce208f45370f/tasks/a*.output` - (the transcripts themselves: `~/.claude/projects/-home-musashi-bfm-decomp/c6a5fb71-f2ae-4846-a4a9-a43a4c1c3496/subagents/`). -- **Every unbanked draft was re-verified by the successor with `rtu_match` in its real TU** (results match the agents' - verdicts exactly). The Opus deliverables had been swept into `.run/P32/t3/opus/_scratch/` by one agent's tidy-up - (07:52Z, `find … -exec mv`) — moved back to `.run/P32/t3/opus/.c` and byte-verified; `tools/agent_drafts_restore.py` - (NEW) replays a transcript if a deliverable ever goes missing again. The drafts + ledger are git-tracked now. -- **Harvest already written (R16/R30):** cookbook **§500** (every closer, the 9 NEAR classes with their inert-lever - lists, two NEW mechanisms, the process defects) · `docs/wave-playbook.md` §S80 addendum-2 · `docs/accelerators.md` - P32 T3 · `docs/decision-log.md` P32 S82. The 8 orchestrator notes in `.run/P32/t3/harvest_notes.md` are subsumed. +### 0. How to use this block +You are a FRESH SESSION that has read `PROJECT_CONTEXT.md`, `phase-ends/DIGEST.md`, `PhaseEnd_Phase29/30/31.md` and this +file, and nothing else (CLAUDE.md protocol, R64 candidate). Replay this block verbatim into your chat, state phase / done / +NEXT / effort, list the rules from the digest, then WAIT for Drew. When he confirms, follow §5 in order. **Effort: xHigh +for T3 and T4** (R27 — Drew sets it; if the status line does not say xHigh, prompt before the first command); **Max only +for T5.** Drafter ladder Haiku ≤50 ins / Sonnet ≤120 / Opus >120; Fable only if an agent names a wall class the codegen +map lacks — STOP and prompt Drew first. No Workflow / Ultracode in T3: one Agent-tool subagent per function. -### Census — 44 stubs / 5,313 ins (`.run/P32/frontier_t3_checkpoint.json`), every row with its state -| binary | stubs | rows (nins · state) | +### 1. Where we are +**Phase 32 — the last 21 + the parked 5 (short, kill-gated).** Gate 1 approved 2026-09-05 (Drew, plan mode, Max, +Fable 5.1); rules R44–R63 ratified then; R64 is a candidate (DIGEST §3). Tasks: **T0 ✓** `commit:3901` · **T1a ✓** +`commit:3902` `commit:3904` · **T1b ✓** `commit:3903` `commit:3906` `commit:3907` · **T1c ✓** `commit:3908` · **T2a ✓** `commit:3909` +· **T2b ✓** `commit:3911` `commit:3912` `commit:3913` `commit:3914` (fleet 213 → 218) · **T2c ✓** `commit:3917` `commit:3918` +`commit:3919` `commit:3920`, close `commit:3921` · **T2d not needed** · **T3 IN PROGRESS** (launch `commit:3922`; banks +`commit:3923` `commit:3924` `commit:3925` `commit:3926` `commit:3927` `commit:3928` `commit:3929` `commit:3930` `commit:3931`; the +successor's checkpoint `commit:3932` + the protocol commit = HEAD) · **T4, T5 pending.** Harness task list #1–#11 exists +(#9 = T3 in_progress). Fleet **218 binaries** (main + resident + 138 `ov_*` + 78 `md_*`). **Last full R22: 218/218 rc 0 +at the T2c close** (`.run/P32/t2c/r22.log`); the 10 T3 banks each built byte-identical in their own binary but **no fleet +R22 has run since — §5 step 0 runs one before any new bank.** Non-ghidra tree clean at HEAD; the `ghidra/` churn +(`db.*.gbf`, `~index.*`, `*.prp`) is R23 restart-noise — never stage it. Unpushed commits at this writing: 32 +(Drew pushes, R6). + +### 2. What happened in the previous session (c6a5fb71, 2026-09-04 22:39 → 2026-09-05 01:07 MDT) +T0–T2c as logged above. T3: census 54 − 7 pinned walls = **47 targets** (`.run/P32/t3/targets.json`); packs built +(`claude_wave_packs`, 47/47 neighbours, 10 journal notes); brief `.run/P32/t3/BRIEF.md`, laws `.run/P32/t3/SYS.md`. +**20 drafters launched 00:53–00:55 MDT** (16 Opus: the 11 old near/far rows + resident `func_800D06E8` + the 4 largest new +bodies; 3 Sonnet; 1 Haiku), **27 Haiku rows queued** behind the harness's 20-concurrent cap; the launch was checkpointed +(`commit:3922`, 00:59). Ten queued rows were launched as slots freed (01:00–01:07). **Ten functions banked in nine commits +01:01–01:07** (list in §4). **At 01:07:15 MDT the coordinator hit "Prompt is too long"** (its context was ~95% full from +the whole day BEFORE the wave); the other **22 completions (01:07–02:04 MDT) arrived as notifications into a dead +session.** At 01:52 MDT one agent (func_800CD674's) tidied the SHARED `.run/P32/t3/opus/` with +`find .run/P32/t3/opus -maxdepth 1 -type f ! -name 'func_800CD674.c' -exec mv {} .run/P32/t3/opus/_scratch/ \;`, moving +**11 sibling deliverables** (the three agents that finished later wrote their finals afterwards and survived). Drew's last +message (09:04): "97% context. checkpoint for fresh session, have next session analyze the completed subagents results". + +### 3. What THIS session did (e40106e1, 2026-09-05 09:12 → 10:01 MDT, Max, Fable 5.1) +(a) Dumped the dead session's transcript (`~/.claude/projects/-home-musashi-bfm-decomp/c6a5fb71-….jsonl` → condensed text: +assistant text + tool calls + truncated results) and summarised all 31 subagent transcripts. (b) **Rebuilt the verdict +ledger by the recorded route:** `.venv/bin/python tools/agent_verdicts.py /tmp/claude-1000/-home-musashi-bfm-decomp/ +7beebba8-05e9-4d18-98ea-ce208f45370f/tasks/a*.output --append .run/P32/t3/verdicts.jsonl` → **31 rows: 20 MATCH / 9 NEAR / +2 FAIL** (pass ONLY `a*.output` — the `b*.output` files there are older sessions' tasks). (c) Found the swept deliverables +in `_scratch/`, moved the 9 missing ones back to `.run/P32/t3/opus/.c`, and **re-verified EVERY unbanked draft with +`rtu_match` in its real TU — every result equals the agent's verdict** (§4). (d) Wrote `tools/agent_drafts_restore.py` +(transcript replay of Write/Edit/cp/mv/heredoc ops; rebuilt 26/30 exactly — the 4 an agent had edited via shell after its +last Write were stale, so an on-disk copy always wins). (e) **Harvest (R16/R30): cookbook §500** (10 banked closers, 10 +MATCH closers, the 9 NEAR classes with their inert-lever lists, two NEW mechanisms — the pinned-base-vs-pseudo-address +alias basin, `#line`-equalised ASM_OPERANDS for cross_jump — and the process defects), `docs/wave-playbook.md` §S80 +addendum-2, `docs/accelerators.md` P32 T3, `docs/decision-log.md` P32 S82 (R31), `docs/SETUP.md` tool row (R21), +`docs/cookbook-index.md` regenerated (tools-health's `--check` is green), `.run/P32/t3/BRIEF.md` output contract amended +(final message = the JSON line ONLY; scratch only under `.run/P32/t3/work//`; never `find`/`rm`/`mv` in a shared +dir). (f) `.gitignore` allowlist for `.run/P32/**` (drafts, ledger, census jsons, BRIEF/SYS/LAUNCHED/targets/pending/ +harvest_notes/PROMPT_TEMPLATE, `restored/sweep_*.py`) → committed **`commit:3932`**. (g) **Drew-directed protocol change:** +`phase-ends/DIGEST.md` created (every phase synopsis, every rule in full, the PROJECT_CONTEXT corrections, the doc map); +CLAUDE.md session-start rewritten (≈100k-token budget: PROJECT_CONTEXT → DIGEST → last 3 PhaseEnds → CURRENT_PHASE; rules in +full from the digest; the 🛑 block replayed VERBATIM); Phase Boundary step 3b (append the phase to the digest, P7); +`phase-ends/README.md`; SETUP §7 pointer; the memories `checkpoint-current-phase-before-pause` and +`session-start-list-rules-in-full` + MEMORY.md; **R64 candidate** — ratify at PhaseEnd_Phase32. (h) +`.run/P32/t3/PROMPT_TEMPLATE.md` — the verbatim agent prompts (Haiku plain / Haiku with a twin hint / the Sonnet +escalation / Opus / Sonnet). (i) Rebuilt the harness task list; wrote this block. **Nothing under `src/` or `config/` +changed this session.** + +### 4. Census — 44 stubs / 5,313 ins (`.run/P32/frontier_t3_checkpoint.json`), every row with its state and draft path +| binary | stubs · ins | rows | |---|---|---| -| main | 9 · 1,643 | **MATCH-unbanked:** func_80015B6C 120 (Opus, `.run/P32/t3/opus/func_80015B6C.c`, TU `src/800.c`) · func_8002FDE8 73 (Opus, `…/opus/func_8002FDE8.c`, TU `src/800_b_2.c`) · **NEAR:** func_80039308 518 → 17 (`…/opus/func_80039308.c`) · func_8001BC6C 69 → 6 (`…/opus/func_8001BC6C.c`) · **WALLS (pinned, T4):** func_80011380 192 (boot −O0; best `.run/m3/opus/func_80011380.c` 6-off) · func_80032A74 (800_b_2) · func_80020DA4 100 (800; 2-off) · func_80039DEC (800_c) · func_800391D4 (800_c) | +| main | 9 · 1,643 | **MATCH-unbanked:** func_80015B6C 120 (`.run/P32/t3/opus/func_80015B6C.c`, TU `src/800.c`) · func_8002FDE8 73 (`.run/P32/t3/opus/func_8002FDE8.c`, TU `src/800_b_2.c`) · **NEAR:** func_80039308 518 → 17 (`…/opus/func_80039308.c`, TU `src/800_c.c`) · func_8001BC6C 69 → 6 (`…/opus/func_8001BC6C.c`, TU `src/800.c`) · **WALLS (pinned in `config/wave_exclude.txt`, T4):** func_80011380 192 (boot −O0; `.run/m3/opus/func_80011380.c` 6-off) · func_80032A74 (800_b_2) · func_80020DA4 100 (800; `.run/S79w/sonnet/func_80020DA4.c` 2-off) · func_80039DEC (800_c) · func_800391D4 (800_c) | | md_MAIN_003 | 1 · 469 | NEAR func_800CF3E8 469 → 27 (`…/opus/func_800CF3E8.c`) | -| md_MAIN_007 | 14 · 701 | **MATCH-unbanked (Haiku):** func_800CF148 33 · func_800CF2BC 32 · func_800CEEFC 25 · func_800CEF94 25 · func_800CF068 21 (`.run/P32/t3/haiku/.c`) · **leaf-exact behind the TU decl:** func_800CF3B0 22 (`…/haiku/func_800CF3B0.c`; `src/md_MAIN_007/md_MAIN_007.c:91` declares `extern void func_800CF3B0(void*,void*,void*)`, the banked `func_800CF390` at `:94` calls it with 3 args; the real signature is `s32 (void)`) · **NEAR:** func_800CF6D0 249 → 137 · func_800CF408 178 → 49 (`…/opus/`) · **QUEUED Haiku:** func_800CF0F4 21 · func_800CF1CC 21 · func_800CF268 21 · func_800CF33C 21 · func_800CF220 19 (twin ov_SC03_001:0x80182860 d=4) · func_800CEFF8 13 (twin ov_SC02_005:0x801865d0 d=3) | +| md_MAIN_007 | 14 · 701 | **MATCH-unbanked (Haiku, `.run/P32/t3/haiku/.c`):** func_800CF148 33 · func_800CF2BC 32 · func_800CEEFC 25 · func_800CEF94 25 · func_800CF068 21 · **leaf-exact behind the TU decl:** func_800CF3B0 22 (`src/md_MAIN_007/md_MAIN_007.c:91` = `extern void func_800CF3B0(void *a0, void *a1, void *a2);`, the BANKED `func_800CF390` at `:94` calls it with 3 args; the real signature is `s32 (void)`) · **NEAR:** func_800CF6D0 249 → 137 · func_800CF408 178 → 49 (`…/opus/`) · **QUEUED Haiku:** func_800CF0F4 21 · func_800CF1CC 21 · func_800CF268 21 · func_800CF33C 21 · func_800CF220 19 (twin ov_SC03_001:0x80182860 d=4) · func_800CEFF8 13 (twin ov_SC02_005:0x801865d0 d=3) | | md_MAIN_009 | 10 · 603 | **NEAR:** func_800CD92C 247 → 15 · func_800CD674 174 → 2 (`…/opus/`) · **QUEUED Haiku:** func_800CD464 25 · func_800CD558 24 · func_800CD408 23 · func_800CD5B8 23 · func_800CD4C8 22 · func_800CD520 22 (twin ov_SC03_011:0x8017dbd8 d=3) · func_800CD614 22 · func_800CD3B8 21 | | md_SC03_053 | 2 · 116 | **MATCH-unbanked (Sonnet):** func_801EF734 44 (`.run/P32/t3/sonnet/func_801EF734.c`) · func_801EF7E4 72 (`…/sonnet/func_801EF7E4.c`) → the module reaches 100% C | -| md_SC03_054 | 3 · 698 | **MATCH-unbanked:** func_801EF6D8 663-row (604 code ins + six jump tables → B-CARVE; `…/opus/func_801EF6D8.c`) · **QUEUED Haiku:** func_801F0048 20 · func_801F00C8 15 (twin md_SC03_053:0x801ef9dc d=5, hand-adapt) | +| md_SC03_054 | 3 · 698 | **MATCH-unbanked:** func_801EF6D8 — targets.json nins 663 = 604 code ins + six jump tables (B-CARVE; `…/opus/func_801EF6D8.c`) · **QUEUED Haiku:** func_801F0048 20 · func_801F00C8 15 (twin md_SC03_053:0x801ef9dc d=5 — `family_remap` refused, reloc-count 1≠2, hand-adapt) | | md_SC03_056 | 1 · 23 | QUEUED Haiku func_801CBB80 23 (twin ov_SC06_025:0x8017ded8 d=5) | -| ov_SC03_105 | 2 · 595 | NEAR func_80185810 489 → 35 (`…/opus/func_80185810.c`) · WALL (pinned) func_801834A4 106 (S71_gate14 variants 6-off) | +| ov_SC03_105 | 2 · 595 | NEAR func_80185810 489 → 35 (`…/opus/func_80185810.c`) · WALL (pinned) func_801834A4 106 (`.run/S71_gate14/ov_SC03_105*/func_801834A4.c` 6-off) | | ov_SC06_022 | 1 · 119 | WALL (pinned) func_8017DF28 119 (`.run/S79w/sonnet/func_8017DF28.c` 2-off) | | ov_SC07_002 | 1 · 346 | NEAR func_8017DC80 346 → 46 (`…/opus/func_8017DC80.c`) | -**FAIL rows:** haiku func_801EF734 (47 vs 44 — superseded by the Sonnet MATCH), haiku func_800CF3B0 (leaf-exact; the TU decl). +**FAIL rows:** haiku func_801EF734 (47 vs 44 — superseded by the Sonnet MATCH); haiku func_800CF3B0 (leaf-exact 22/22; the +TU decl). **The 10 BANKED in T3 so far (1,063 ins):** md_SC03_054 func_801EF558 96 (`commit:3923`, sha `06bd73df…`) · +md_SC03_053 func_801EF49C 49 (`commit:3924`), func_801EF6B0 33 + func_801EF95C 20 (`commit:3927`), func_801EF624 35 +(`commit:3928`) (all `c0848f30…`) · resident func_800D06E8 344 (`commit:3925`, `8e17e02f…` — the resident is 145/145 C; its +`jtbl_80113FA4` carved by `jtbl_carve --func`) · main func_80039B20 79 (`commit:3926`), func_80023BF0 281 (`commit:3930`), +func_80038698 74 (`commit:3931`) (all `143dbb89…` via `gate_main`) · md_MAIN_007 func_800CEE2C 52 (`commit:3929`, `2ff702b6…`). -### NEXT — the T3 resume order (xHigh; each step's evidence quoted, R42 commit before the next command that can touch src/) -0. **Preflight:** `git status` (only `ghidra/` churn) · `verbatim_check --strict` (5==5) · `make check-all` **218/218 rc 0** - (R22 baseline before any bank; if red, fix the baseline first — R56) · read cookbook §500-B for each MATCH's plumbing note. -1. **md_SC03_053 ×2 (Sonnet MATCH):** for `func_801EF734` then `func_801EF7E4`: `rtu_match --split md_SC03_053 --source - md_SC03_053 --c .run/P32/t3/sonnet/.c --asm-subdir asm/md_SC03_053/nonmatchings/md_SC03_053 --work .run/P32/t3/verify/` - → splice over the `INCLUDE_ASM(…, );` line (the T3 (1)/(2) python one-liner) → `make build BINARY=md_SC03_053 -j8` - (rc via PIPESTATUS, R53) → sha `c0848f30…` == `config/check.md_SC03_053.sha` → commit → **md_SC03_053 is 100% C**. -2. **main ×2 (Opus MATCH):** one slate `[{"fn":"func_80015B6C","draft":"/.run/P32/t3/opus/func_80015B6C.c"}, - {"fn":"func_8002FDE8","draft":"/.run/P32/t3/opus/func_8002FDE8.c"}]` → `tools/gate_main.py --apply` - (read the BODY/TABLE/PLUMBING/MIXED line; clean rebuild) → sha `143dbb89…` → commit `src/800.c` + `src/800_b_2.c`. - Keep `func_8002FDE8`'s block-scope `extern s16 D_800A46D2;` (the scalar spelling IS the lever, §500-B). -3. **md_SC03_054 `func_801EF6D8` (604 + six jtbls):** `tools/jtbl_carve.py md_SC03_054 --func func_801EF6D8` (as T3 (3) - did for the resident) → `make extract BINARY=md_SC03_054` (EXIT CODE) → splice → `make build BINARY=md_SC03_054 -j8` → - sha `06bd73df…` → `pads_audit md_SC03_054` + `interleave_check md_SC03_054` (R60) → commit carve state (only this - binary's `overlays.mk`/yaml lines) + the bank. Alternative: `parallel_gate --r22` (it carves). rtu_match MATCH was - re-confirmed against the CURRENT TU (after `func_801EF558` landed). -4. **md_MAIN_007 six:** FIRST the byte-neutral plumbing commit (S77 law): `src/md_MAIN_007/md_MAIN_007.c:91` - `extern void func_800CF3B0(void *a0, void *a1, void *a2);` → `extern s32 func_800CF3B0();` (no-proto, §376 class — - keeps `func_800CF390`'s 3-arg call legal, admits the `s32 (void)` definition) → `make build BINARY=md_MAIN_007 -j8` sha - `2ff702b6…` UNCHANGED → commit. (If the sha moves: keep `void (void*,void*,void*)` and give the definition three unused - pointer params instead — the gate decides.) Then `rtu_match` each of func_800CEEFC, func_800CEF94, func_800CF068, - func_800CF148 (drop its block-scope redeclaration of `func_800CF3B0` only if cc1 objects), func_800CF2BC, func_800CF3B0 - → splice → one build → sha → commit (one commit per bank or per verified same-TU batch). -5. After 1–4: `tools/twin_rescan.py` (a bank changes the twin graph — the queued md_MAIN_009 rows may gain twins) · - `verbatim_check --strict` · R22 `make clean && make extract-all && make check-all` → quote **218 passed / 0 failed rc 0** - (R58) · `make tools-health` · refresh this block + commit. Expected census after 1–4: **33 stubs / ~4,250 ins**. -6. **Ledger the 9 NEAR** with `tools/backlog.py log` (closeness · class · best draft · cost "1 Opus agent, 30–70 min", R41): - func_800CD674 2 REGALLOC-PERM `$a3↔$t1` · func_8001BC6C 6 REGALLOC-PERM `$v0↔$v1` (qty_compare one span unit; pinned - seed → §494 `permuter_ils … --cycles 8 --secs 150 --j 3`) · func_800CD92C 15 §S7 prologue weave · func_80039308 17 - sched2 + cross-block regalloc · func_800CF3E8 27 pinned-base alias basin (§500-D1) · func_80185810 35 [permuter] 4 - emission windows · func_8017DC80 46 reload-slot frame + `la $a0` slot · func_800CF408 49 [permuter] 3 hunks · - func_800CF6D0 137 sched1 rank_for_schedule class tie. `backlog.py render`. -7. **Launch the 17 queued Haiku rows** (one per free slot, ≤20 concurrent, dequeue-then-launch; escalate a structural - FAIL to Sonnet) — but FIRST amend `BRIEF.md`'s output contract per §S80 addendum-2: final message = the JSON line ONLY - (prose → `.run/P32/t3/reports/.md`); scratch ONLY under `.run/P32/t3/work//`; never `find/rm/mv` elsewhere. - Per result: verbatim grep → your own `rtu_match` → splice/build/sha → commit → `twin_rescan`. +### 5. NEXT — the T3 resume order (each step's evidence quoted; R42: commit before the next command that can touch src/) +0. **Preflight:** `git status --short | grep -v ghidra/` (empty) · `.venv/bin/python tools/verbatim_check.py --strict` (5 == 5) + · `make check-all` → **218 passed, 0 failed of 218, exit 0** (R22 baseline before any bank; if any binary is red, fix the + baseline first — R56) · read cookbook §500-B for each MATCH's plumbing note. +1. **md_SC03_053 ×2 (Sonnet MATCH):** for `func_801EF734` then `func_801EF7E4`: `.venv/bin/python tools/rtu_match.py + --split md_SC03_053 --source md_SC03_053 --c .run/P32/t3/sonnet/.c --asm-subdir asm/md_SC03_053/nonmatchings/md_SC03_053 + --work .run/P32/t3/verify/` (expect `MATCH (N ins)`) → splice the draft over the one `INCLUDE_ASM("asm/md_SC03_053/ + nonmatchings/md_SC03_053", );` line (python: assert the line occurs once, replace with the draft text) → `make build + BINARY=md_SC03_053 -j8` (read `${PIPESTATUS[0]}`, R53) → `sha1sum build/md_SC03_053/md_SC03_053` == `config/check.md_SC03_053.sha` + (`c0848f30…`) → `git add src/md_SC03_053/md_SC03_053.c` + commit ("T3 (10) …") → **md_SC03_053 is 100% C.** +2. **main ×2 (Opus MATCH):** write `.run/P32/t3/gate/slate_main2.json` = `[{"fn":"func_80015B6C","draft":"/home/musashi/ + bfm-decomp/.run/P32/t3/opus/func_80015B6C.c"},{"fn":"func_8002FDE8","draft":"/home/musashi/bfm-decomp/.run/P32/t3/opus/ + func_8002FDE8.c"}]` (ABSOLUTE paths) → `.venv/bin/python tools/gate_main.py .run/P32/t3/gate/slate_main2.json --apply` + (a clean main rebuild; read the "slate 2 -> N compatible" and the "BANKED n main functions -- 143dbb89… BYTE-IDENTICAL" + lines; on a drop, read the BODY/TABLE/PLUMBING/MIXED verdict) → `git add src/800.c src/800_b_2.c` + commit. Keep + `func_8002FDE8`'s block-scope `extern s16 D_800A46D2;` — the scalar spelling IS the lever (§500-B). +3. **md_SC03_054 `func_801EF6D8` (604 + six jtbls):** `.venv/bin/python tools/jtbl_carve.py md_SC03_054 --func func_801EF6D8` + (as T3 (3) did for the resident) → `make extract BINARY=md_SC03_054` (EXIT CODE — a failed extract leaves a stale linker + script, §498) → splice → `make build BINARY=md_SC03_054 -j8` → sha `06bd73df…` → `.venv/bin/python tools/pads_audit.py + md_SC03_054` + `tools/interleave_check.py md_SC03_054` (R60) → commit the carve state (ONLY this binary's `config/overlays.mk` + lines + `config/splat.md_SC03_054.yaml`) + the bank. Alternative: `tools/parallel_gate.py … --r22` (it carves). The draft's + rtu_match MATCH was re-confirmed against the CURRENT TU after `func_801EF558` landed. +4. **md_MAIN_007 (six):** FIRST the byte-neutral plumbing commit (the S77 law): `src/md_MAIN_007/md_MAIN_007.c:91` + `extern void func_800CF3B0(void *a0, void *a1, void *a2);` → `extern s32 func_800CF3B0();` (no-proto, the §376 + `fix_arity_callers` class — keeps `func_800CF390`'s 3-arg call legal and admits the `s32 (void)` definition) → `make build + BINARY=md_MAIN_007 -j8` → sha `2ff702b6…` UNCHANGED → commit. (If the sha moves, keep the 3-param decl with `s32` return + and define `func_800CF3B0` with three unused pointer params instead — the gate decides.) Then `rtu_match` each of + func_800CEEFC, func_800CEF94, func_800CF068, func_800CF148 (drop its block-scope `s32 func_800CF3B0(void)` redeclaration + only if cc1 objects), func_800CF2BC, func_800CF3B0 → splice → one build → sha → commit (per bank, or per verified same-TU + batch). +5. **After 1–4:** `.venv/bin/python tools/twin_rescan.py` (a bank changes the twin graph — the queued md_MAIN_009 rows may + gain twins; it prints ready `family_remap` command lines) · `verbatim_check --strict` · R22 `make clean && make + extract-all && make check-all` → quote **218 passed / 0 failed, exit 0** (R58) · `make tools-health` → OK · refresh this + block + commit. Expected census after 1–4: **33 stubs / ~4,250 ins.** +6. **Ledger the 9 NEAR** in the backlog (`grep -n add_argument tools/backlog.py` first — the dead session's query on keys + `addr`/`fn` returned nothing for the wall rows, so confirm the row schema; then `tools/backlog.py log …` per row with + closeness · class · best draft · cost "1 Opus agent, 30–70 min" (R41) · `tools/backlog.py render`): func_800CD674 2 + REGALLOC-PERM `$a3↔$t1` · func_8001BC6C 6 REGALLOC-PERM `$v0↔$v1` (qty_compare one span unit; pinned seed → §494 + `permuter_ils … --cycles 8 --secs 150 --j 3`) · func_800CD92C 15 §S7 prologue weave · func_80039308 17 sched2 + + cross-block regalloc · func_800CF3E8 27 pinned-base alias basin (§500-D1) · func_80185810 35 [permuter] 4 emission + windows · func_8017DC80 46 reload-slot frame + `la $a0` slot · func_800CF408 49 [permuter] 3 hunks · func_800CF6D0 137 + sched1 rank_for_schedule class tie. +7. **Launch the 17 queued Haiku rows** from `.run/P32/t3/pending_launch.txt` with the prompts in + `.run/P32/t3/PROMPT_TEMPLATE.md` (substitute fn / binary / nins / sub / asm / tu / twin; keep the arm; the packs are at + `.run/P32/t3/packs/.md` — regenerate with `claude_wave_packs` if missing): **dequeue the row (`sed -i '/^ + /d' pending_launch.txt`) BEFORE launching; ≤20 concurrent** ("Concurrent subagent limit reached. … Do not retry" = + wait for a completion); each agent's final message is now the JSON line only (BRIEF amended). Per result, never in bulk: + `grep -c '\.ent\|\.word' ` (0) → your OWN `rtu_match` → splice/build/sha → commit → `twin_rescan`. A Haiku FAIL + whose note names a C-structure residual at near-exact length → escalate to Sonnet with the shape hint (the + PROMPT_TEMPLATE has the escalation prompt); a TU `conflicting types` → the §376 plumbing commit first. 8. **The NEAR tail (bounded):** permuter on the two REGALLOC-PERM seeds (func_800CD674, func_8001BC6C) via the repaired - `permuter_ils`; one Opus second look ONLY where §500 names an untested lever (func_800CF3E8: an unpinned alias of `p6` + `permuter_ils`; ONE Opus second look only where §500 names an untested lever (func_800CF3E8: an unpinned alias of `p6` for the tag load alone). Plateaus stay in the backlog. **Kill gate stands:** a session with no bank and no new verdict ends T3. -9. **T3 close:** any new idiom from steps 7–8 → cookbook §500 addendum (R16/R30); `harvest_notes.md` pointer; then **T4**. +9. **T3 close:** any new idiom from steps 7–8 → cookbook §500 addendum (R16/R30) + `harvest_notes.md`; regenerate + `docs/progress.fleet.md` (`make report`); then **T4**. -### T4 pre-read (read-only, run by the dead session at 07:00Z — its ledger repairs are still owed) -`exclude_audit --assert-fresh`: 7 entries, 7 WALL, 0 stale. Best drafts in the REAL TU today: `main:func_80011380` -`.run/m3/opus/func_80011380.c` DIFF 6 (the ledger's `.run/backlog_drafts/func_80011380.c` is MISSING — R62 path fix) · -`main:func_80032A74` `.run/S79w/opus/…` **CC1 FAIL** (redefinition of `struct Slot`/`Slot`, conflicting `A12`/`B12` vs -`src/800_shared.h:68/95` — a §376 plumbing class, re-probe before calling it a wall, R40) · `main:func_80020DA4` -`.run/S79w/sonnet/…` DIFF 2 · `main:func_80039DEC` both S79w drafts **CC1 FAIL** (`conflicting types for func_80039DEC` -— a def-side declaration wall, §495 class: fix the TU's own decl first) · `main:func_800391D4` **CC1 FAIL** (`D_80073140` -conflicting types) · `ov_SC06_022:func_8017DF28` DIFF 2 · `ov_SC03_105:func_801834A4` S71_gate14 variants DIFF 6 (the -ledger's `.run/backlog_drafts/func_801834A4.c` is MISSING). The backlog query for the seven wall rows returned nothing -under the `addr`/`fn` keys — check `backlog.py`'s row schema before rendering. +### 6. Files, tools, exact invocations, gotchas +- **`.run/P32/t3/` (git-tracked unless noted):** `BRIEF.md` (agent brief, amended) · `SYS.md` (the laws) · `targets.json` + (47 rows: name, binary, nins, sub, asm, tu, klass, closeness, model, twin, twin_d) · `pending_launch.txt` (17 rows + `binary fn nins [twin=…]`) · `verdicts.jsonl` (31) · `LAUNCHED.md` (recovery route + status) · `harvest_notes.md` · + `PROMPT_TEMPLATE.md` · `{opus,sonnet,haiku}/func_*.c` (the deliverables: 12 + 4 + 11) · `restored/sweep_func_80039308.py` + (the dead-local sweeper an agent wrote — a tool candidate) · untracked: `packs/.md` (47; regenerable), `verify/` + + `verify_*.txt` + `gate/slate_*.json` (the coordinator's own checks), `work/` `rtu/` (agent scratch), `opus/_scratch/` + `opus/x/` `opus/var/` `opus/_h/` `opus/_wk_8017DC80/` `opus/sweep/` (agent leftovers — ignorable), `restored/*.c` + (transcript replays — inferior to the on-disk finals). Census jsons: `.run/P32/frontier_*.json` (tracked). +- **Transcripts:** `~/.claude/projects/-home-musashi-bfm-decomp/c6a5fb71-f2ae-4846-a4a9-a43a4c1c3496/subagents/agent-.jsonl` + (31; `/tmp/claude-1000/-home-musashi-bfm-decomp/7beebba8-05e9-4d18-98ea-ce208f45370f/tasks/.output` are symlinks to + them; the id→function map is the `file` field of each `verdicts.jsonl` row). Never cat one; use `agent_verdicts.py` / + `agent_drafts_restore.py`. +- **`rtu_match`:** `--split --source --c --asm-subdir --work `; **main adds `--tu + src/.c`**; ``/``/`` come from `targets.json` or `corpus.stubs()` (`asm_path`, `path`). The + verdict line starts `MATCH`/`DIFF`/`CC1`. It compiles the WHOLE TU with the draft spliced — the gate predictor. +- **Build check:** `make build BINARY= -j8 2>&1 | grep -v "warning\|In function" | tail -2; rc=${PIPESTATUS[0]}` then + `sha1sum build//` vs `config/check..sha`. R53: exit code, never the file (a failed build leaves the old binary). +- **`gate_main`:** the ONLY way to gate main (incremental builds false-pass/false-diff on main, R43/§S52); slate = JSON list + of `{fn, draft(ABSOLUTE)}`; `--apply` keeps the splice on success; then `git add` the TU + commit. +- **Carves:** `jtbl_carve.py --func ` → extract (rc) → build; `pads_audit.py `, `interleave_check.py `; a + DIFF that starts at the first code byte is a stale linker script, never the draft (§498). +- **Gotchas that bit this week:** `set -o pipefail` + `grep -c` exits 1 on zero matches (a "no ghidra staged" guard + aborted a good commit) · never `cd` inside a compound command (the cwd persists into later calls) · `masked_diff.py` + leaves `src/.masked_diff_probe..c` while running — they are other agents' live probes, never delete them · the + `.run/P32/t3//` dirs are SHARED (agents are now told not to touch siblings) · the SessionStart hook launches a + headless Ghidra MCP server (`.run/ghidra-mcp.log`) — T3/T4 never use it · `agent_verdicts.py` over a whole `tasks/` dir + picks up older sessions' outputs — pass `a*.output`. -### Standing reminders -Effort **xHigh** for T3/T4, **Max** for T5 (prompt at each transition, R27) · every bank commits before the next command -that can touch `src/` (R42) · count banks from the SOURCE, quote the fleet's green count at every close (R58) · the -Ghidra MCP is not needed for T3/T4; if a hook started one, do not stage `ghidra/` (R23) · Fable only if an agent names a -wall class the codegen map lacks — STOP and prompt Drew first. +### 7. Carried context for T4 and T5 +**T4 (xHigh, no drafting) — the dead session's read-only pre-check (07:00Z):** `exclude_audit --assert-fresh`: 7 entries, +7 WALL, 0 stale. Best drafts re-run in their REAL TU: `main:func_80011380` `.run/m3/opus/func_80011380.c` DIFF 6 (the +ledger's `.run/backlog_drafts/func_80011380.c` is MISSING — R62 path fix) · `main:func_80032A74` `.run/S79w/opus/ +func_80032A74.c` **CC1 FAIL** (`redefinition of struct Slot`/`Slot`, `conflicting types for A12`/`B12` vs +`src/800_shared.h:68/95` — §376 plumbing, re-probe before a final verdict, R40) · `main:func_80020DA4` `.run/S79w/sonnet/ +func_80020DA4.c` DIFF 2 · `main:func_80039DEC` both `.run/S79w/{permuter,sonnet}/func_80039DEC.c` **CC1 FAIL** +(`conflicting types for func_80039DEC` — a def-side declaration wall, §495: fix the TU's own decl first) · +`main:func_800391D4` `.run/S79w/sonnet/func_800391D4.c` **CC1 FAIL** (`conflicting types for D_80073140` at t.c:3310 vs +:2622) · `ov_SC06_022:func_8017DF28` DIFF 2 · `ov_SC03_105:func_801834A4` S71_gate14 variants DIFF 6 (the ledger's +`.run/backlog_drafts/func_801834A4.c` is MISSING). Deliverables: each of the 7 rows PROVED vs CANDIDATE with a current +citation + an instrument-exonerated bounded attempt (R40), `exclude_audit --write`, `backlog.py render`, the wall table +into this file, cookbook §501 if a verdict changes, decision-log, accelerators. A T3 idiom naming a wall's mechanism +re-opens that row (one bounded attempt, permuter first). +**T5 (Max, Tier 1 — prompt R27; WAIT for gate 2):** P7 checkbox walk over every task above; milestone demo = R22 fleet +218/218 · `make tools-health` OK · `verbatim_check --strict` 5==5 · the final census (`tools/frontier_classify.py --json`) +· the wall ledger · parked-5 dispositions via `make audit-disc` (UNCLAIMED 0 of 220 at T2c) · `make report` all three +metrics + main `143dbb89…` WITH and WITHOUT the SDK object dirs (`.run/obj40`, `.run/obj42`; fresh-extract fallback) · +corrected denominators (main game-code 41,556 — the 22-ins Ghidra-boundary gap; the fleet denominator grew by the five +modules' ~2,600 ins at T2b). Then `PhaseEnd_Phase32.md` (+ Roadmap delta: P33 = verify + flip; + Plain-English Recap; + +the rules table incl. R64) → **append the P32 synopsis + rules to `phase-ends/DIGEST.md` (step 3b)** → `git mv +CURRENT_PHASE.md phase-ends/logs/Phase32.md` (R19) → R23 MCP stop if it ran → leave both uncommitted for Drew (R6) → 🛑. + +### 8. Environment +Fleet 218; shas of the binaries T3 touches: main `143dbb89f34491258bbc27810d0a12ec8b43a8dd` · resident +`8e17e02ff8954d07c979449198f7e1645046b353` · md_SC03_053 `c0848f308342e499e2bd8c2db86f6225a29e1592` · md_SC03_054 +`06bd73dfbdb10748adcbac7093ead5d76131206a` · md_MAIN_007 `2ff702b605ab5cfc18474c464c4c07e5f8ffd48c` · md_MAIN_009 +`d270f695…` · md_SC03_056 `bc768a6b…` (`config/check..sha` is authoritative). Toolchain unchanged (SETUP §5.4). Harness: +20 concurrent Agent-tool subagents max; an Agent call beyond that returns "Concurrent subagent limit reached" (do not +retry — wait). Claude commits, Drew pushes. Last published metrics (P31 close, 213 binaries): instr 100.0% · distinct +99.9% · fn 99.99% — regenerate with `make report` at the T3 close (218 binaries). + +### 9. Standing reminders (the rules that bite in T3) +Every bank commits before the next command that can touch `src/` (R42) · count banks from the SOURCE and quote the +fleet's green count at every close (R58) · verify a build from its exit code (R53) · a masked score is not a closeness +until its diff is read (R63) · an `__asm__` body is a verbatim, not a bank (R62) · fix the TU by a byte-neutral plumbing +commit BEFORE any gate (S77 law) · after a carve/merge touching a yaml/`.mk`: `make extract` before building, then +`pads_audit`/`interleave_check` (R60) · rules check every 4 tasks (P6) · harvest idioms into the cookbook before the next +drafting step (R16/R30) · no `Co-Authored-By` (R5) · never stage `ghidra/` (R23). + +**Plain-English recap (R18).** Last night thirty-one AI agents were set on the leftover functions; twenty produced exact +matches, but the coordinator ran out of memory after banking the first ten and one agent accidentally swept the others' +finished files into a side folder. This session read the whole record, pulled every result back out, confirmed each one +byte-for-byte, put the swept files back, wrote the lessons into the cookbook and the playbook, and — at Drew's direction — +made session start cheaper (a one-page digest of all 32 phases instead of reading them all) and made this checkpoint the +complete hand-off the next session replays verbatim. The next session's first jobs: re-verify the fleet, bank the ten +ready matches, then launch the seventeen queued small functions. diff --git a/phase-ends/DIGEST.md b/phase-ends/DIGEST.md new file mode 100644 index 0000000000..32f63f781e --- /dev/null +++ b/phase-ends/DIGEST.md @@ -0,0 +1,234 @@ +# phase-ends/DIGEST.md — the session-start digest (every PhaseEnd in one page + every rule in full) + +> **Purpose (R64 candidate, Drew 2026-09-05).** The Session Start Protocol used to read all 32 PhaseEnd files (~510 KB, +> ~150k tokens) before any work. This digest replaces that read: it carries **every rule's full text** (the rules +> acknowledgment is transcribed from here) and a **synopsis of every phase**, so a session reads `PROJECT_CONTEXT.md` +> → this file → the **three most recent** `PhaseEnd_*.md` in full → `CURRENT_PHASE.md` (and replays its 🛑 block +> verbatim into the chat). Budget: the whole protocol ≈ 100k tokens + the verbatim checkpoint. The PhaseEnd files are +> still the durable record (never deleted, R19) — read an older one on demand when a synopsis is not enough. +> **Maintenance:** at every PhaseEnd, append that phase's synopsis and its ratified rules here (a P7 checkbox). +> This file is DERIVED from the PhaseEnds and may be corrected; PROJECT_CONTEXT.md is never edited (P1). + +## 0. Where the project stands (at the latest PhaseEnd — the live state is in CURRENT_PHASE.md) +Brave Fencer Musashi (SLUS-00726) matching decomp. **Phase 31 closed 2026-09-05 (v1.30.0):** 213 binaries (main EXE + +resident engine blob + 138 location overlays + 73 `md_*` code modules) rebuild byte-identical from source; fleet +**100.0% instruction-weighted / 99.9% distinct-code / 99.99% fn-count**; 21 open stubs / 4,554 ins; main REAL 777 / +LINKED 1,256 (real PsyQ objects incl. libpad 4.2.1) / 12 stubs (99.43% byte-identical, 95.0% game-code); 5 PERMANENT +verbatim `__asm__` bodies; dedup registry 2,220 groups / 0 failures. **Phase 32 (in progress)** = the last stubs + the +five parked disc payloads, short and kill-gated; then **P33 = verify + public flip**. Roadmap: `docs/roadmap-to-100.md` +v2 (adopted 2026-07-15, rewritten 2026-07-30); jumping-off doc `docs/frontier-p32.md`. + +## 1. Corrections and supersessions of PROJECT_CONTEXT.md recorded in PhaseEnds (P1: the constitution is never edited) +- **Session start** reads this digest + the last three PhaseEnds, not every PhaseEnd (R64 candidate, Drew 2026-09-05). +- **P8 "absorb and delete CURRENT_PHASE.md"** → **R19**: `git mv` it to `phase-ends/logs/Phase.md`, out of the load + order; consult a log only when researching a past mechanism. +- **Commit cadence:** P4 per-task → R8 one-commit-at-phase-end (P2) → per-session checkpoint commits (P7) and R20 + backups → today: **one commit per completed task after CURRENT_PHASE.md is updated; a bank commits the moment it + exists (R42)**. Claude commits; **Drew pushes** (R6); the PhaseEnd + archived log are left uncommitted for Drew's + milestone-close commit; no `Co-Authored-By` (R5). +- **H1** relaxed while private (R1): ROM-derived content may be committed; the disc dump never. +- **Environment:** all-in-WSL (R2); Ghidra runs **headless** (MCP server via `tools/ghidra_mcp_start.sh` / the + SessionStart hook; symbols persist only via `tools/ghidra_apply_symbols.sh`, MCP renames do not); PCSX-Redux is + Windows-native bridged over the web API (R11); no `/tmp`, scratch under `.run/` (R12). +- **Roadmap:** the constitution's Gen1 roadmap ended at Phase 7 (Gen1 EXIT confirmed 2026-06-15); Gen2 phases 8–32 are + governed by `docs/gen2-roadmap.md` → `docs/roadmap-to-100.md` v2; **Phase 14 (public flip) is deferred to Gen3+** and + becomes P33. +- **Effort doctrine (Drew 2026-07-04, `docs/effort-map.md` governs):** xHigh for most tasks, Max for deep tasks (phase + plans, PhaseEnds, non-obvious debugging), Ultracode for breadth; plan mode always Max; every transition is prompted + (R27). Model ladder for drafters: Haiku ≤~50 ins → Sonnet ~50–120 → Opus ≥120 → Fable only for a NEW wall class. +- **Compiler triple pinned** (P6, SETUP §5.4): `gcc-2.7.2-psx cc1 -O2 -G0 -mips1 -mcpu=3000 -mgas -msoft-float + -fgnu-linker` → `maspsx --aspsx-version=2.56 --expand-div` → `mipsel-as -march=r3000 -mtune=r3000 -no-pad-sections + -O1 -G0`; per-file `-O0` modules exist (boot, the `_o0` splits). + +## 2. Phase synopses (what each phase delivered, its key finding, the rules it added) +**P1 (2026-06-13, v1.1.0) Repo governance + WSL RE stack.** Ghidra 12.1 + GhidrAssistMCP + ghidra_psx_ldr installed +headless; `SLUS_007.26` imported (1,726 fns, PsyQ 4.0.0), PsyQ types imported; the LZSS decompressor at 0x80018730 +decompiled via MCP. Rules R1–R6. +**P2 (2026-06-13, v1.2.0) Deterministic extraction.** `tools/bfm_extract` walks the disc/.CD/PAC/LZSS into 1,801 +manifest-tracked artifacts, byte-validated against CUE's `brave` (138/138 type-4). `docs/effort-map.md`. Rules R7, R8. +**P3 (2026-06-14, v1.3.0) File-loader & overlay map.** The loader is a hand-rolled CdControl reader driven by +`cdFileLocTable` (LIST.CD) + `resourceIdMap`; LZSS staging 0x80079A70; PCSX-Redux runtime oracle; resident blob +@0x800CEDF8 and location overlays @0x80128158 byte-proven against live RAM; 13 area-states; player state verified. +Rules R9–R12. +**P3.5 (2026-06-14, v1.3.1) Prototype spike — NO-GO.** Neither US prototype carries symbols; Sep-8 = retail minus 3 +functions; protos kept only as assets. Rules R13, R14. +**P4 (2026-06-14, v1.4.0) Build toolchain.** binutils-mipsel 2.42, splat64 0.41.0, pinned submodules +(maspsx/asm-differ/m2c/decomp-permuter), gcc-2.7.2-psx/cdk cc1 (i386 static); `make check-env`. No rules. +**P5 (2026-06-14, v1.5.0) All-asm byte-identical EXE** (`143dbb89…`) from the splat config; `-G0`; binutils 2.42 +byte-clean. Rule R15. +**P6 (2026-06-14, v1.6.0) Compiler pinned + first matches.** The triple above (`--expand-div` required); 14 matches; +`docs/matching-cookbook.md` and the permuter harness created. Rule R16. +**P7 (2026-06-15, v1.7.0) Gen1 EXIT.** Reports (progress/difficulty/dup); the `-O0` boot module; **real PsyQ library +objects linked byte-identical** (libcd + libgs); LZSS matched; 43 REAL. Rules R17–R19. +**P8 (2026-06-15, v1.8.0)** Eight more PsyQ libraries linked; EXE 50.24% byte-identical-from-source. Rule R22. +**P9 (2026-06-15, v1.9.0)** Binary-agnostic toolchain (`make build BINARY=`, required `--vram-base/--exe`). Rule R23. +**P10 (2026-06-15, v1.10.0)** The resident engine blob is the 2nd byte-identical binary (`8e17e02f…`, flat-blob +recipe); it detects PsyQ 4.7. Rules R24, R25. +**P11 (2026-06-16, v1.11.0)** Cross-binary dedup pipeline (`sig_image.py`, `dup_report --cross`, `config/dedup.us.yaml`, +`src/shared/`); all 134 overlays signed — 9,366 cross-binary groups. No rules. +**P12 (2026-06-16, v1.12.0)** Resident harvest 1.4% → 85.6% via the Ultracode parallel-draft + whole-binary byte-gate +(`harvest_verify.py`, `match_one.py`); the "script VM" is compiled-MIPS dispatch tables; save format documented. Rule R26. +**P13 (2026-06-16, v1.13.0)** Representative overlays; 6 binaries; `tools/new_overlay.sh`; non-4-aligned overlay +handling; dup-pair collapse. Rules R27–R29. +**P15 (2026-06-18, v1.14.0)** All 134 overlays onboarded (136 binaries); `dedup_propagate` + `engine_core.h` (match once +→ ×134); fleet 3.82% → 54.48%; `sig_unify`. No rules. (P14 public flip deferred.) +**P16 (2026-06-19, v1.15.0) PIVOT.** m2c + permuter cannot crack the loose-typed engine core (~3%); `docs/struct-core-pivot.md`. +**P17 (2026-06-20, v1.16.0)** Canonical-sig layer; the wall is the compiler's codegen, not signatures/types; 55.51%. +**P18 (2026-06-20, v1.17.0)** Compiler-quirk research → the register-pin toolkit (cookbook §17); waves 33% → 56% → 90% +close-rate; 56.64%. +**P19 (2026-06-20, v1.18.0)** Scaled waves (88/92% match_one); `canon_resident_calls`, `fix_arity_callers`; propagation +is the cap; 58.00%. +**P20 (2026-06-21, v1.19.0)** `cast_call_sites` cap tool; typedef type-lift; the `%lo`-fold class cracked; 58.82%. Rule R30. +**P21 (2026-06-26, v1.20.0)** The automation manager (`gate_stage`, `worker_wave`, `grinder`, `orchestrator`, backlog +ledger, `idiom_loop`); 63.18%; automated ceiling byte-proven; a 5-scout sweep found no external shortcut. +**P22 (2026-06-29, v1.21.0)** Tractable giants banked ×134; 63.66%; pivot to the local LLM tier. +**P23 (2026-07-02, v1.22.0) THE BREAKTHROUGH.** Local 7B tier saturates ≤15-ins ($0); **Fable reading the gcc-2.7.2 +source cracks "unsteerable" classes** → the §31 codegen map (`docs/gcc-2.7.2-map/`); 64.86%; `gcc-papermario` is +gcc 2.8.1 — vanilla 2.7.2 staged under `tools/reference/`. +**P24 (2026-07-08, v1.23.0)** Permuter overhaul (masked scorer, §31 class weights, ILS); integration-recovery tools; +every matched giant ×134 (incl. the 770-ins whale, the 400-ins flagship); 66.02%; the h_norm structural-family reframe. +**P25 (2026-07-11, v1.24.0)** Family engine (`family_remap`/`family_sweep`, `canon_sig_reconcile` v3.2, `rtu_match`); +giant endgame complete; 74.6% fn / 58.2% instr / 30.3% distinct; the h_seq reframe → `family-endgame-megaplan.md`. Rule R31. +**P26 (2026-07-15, v1.25.0)** Family engine + the **26-A tooling-integrity audit** (`corpus.py`, `cdecl.py`, +`audit-corpus` — the tools WERE several walls) + the §52 discovery flywheel; 68.9% instr / 49.2% distinct; mechanical +harvest exhausted. Rules R32–R34. +**P27 (2026-07-15, v1.26.0)** Instruments fixed (fail-closed Makefile, one typedef-strip primitive, second oracle on +resident); disc audit 136 → 140 + 39 type-1 modules found; the pin-crash "wall" was a tool bug; 67.0% (denominator +correction). Rule R35. +**P28 (2026-07-16, v1.27.0)** Instrument repair; B2 LIVES (its 0/8 was a missing carve); SC07 pool wired via +`dedup_extend` (6,174 members); resident 90%; 68.9%. Rule R36. +**P29 (2026-07-30, v1.28.0) THE FAMILY CAMPAIGN.** 25 sessions / 552 commits; 68.9 → 87.5% instr, 49.5 → 78.0% distinct; +`diff_regions.py` resolved the swing number (tooling); integration, not idioms, is the wave bottleneck; roadmap v2. +Rule R37 proposed. +**P30 (2026-08-14, v1.29.0)** Recovery & concentration; 87.5 → 95.3% instr; fleet 140 → 213 (disc audit + module +onboarding); the zero-token mechanical pipeline (`aprop_autodraft`, `symfix`, `prechecks`, `gate_lane`); the §172 wall +model. R37 operated as binding; R38–R39 proposed. +**P31 (2026-09-05, v1.30.0) THE FRONTIER ATLAS & WIDE-TOLERANCE CAMPAIGN.** 30 sessions / ~1,660 commits; the atlas +(`atlas.py`), 6,000-ins waves, autonomous lanes, a completion sprint; stubs 12,059 → 21; fleet 95.3 → 100.0% instr; +main 1,041 → 12 open; libpad 4.2.1 + RTL 4.2 archive linked (twelve "walls" were Sony objects); the verbatim `__asm__` +class censused to 5 PERMANENT rows; `gate_main` (main gates only by clean rebuild). R37–R39 ratified; R40–R43 + R61 +accepted; R44–R60, R62–R63 proposed → **all ratified at P32 gate 1 (2026-09-05)**. +**P32 (open 2026-09-05)** The last 21 + the parked 5 (short, kill-gated) — see `CURRENT_PHASE.md`. + +## 3. Every rule, in full (transcribe these at session start; P/G/H/X are in PROJECT_CONTEXT.md) +- **R1 — H1 relaxed while private.** ROM-derived content (`asm/`, `assets/`, `extracted/`, decompressed `.CD`) MAY be + committed while the repo is private; accidental inclusion is not a violation. The raw multi-GB disc dump stays ignored + regardless. Compliance before going public = history scrub + a rom→decoder regeneration tool. +- **R2 — All-in-WSL (H2 restatement).** One ext4 clone at `~/bfm-decomp`; no Windows/WSL split, no second clone, no + `/mnt` builds; MCP is loopback `127.0.0.1:8080`. +- **R3 — All tooling under `tools/`.** Including `tools/bin` (compilers), `tools/psyq*`, `tools/ghidra_scripts`. +- **R4 — Plan mode every phase.** Present the task-by-task plan and get approval before executing (the Phase Start gate). +- **R5 — No `Co-Authored-By` trailer on commits.** +- **R6 — Git workflow = Claude commits in WSL, Drew pushes.** Never `git push` from the WSL CLI. Phase-boundary + exception: Claude writes `PhaseEnd_PhaseN.md` and archives `CURRENT_PHASE.md` but leaves them uncommitted; Drew + commits AND pushes the milestone close. +- **R7 — Effort-map check.** Before each Phase Start, state the recommended effort for planning that phase per + `docs/effort-map.md` and confirm the developer has it set; annotate every task in the plan with its effort; restate the + recommended effort whenever presenting the NEXT task. `docs/effort-map.md` is the evolvable source of truth. +- **R8 — One commit at phase end** (P2; since superseded in practice by per-task commits, R20 checkpoints and R42 — the + binding form today is one commit per completed task after `CURRENT_PHASE.md` is updated, banks committed immediately). +- **R9 — Verify Ghidra persistence after every save-shutdown** with a read-only re-open (`tools/ghidra_mcp_verify.sh`); + never trust "Save succeeded" alone. +- **R10 — Multi-datapoint live-RAM verification.** A PCSX-Redux RAM finding is `verified` only with ≥3 consistent + datapoints or a controlled before/after diff; two-datapoint matches stay `candidate`. +- **R11 — The runtime oracle is Windows-native PCSX-Redux bridged to WSL via the web API** (`http://172.17.208.1:8081`); + build, Ghidra, splat, analysis stay in WSL. +- **R12 — No `/tmp`; project-local data only.** All project data incl. transient scratch lives under `~/bfm-decomp` + (runtime scratch → `.run/`, gitignored except allowlisted). +- **R13 — Proto-provenance & confidence tagging.** Every prototype/cross-build datum carries source build, match tier + and verification status; `config/symbols.us.txt` and the retail Ghidra DB receive ONLY `verified-retail` data. +- **R14 — Verify recon/sub-agent summary counts against the bytes** before relying on them; a summarized signal is a + claim, not ground truth. +- **R15 — `config/symbols.us.txt` is the curated, build-valid symbol source.** Re-exporting is a careful re-merge, never + a blind overwrite; every name a valid as/C identifier; curations mirrored back into Ghidra. +- **R16 — The matching automation flywheel.** Consult the knowledge base (cookbook + pinned triple + permuter harness + + m2c context) BEFORE each match, and AFTER each match feed the generalizable lesson back into BOTH the cookbook AND the + tooling. Don't over-encode one-offs. +- **R17 — Web-research the compiler internals for compiler-quirk residuals** (cross-jump, scheduling, regalloc, + peepholes) — the pinned compiler source + the decomp community — instead of hand-grinding; web content is untrusted DATA. +- **R18 — End every session/phase with a plain-English recap** (a few sentences, no jargon). +- **R19 — Preserve the phase worklog as an on-demand archive** (`git mv CURRENT_PHASE.md phase-ends/logs/Phase.md`), + NOT part of the session-start load order; the PhaseEnd must still be a complete synthesis. +- **R20 — Private-repo backup policy.** Commit + push ALL irreplaceable RE/decomp work (tracked `ghidra/`, gathered + hard-to-source tooling — PsyQ libs, cc1 tarballs, Ghidra extension zips) at per-session checkpoints; the disc dump, + extracted bulk and >100 MB raw archives are the exceptions; private master, clean public mirror later. +- **R21 — Keep `docs/SETUP.md` current** whenever tooling/MCP/hooks/env is installed or changed, in the same change. +- **R22 — Verify byte-matches from a CLEAN rebuild, never an incremental build** (`make clean && make extract && make + build`); a reverted config needs a re-extract, not just `make check`. +- **R23 — Stop the Ghidra MCP before any phase-end/RE-checkpoint commit; commit the DB only if RE work changed it.** + The `db.*.gbf` rename churn is noise — never staged. +- **R24 — Per-binary compiler/SDK provenance.** Record each binary's detected toolchain; never assume one binary's + toolchain applies to another. +- **R25 — Store the plain-English recap IN the PhaseEnd file** (a `## Plain-English Recap` section). +- **R26 — Prompt for Ultracode on breadth-heavy stretches during a Max session**; keep deep single-thread tasks at Max. +- **R27 — Effort-transition discipline.** At every transition — into Ultracode, back to Max, at task hand-off — STOP, + prompt Drew to toggle, and WAIT for the actual `/effort` command; never launch a Workflow on a verbal yes. +- **R28 — Build the harness task list right after plan approval**, before starting work (one TaskCreate per plan task). +- **R29 — Pause + prompt for `/mcp` reconnect after any MCP server restart/program switch**, then one cheap + `get_binary_info` (G2) before continuing. +- **R30 — Capture context-dependent knowledge artifacts DURING the producing session**, before any fresh-session handoff; + defer only mechanical/continuable work. +- **R31 — Capture the WHY behind strategic pivots in `docs/decision-log.md` while fresh**: context+belief → what failed → + the pivot → the measurement-grounded why → a hindsight "better path". +- **R32 — Assert your COVERAGE.** A corpus scanner compares what it found against an over-approximating candidate set + and fails on the gap; a silent skip is a defect, and a loud failure nobody counts is exactly as invisible. +- **R33 — Derive, don't re-derive.** Where a proven invariant answers the question, derive from it rather than re-parse + the source; the best outcome is a DELETED scanner. +- **R34 — A second, DISAGREEING oracle — not a better assertion** — when an oracle is structurally blind to an error class. +- **R35 — Fix the measuring instrument before trusting its measurement; a probe from a broken tool is not evidence.** + Tool-integrity is a precondition of a measurement, not a parallel concern. +- **R36 — A newly-discovered binary is not real until every consumer knows it** (sig set, family map, dedup registry, + shared-header include, reports) — asserted by a gate (`make audit-binaries`), not remembered. +- **R37 — Probe before costing.** Ground every estimate/attribution on ONE instance; derive counts from `corpus.stubs`; + diff the artifact to prove an edit actually ran before judging the lever it carried. +- **R38 — Read the recorded failure verdicts before designing an experiment** (`.run/harvest_failed.*.classified.txt`, + gate results, journals) — the answer is frequently already recorded. +- **R39 — Negative-control every new refusal-check against the already-succeeded population**; zero false positives + before it ships. +- **R40 — Exonerate the instrument before attributing a failure to its subject** (truncation, fences, rate limits, tool + faults first; ~a third of P31's "walls" were tooling). +- **R41 — Every cost/rate/yield/effort number ships with its denominator.** +- **R42 — Commit banked work the moment it exists**, before the next command that can touch `src/` (a gate IS one); + never blind-revert a dirty `src/`; count banks from the SOURCE. +- **R43 — A tool must refuse an input it cannot handle, never process it wrongly.** +- **R44 — A card may not name a lever the knowledge base does not contain.** +- **R45 — Draw-time bankability: never draw a card the pipeline cannot bank.** +- **R46 — A budget is part of the harness, not a constant.** +- **R47 — Consume every verdict layer** (a stage reading one bit of one oracle staged garbage forever). +- **R48 — Never key by bare function name** (scratch dirs, ledgers, drafts — collisions destroy work). +- **R49 — A soft error inside a success envelope is still that error** (a 200 carrying code 429; `rc≠0` read as "no binary"). +- **R50 — Periodic whole-fleet verification** (a byte gate is silent about every binary it did not build). +- **R51 — A derived property stored as config will go stale and take a binary with it**; derive it or give it a + byte-proven self-repair. +- **R52 — A blanket committer must not adopt a collapsed file** (right for `src/`, wrong for config). +- **R53 — Verify a build from its exit code, not its output file** (a failed build leaves the previous binary in place). +- **R54 — A guard downstream of the failure is not a guard, and a guard that is not running is not a guard.** +- **R55 — A lane that runs unattended must leave evidence** (progress logs; empty log + no ps hits = never started). +- **R56 — A gate verdict measures the draft only while the binary's baseline is green**; check the baseline first. +- **R57 — An instrument's own write path is part of the instrument.** +- **R58 — A session-close "clean" must quote the fleet's green count** (tree-clean ≠ fleet-green). +- **R59 — A blanket commit of another lane's mid-gate tree is a race, not a backup.** +- **R60 — `config/overlays.mk` and the splat yamls are CARVE STATE**: a gate commit carries only its own binary's lines; + any blanket restore/commit is followed by `interleave_check` + `pads_audit` on every touched binary. +- **R61 — A tool must distinguish "judged and failed" from "not judged", and a judging tool must model what the gate + does to the draft** (a loop tool that reports "unchanged" for N cycles must prove it iterated). +- **R62 — A ledger's best draft may never be an `__asm__` body, and a bank whose body is `__asm__` is a verbatim, not a + bank** (`verbatim_check --strict` in the per-bank close). +- **R63 — A permuter/waypoint score is not a closeness until its diff is read.** +- **R64 (CANDIDATE, Drew-directed 2026-09-05; ratify at PhaseEnd_Phase32) — Session start reads PROJECT_CONTEXT.md → + `phase-ends/DIGEST.md` → the three most recent PhaseEnds → `CURRENT_PHASE.md`, then replays the 🛑 SESSION CHECKPOINT + block VERBATIM into the chat; the protocol costs ≈100k tokens + the checkpoint. Every PhaseEnd appends its synopsis + and rules to the digest (P7). A checkpoint is written to be replayed: self-sufficient, verbose, every path/command/hash + explicit (see `checkpoint-current-phase-before-pause` memory).** +(R40–R43 and R61 were accepted mid-P31; their long forms are in `phase-ends/logs/Phase31.md` — the one-liners above are +the binding text. R44–R63 one-liners are the P31 table, ratified at P32 gate 1.) + +## 4. Where things live (the doc map a session needs) +`docs/SETUP.md` (environment, every tool's row, commands) · `docs/matching-cookbook.md` §1–§500 (idioms; 3.5 MB — +grep by §, never read whole) + `docs/cookbook-index.md` (symptom-keyed, derived, 566 KB — grep) · `docs/gcc-2.7.2-map/` +(the compiler map) · `docs/wave-playbook.md` (THE wave procedure; `docs/automation-runbook.md` is retired) · +`docs/effort-map.md` · `docs/roadmap-to-100.md` v2 · `docs/frontier-p32.md` · `docs/decision-log.md` (R31) · +`docs/accelerators.md` · `docs/memory-map.md` (addresses, provenance) · `docs/formats.md` · `docs/disc-completeness.md` + +`docs/disc-ledger.md` · `docs/backlog.md` (near-miss ledger) · `config/wave_exclude.txt` (pinned walls) · +`config/verbatim_manifest.json` · `phase-ends/logs/` (on demand only, R19) · `.run/` (scratch; allowlisted subtrees are +tracked — e.g. `.run/P32/t3/` drafts/ledger). diff --git a/phase-ends/README.md b/phase-ends/README.md index 33f9fcf981..51e4204858 100644 --- a/phase-ends/README.md +++ b/phase-ends/README.md @@ -2,4 +2,6 @@ - `PhaseEnd_Phase[N].md` — written at each phase boundary (format defined in `PROJECT_CONTEXT.md`). Append-only history: build log, deviations, commit message, rules added, changelog. Never deleted. - `CURRENT_PHASE.md` — the in-phase autonomous log: approved phase plan, per-task checkboxes, current task pointer, blockers. Created at phase start, updated after every task, absorbed into the PhaseEnd file and deleted at phase close. This is the crash/compaction recovery point. -- Sessions read `PROJECT_CONTEXT.md`, then every `PhaseEnd_*.md` in numeric order, then `CURRENT_PHASE.md` (if present) — in that order, every session. +- `DIGEST.md` — the session-start digest: every phase's synopsis + every rule in full + the corrections to PROJECT_CONTEXT.md; appended at every PhaseEnd (P7). +- `logs/Phase.md` — the archived in-phase worklogs (R19): NOT in the load order; consult on demand only. +- Sessions read `PROJECT_CONTEXT.md`, then `DIGEST.md`, then the THREE most recent `PhaseEnd_*.md` in numeric order, then `CURRENT_PHASE.md` (if present), and replay its 🛑 SESSION CHECKPOINT block verbatim into the chat — every session (R64 candidate, 2026-09-05; ≈100k tokens + the checkpoint).