# CURRENT_PHASE — Phase 36: levers off — every compiler-forcing construct out of the matched C (v2.1.0 → v2.2.0) > **Gate 1 approved by Drew on 2026-09-09 (S97; plan mode at Max; Fable 5.1).** The Gen3 order is Drew's: dedup (P35, closed) → > **pins** → structs → names. Drew widened the phase at gate 1: *"this phase we also want to remove the asm volatiles and the "r"'s > and all the other compiler hints/hacks"* — so the unit of work is a **lever site** of any class (register pins, asm statements > incl. every `"r"`-constraint hack, volatile levers, bare `register`), and the phase's product is a tree with **no register pin and > no asm statement left** (decision 2: grind to zero), the GTE coprocessor asm consolidated under Sony's names, the byte-needed > `volatile`/`register` kept as ordinary C and counted, and a self-asserting census as a `tools-health` gate. The approved plan is > reproduced VERBATIM at the end of this file (§"Approved plan"). **Baseline HEAD at open: `e6d98dd1d`** (Drew's P35 close commit, > v2.1.0). **R22 obligation:** every batch that touches `src/` is followed by the clean fleet run (218/218) before its commit — > this phase changes no byte, ever. **Rules ratified at gate 1 by the plan approval: R100–R106** (the PhaseEnd_Phase35 candidates > (a)–(g); Drew may still veto any of them — say so and the DIGEST entry is amended). ## Milestone (gate 2 — what Drew confirms, each with its literal output) 1. `tools/lever_census.py --check --strict` → **0 register pins, 0 asm statements** outside the one GTE header, the byte-needed `volatile`/`register` counted and unmarked, the counts published in `docs/progress.json` / the README block with the dated snapshot, the coverage assertion green; `tools/verbatim_check.py --strict` unchanged (the five 1998 routines untouched). **Amended S104 (Drew, 2026-09-10; decisions §S104):** a site T7 cannot close now stays a MARKED minimum-lever site, counted in the published split and named for the structs phase — "0" is the structs phase's finish line, not this phase's gate. 2. The ledger names, for every site, the rung and the instrument that judged it (REMOVED / REWRITTEN / NEEDED-kept / the wave that reshaped it) — R65-style attribution. 3. `make clean && make extract-all JOBS=16 && make check-all JOBS=16` → `check-all: 218 passed, 0 failed of 218` (R22); `make tools-health` OK with the new rung; the GTE macros in one header; no per-TU lever macro definitions. 4. The record (T9) written; PhaseEnd_Phase36.md, the DIGEST append, the log archived (T10); v2.2.0. ## Effort / model (R7/R26/R27 — every transition is PROMPTED, never assumed) - **Max** for T2 (the probe and its pricing), T3's design, T10 (the PhaseEnd); **xHigh** for T0, T1, T3's finish, T4, T5, T6, T8, T9; **low** for T0's bookkeeping. Max is session-only (re-apply each session); xHigh is the highest persistent level. - **Ultracode ONLY for T7** (the reshaping waves — breadth), and only after Drew's actual `/effort ultracode` toggle (R27); the coordinator's own judgment (harvest, toolify, the packs) stays at Max — flip back before each harvest. - **Drew-only (R6):** every `git push`; the gate-2 confirmation; the milestone-close commit + the `v2.2.0` tag. - Drafter escalation inside T7 (the model-ladder memory): Opus for exemplars ≤ 150 instructions, Fable above or on a new wall class. ## Tasks (plan order; one commit each; ☐ → ☑ with the verify line quoted in the log) - ☑ **T0** (S97, commit `63b886626`) — Baseline and the phase file: R22 clean fleet at the open `check-all: 218 passed, 0 failed of 218` (88 s); `.gitignore` P36 evidence allowlist; this file; the harness task list (R28, 11 tasks); `git status` clean after the commit. - ☑ **T1** (S97) — `tools/lever_census.py`: `lever_census: 218 binaries · 4,121 TUs + 3,181 headers · coverage OK · unclassified 0 · verbatim excluded 5 fn / 5 sites (manifest 5)`; controls 4/4 exact; **THE PHASE'S NUMBER: 53,221 sites (37,720 register pins + 15,501 asm statements) in 15,666 bodies (2,214 distinct)**; `progress.py --json --readme --check` fresh (the `levers` block + the README sentence); `make report BINARY=main` OK (226 s); dictionary + SETUP rows; kit corpus regenerated. The finding of the task — 23 whole-body assembly routines inside C shells, outside the manifest — is in the log and the decisions section (Drew's call). - ☑ **T1b** (S97; added on Drew's confirmation, P5d) — The verbatim manifest learns the in-function form: 23 rows (`binary: "ov_*"`, `form: "in-function"`; 22 PERMANENT-VERBATIM trampolines + `func_80184440` DECOMPILE-NOW); `tools/verbatim_check.py` detects the form structurally through `lever_census.whole_body_asm_functions` (.c and `src/shared/**/*.h`) with wildcard matching — `--strict` green; the census defers the exclusion to the manifest (`asm-body` → `verbatim-body` only when PERMANENT): **the phase's number is 53,222 sites in 15,667 bodies (2,215 distinct)** (+1: the DECOMPILE-NOW body is a lever); `progress.py` counts PERMANENT rows (27) with a dated `corrections` entry; README prose + wiki Home + Where-next + gen3-standards + gen3-handoff updated as dated snapshots; `progress.py --json --readme --check` fresh; `doc_links --strict` green. - ☑ **T2** (S97) — The probe. `tools/delever_oracle.py`: 4,284 recipes captured in 14 s; `--calibrate ov_SC04_011 ov_SC03_015 ov_SC03_014 main`: **177/177 objects byte-identical untouched; twin checks 32 (0 mismatch); positive control DIFFERS on build/src/800.o — OK** (main 0.079 s per object mean, 0.77 s for `800.o`; overlays ~0.14 s). `tools/delever.py --probe --sample 300 --seed 11 -j 12`: **285 distinct bodies sampled, 283 judged, 1,660 compiles, 151 s wall; rung A identical 53/283; lever-free after rung B 53/283; sites 1,309 usable → removed 561 (42.9 %), needed 748 (57.1 %)**; the table is in the log entry below and in `.run/P36/probe/probe_table.md`. - ☐ **T3** (Max design) — `tools/delever.py` + `tools/delever_cycle.sh`: rungs A/B/C, group testing per TU with per-symbol attribution and the 2 % per-body control, shared headers greedy-on-one/verify-on-all (h_text on all), the in-memory snapshot + `inflight.json` as the only restore, the ledger keyed alias+tu+function+address, refusals, progress logs, negative controls, selftest with decoys. Verify: selftest; the calibration line; one batch on one overlay end-to-end with R22 green. - ☐ **T4** — The mechanical campaign over the whole population (headers → multi-copy classes → singletons), batches < 10 min, R22 every 2 batches, one commit per batch carrying the census line, the log line and the 🛑 headline. Verify per batch: `delever: batch — sites removed / needed in bodies; gated / objects identical`; R22 `218 passed`. - Rules check (P6) after T4. - ☐ **T5** — GTE consolidation (one header, PsyQ's names; the `"memory"`-clobber variants are levers → residue, not a second spelling) + the dead lever-macro sweep (`SHB` cross-file use counted). Verify: `lever_census` 0 per-TU asm macro definitions; R22 green. - ☑ **T6** — Rung R (mechanical shape recipes, each negative-controlled) and rung D (the permuter on the residue exemplars, time-boxed, 16 workers; a score-0 applied through `delever --apply-body` and gated). Verify: `recipes: of NEEDED sites removed`; `permuter: of exemplars matched lever-free in h`. - ☐ **T7** (Ultracode, prompted) — The reshaping waves to zero: wave → harvest → toolify (cookbook + rung R) → sweep → next draw; wave 1 ≈ 40–60 exemplars reported with yield and tokens per bank (R41); stop rule = residue 0. Rules check (P6) after wave 1 and every fourth task thereafter. - ☐ **T8** — The gate: `// !FAKE:` markers from the ledger mid-campaign; `lever_census --check` in `make tools-health` (0 UNMARKED); `--strict` at close (0 pins, 0 asm outside the GTE header, manifest unchanged); `progress.py` final split. Verify: `lever_census --check --strict: pins 0, asm 0, volatile-needed , register-needed — OK`; tools-health OK. - ☐ **T9** — The record (cookbook §, decision log P36, accelerators, SETUP rows, wiki, gen3 snapshots, tool-index, kit corpus, `doc_links --strict` 0/0, tools-health OK). - ☐ **T10** (Max) — Close: R22 218/218; tools-health OK; PhaseEnd_Phase36.md + DIGEST §0/§2/§3 + this log archived (R19) + kit corpus; left uncommitted for Drew's close commit; v2.2.0. ## Decisions (owner's words, in order) - **Gate 1 (2026-09-08/09, S97):** *"this phase we also want to remove the asm volatiles and the "r"'s and all the other compiler hints/hacks."* → the scope widened from pins to every lever class (the plan's classes A–D). - **Scope question:** Drew chose *"A–D now, GTE consolidated"* — classes E (asm-label aliases), F (`__builtin_*`), G (`__attribute__`) are DEFERRED to the structs/types phase, where the canonical declaration layer (R95) removes their reason to exist. - **Residue question:** Drew chose *"Grind to zero"* — waves continue until no register pin and no asm statement remains, regardless of token cost; the phase does not close with a residue. `// !FAKE:` is the MID-campaign honesty marker only. - **Marking question:** Drew chose *"Keep unmarked, ledgered"* — a byte-needed `volatile` or bare `register` stays as ordinary C (1990s code used both), recorded in the ledger and the published count; `!FAKE` goes only on a surviving pin/asm statement. - *"just to confirm we aren't including the hand crafted asm code from 1998 right?"* → **confirmed NOT in scope:** the five hand-written assembly routines in `config/verbatim_manifest.json` (PERMANENT) are the original's code; the census excludes them by the manifest and `verbatim_check --strict` stays green. The 1,256 Sony objects are linked, not source. The GTE coprocessor ops are Sony's own inline-asm idiom and are kept under the SDK's names. - **T1 finding → Drew (2026-09-09): *"confirmed per your recommendations."*** → **T1b added (P5d):** the manifest extended with the in-function form; `verbatim_check` taught the form; the README count regenerated (5 → 27 PERMANENT; the 23rd routine, `func_80184440`, is `-O0` compiler output — frame-pointer prologue around two global stores — and is listed DECOMPILE-NOW, a Phase-36 residue counted as a lever). The 20 per-overlay trampoline families (133 private copies each, bytes varying with the wrapped callee) are the names phase's parameterized-form inheritance. - **S103 (2026-09-10), Drew: *"max concurrent agents is 5, leave the ones you have running, but maintain max of 5 concurrent agents from now on."*** → the T7 agent lane runs at most FIVE agents at once (six were running when he said it; they finish, and no new one launches until fewer than five are live). - **S104 (2026-09-10), Drew, on S103's four open questions:** *"your 4 questions i dont know enough to answer theese. 1. we can leave it in for now and come back later and fix them. we should check sotn decomp and see what they do here, 2, i dont know. i believe we decided on leaving GTE for now and cominb back later. 3, all sites are redcusable to C, the 1998 devs wrote it in C right?. anything we can't hit now, we come back to durnig struct work because that is likely the missing peice to egetting the C shape right without pins. 4, huuh? a new phase for types?. for all 4 questions, search the sotn decomp"* → read from sotn-decomp's tree (R106; shallow clone `tools/reference/sotn-decomp` @ `6cbc55a`, 2026-09-11, ignored; X2 — data): **its PSX C carries 0 `register … asm` pins and 0 asm statements** (all 31 asm statements in `src/` are Saturn/PSP or data directives) across 2,987 C files — **it keeps 3,101 `INCLUDE_ASM` stubs instead**; its fakes are ordinary C marked by `docs/STYLE.md`'s rule *"A fake should be commented with an `// !FAKE:` above or to the side of the code"* — `do { … } while (0)` (e.g. `st/nz0/gaibon.c:563` "do-while needed on PSX but not PSP", `libc/sprintf.c:129` `} while (0); // FAKE`, `dra/5087C.c:476` "temp variables, meaningless self-assigns, and do-while(0)"), `if (prim && prim) { // !FAKE`, `volatile u32 pad; // !FAKE:`; its GTE ops are ONE header (`include/psxsdk/libgte.h`, 44 `gte_*` macros, `__asm__ volatile`) that **adds 7 macros Sony's `inline_c.h` does not have**, three of them three-op load forms (`gte_SetRGBfifo`: three `lwc2`; `gte_SetIR123`/`gte_SetMAC123`/`gte_SetRii`: three `mtc2`/`ctc2`, no clobber). **Dispositions:** (a) `do { } while (0)` and the dead-initialiser cousin STAY as ordinary C for now, marked `// !FAKE:` per sotn's rule, not a census lever class; revisit later (Drew). (b) GTE deferred — T5 as planned, and when it runs, sotn is the precedent that a project-local macro (a respelled `gte_stORGB`, a three-op load) belongs in the one GTE header. (c) **Every site is reducible to C** (Drew: the 1998 code was C, and sotn shows a PSX decomp with zero pins); a site T7 cannot close now stays a MARKED minimum-lever site, counted, and is carried to the **structs phase** (the missing piece is likely the struct shape) — the phase's milestone "0 pins, 0 asm" is amended to "every surviving site marked, counted, and named for the structs phase" (P5d, on Drew's word). (d) "the types phase" in S102–S103's checkpoints is NOT a new phase — it is the **structs phase**, the third in Drew's Gen3 order (dedup → pins → structs → names; R95's canonical type layer is its core); the signature changes (`func_8017FC5C`, `func_80180200`, `func_80185578`, `func_80157D20`, `func_80168828`) go there with their ready patches. - **S98 (2026-09-09), Drew, mid-T3:** *"dont start ultra code wave for reshaping without my direct approval."* → **T7's reshaping waves (Ultracode) start ONLY on Drew's direct approval in the session that would run them** — the R27 toggle is necessary, not sufficient; the T6 recipe/permuter rungs and the mechanical campaign are not waves and proceed under P3. ## Rules at gate 1 (P10) **R100–R106 ratified by the plan approval (2026-09-09; the PhaseEnd_Phase35 candidates (a)–(g), operated through P35):** R100 a shared body has exactly one source; a duplicate copy is a defect the health chain asserts, its count published with its rule · R101 every commit that advances a task — an intra-task bank included — carries its log line and the 🛑 headline; a checkpoint older than HEAD is a dead session's checkpoint · R102 a tool that restores files restores from its own snapshot, never `git checkout` on a tree it did not commit · R103 a failure-cause extractor is negative-controlled against the compiler's real message forms, not the word "error" · R104 build the disagreeing oracle before the batch runs, and measure its disagreement before believing either side · R105 a registry lists a member only after the gate has spoken for it; a listed member whose site does not share is a defect the check names · R106 a policy taken on a remembered precedent is a belief — read the target project's tree. **Candidates for Phase 37 gate 1 accumulate here as the phase produces them.** ## Log (append-only; one entry per step, with the literal verify line) - **S97 2026-09-09 — session start.** Session-start protocol at low effort, then Drew: `/effort max` + plan mode. Reconnaissance: two Explore agents (pin tooling + the P32 recipes; the gate machinery), one Plan agent (the tool/oracle design, 257k tokens), my own census (the numbers in the plan's population table) and two read-only probes: `make -n -W BINARY=` prints the exact per-object recipe in 0.04–0.06 s (main carries `jtbl_rodata_pads.py --derive main --tu `; a twin compiles the primary's source into its own object); `tools/compile_only.py` omits the pad stage and is NOT a faithful oracle. Three AskUserQuestion forks answered (the decisions above). Plan approved (ExitPlanMode); harness tasks #1–#11 created (R28). - **S97 — T0 baseline.** `make clean && make extract-all JOBS=16 && make check-all JOBS=16` → `extract-all: 217 extracted, 0 failed of 217 (+ main, serial)` · **`check-all: 218 passed, 0 failed of 218`** · `wall=88.46 s user=1384.22 s sys=197.47 s` · `exit=0` (`.run/P36/baseline/r22_t0.log`). Tree clean at `e6d98dd1d` before the run. Headless Ghidra MCP running (2 GB; no RE work planned — stop it via the sentinel at any checkpoint commit, R23). Memory 31 GB (29 available), disk 32 GB free. - **S97 — Plan-agent findings carried into T2/T3 (recorded here so a fresh session has them):** (1) a per-candidate `make ` would overwrite the baseline object and `.d` in `build/` — extract the recipe once per object (`make -n -W`), replay it with `-o` to scratch and `-MF` to scratch; (2) objects embed the source path as an `STT_FILE` symbol (`readelf -s build/src/800_c.o` → `FILE … src/800_c.c`, from cpp's first line marker) — compile IN PLACE at the real path (in-memory snapshot restore) or rewrite the marker if a probe file is used; (3) ~208 pins use the `asm("$4")` spelling that `PIN_RE` and the gate-1 grep miss (e.g. `src/ov_SC03_099/ov_SC03_099_jr_8017BEBC.c:3056`); (4) the file-scope `extern volatile` class is ~526 + 3 (the gate-1 8,262 counted the `volatile` token inside GTE macro definitions); (5) the agent's census: 15,430 lever bodies, 47,766 sites, 2,557 TUs + 353 shared headers, sites per body median 2 / p99 20 / max 45; (6) 330 asm-bearing macro names, mostly PsyQ's `inline_c.h` names already (`gte_ldv0` 839 defs / 9 texts; a 171-definition variant carries a byte-relevant `"memory"` clobber) plus address-suffixed private copies; `SHB` 416 defs / 2 texts; `ENGINE_SHB` 8 uses; one shared header (`src/shared/ov/func_80166F58__3728db8a.h`) uses the INCLUDER's `SHB`; (7) rung A can be group-tested per TU (strip every lever body at once, one compile, attribute per symbol with `masked_diff.insns_from_object`) with a 2 % per-body control (R34); rung B batched across a TU's failing bodies; (8) `!FAKE` reason codes: SCHED-ANTIDEP (§373/§3-2), CSE-REMAT (§153/§176-D1), CROSSJUMP-FENCE (§336), ARGCOPY-ADDU (§194-E), BLOCKCOPY-EXPAND (§176-D2), UNCLASSIFIED; (9) refuse: file-scope `register`, a pin declarator with a function-pointer `(`, a live `#if` inside a body, copies that disagree, a header whose registry and census includers differ, h_text includers disagreeing; (10) dotfile probes must be swept before any `make` (the P32 S83 precedent). - **S97 — T1 the lever census (`tools/lever_census.py`, 720 lines).** Derived from `share_census.scan_text`'s masked-text defs; a token walk in which every `asm|__asm|__asm__` / `register` / `volatile` / `__builtin_*` / `__attribute__` token receives one role; coverage per line against the RAW text; asm-bearing macro names harvested from every `#define` first (so `SHB(x)` / `gte_ldv0(...)` uses are classed by what they expand to); string-literal tokens roled "string"; the manifest's five bodies matched by every `.globl`/`.ent` name of a file-scope block (one block defines a data label THEN the routine — the first name is not enough; and `\t` in C string text is two characters, not whitespace). Fixture selftest `OK — 23 sites, 2 defs, 2 asm macros` (decoys: a comment with a pin, `asm(` inside an INCLUDE_ASM path string, an `#if 0` pin, a multi-line GTE define, a `!FAKE`-marked pin and barrier). Fleet run 32 s at -j16. **Coverage (R32):** asm raw 80,396 = live 66,415 + macro-block 7,189 + comment/dead 6,792 · register 46,408 = 37,806 + 18 + 8,584 · volatile 14,000 = 4,883 + 6,510 + 2,607 · builtin 599 = 445 + 0 + 154 · attribute 76 = 76 + 0 + 0; unclassified 0. **Controls (R39):** `src/800.c func_800226C0` 45 pins ✓ · `src/shared/ov/func_80178004.h` 26 ✓ · `ov_SC03_006 func_80184034` 3 bare-name pins ✓ · `engine_prelude.h` 0 asm sites (a macro definition only) ✓ — each counted by hand at gate 1 with an independent grep. **The table (2026-09-09; `.run/P36/census/lever_census.{json,txt}`):** A pins 37,720 in 13,279 bodies (1,833 distinct; `$0` 1,337, `$sp` 13, with initializer 5,140, volatile-qualified 136, bare-name 76, spelled `asm(` 210) · B asm 25,096 (barrier 5,835 · launder 5,233 · keepalive 2,576 · instruction 1,857 [addu 1,103, move 407, la 145, lh 134, addiu 24, RTP_SND 22, …] · gte 6,911 · verbatim-body 2,683; 14 at file scope) · C volatile 3,139 (cast 2,385 · decl-body 235 · decl-file 517 · param 2) · D bare register 86 · E asm-label 7,428 · F builtin 445 · G attribute 76 · **union A–D 19,164 bodies / 2,545 distinct** (488 multi-copy classes hold 17,107 bodies; by kind ov 18,330 · shared 393 · md 213 · main 212 · resident 16) · **the phase's number 53,221 sites in 15,666 bodies (2,214 distinct), 0 marked, 53,221 UNMARKED** · asm-bearing macro definitions 9,540 (338 names, 32 with >1 text; gte 9,102 · launder 428 · instruction 9 · barrier 1). **Corrections to the gate-1 numbers (R14):** pins 37,720 live, not 40,346 (the grep counted 8,584 `register` tokens in comments and dead code); file-scope `extern volatile` 517, not 8,262 (the gate-1 count included the `volatile` token inside 6,510 GTE macro lines); bare `register` 86, not 290; asm statements 15,501 once GTE (6,911) and the verbatim bodies (2,683) are set apart. **FINDING (R32, P9): 23 whole-body assembly routines live inside C shells** — `void func_801285E4(void) { extern s32 D_801840B4; __asm__ __volatile__(".set noreorder\n" "addiu $sp, $sp, -24\n" "lui $v1, 0x1f80\n" "ori $v1, $v1, 0x03fc\n" "sw $ra, 16($sp)\n" "addu $t0, $v1, $zero\n" "sw $sp, 0($t0)\n" … : : : "memory"); }` — 2,683 sites: 20 routines with one private copy per overlay (133 each; bytes vary per overlay — 134 distinct `h_exact` at 0x801285E4 across 141 sig rows, each copy wrapping its overlay's own callee) + one shared header each, and 3 shared-header-only routines (`func_80128678`, `func_80155FF8`, `func_80184440`). They switch `$sp` to the scratchpad (0x1F8003FC) around a call — a stack-switch trampoline no compiler emits; 18–37 instructions each, ~448 per overlay. They are the §265 "verbatim-asm bank lane" in its IN-FUNCTION form, which `tools/verbatim_check.py` (a file-scope `__asm__` detector) and the manifest's P31 S75 derivation never saw: the manifest lists 5 file-scope rows, the README says "Five functions across the fleet are hand-written assembly", and `progress.py`'s `verbatim_asm_bodies` = 5. The census sets them apart as `verbatim-body` (not levers), publishes them in the README sentence, and the decision below is Drew's. **Aside for the record:** 0x801285E4 has 141 sig rows and the S1 class at that address 3 instances — the other 138 are per-overlay byte variants (singleton classes), not an S1 gap. - **S97 — T1b the manifest's in-function form.** Drew confirmed the recommendation. Rows built from the census sites + the sig files: 22 routines carry the trampoline signature (`0x03fc` + `sw $sp`; 20 with 133 private copies each + a shared header, bytes varying per overlay — 134 distinct `h_exact` of 141; `func_80128678` and `func_80155FF8` shared-only, byte-identical fleet-wide) → PERMANENT-VERBATIM; `func_80184440` (13 ins, 2 binaries) has an `-O0` frame-pointer prologue around two global stores → DECOMPILE-NOW (a carve into an `-O0` unit; a lever until then). `tools/verbatim_check.py --strict`: `verbatim bodies in tree: … in-function sites across 23 routines · manifest rows: 28 (23 of them fleet-wide "ov_*" in-function rows) · no drift` (the literal line is in `.run/P36/baseline/verbatim_check_t1b.log`). The census's `asm-body` kind is structural (the asm statement is the function's only statement; declarations aside) and the manifest decides: `verbatim-body` 2,682 sites / 22 routines excluded; `asm-body` 1 site (`func_80184440:DECOMPILE-NOW`) counted — **53,222 sites in 15,667 bodies (2,215 distinct)**. README block: `27 hand-written-assembly bodies kept verbatim`; prose + wiki + gen3 docs dated. - **S97 — T1b, second pass: the structural detector found 21 MORE in-function bodies.** The first census had applied the whole-body test only to templates classed `instruction`; `tools/verbatim_check.py`, detecting structurally (the asm statement is the function's only statement, declarations aside) through `lever_census.whole_body_asm_functions`, listed 70 NEW — 49 of them false positives of the declaration regex (`iVar1 = …` read as type `iVa` + name `r1` with an initializer; fixed with `\b` after every identifier and a size pre-filter — the unbounded regex had also made the guard take minutes) and **21 genuine**: 8 Sony libgs `GsTMDfast*` renderers in `src/800b2.c` (the cookbook's §176-area bank: libgs code carried as asm where no SDK object of that version matched) and **13 game functions carried whole as assembly inside C shells** — main `func_8001E378` (188 ins), `func_80020F34` (53), `func_800249F0` (116), `func_80025CBC` (127), `func_80026514` (239), `func_800268D0` (293), `func_80027058` (106), `func_80027200` (125); `md_MAIN_027: func_800CBA44` (109), `md_SC07_003:func_801A3BCC` (372); `ov_SC04_016:func_8017E26C` (269), `ov_SC06_032:func_8017D810` (33), `ov_SC07_000:func_8017EEC0` (8) — plus the shared `func_80184440` (13, `-O0` shape). None is in the P31 S75 taxonomy (200 rows, all file-scope): the lane's in-function form was never censused. **Manifest now 49 rows:** 27 PERMANENT-VERBATIM (5 file-scope + 22 trampolines) · 8 SDK-VERBATIM (Sony's code, not ours) · 11 DECOMPILE-NOW (compiler-shaped prologue, no hand-asm marker) · 3 UNCERTAIN (`$at` present: `func_80026514`, `func_800268D0`, `func_8017E26C` — adjudicate). `verbatim_check --strict`: `verbatim bodies in tree: 2709 (5 file-scope, 2704 in-function sites across 44 routines) · manifest rows: 49 (23 of them fleet-wide "ov_*" in-function rows) · no drift` (`.run/P36/baseline/verbatim_check_t1b.log`). The census excludes only PERMANENT/SDK dispositions (by name for `ov_*` rows, by (binary, addr) for concrete ones — `share_census.verbatim_instances` now skips the wildcard rows); DECOMPILE/UNCERTAIN bodies are LEVERS: **the phase's number is 53,234 sites in 15,679 bodies (2,227 distinct)** (pins 37,720 + asm statements 15,514, of which 14 are whole-body asm functions to decompile). README block: `27 hand-written-assembly bodies kept verbatim · 8 Sony library routines carried as assembly where no SDK object matched`. **P9 finding for the record:** the P32 close's "every game-code function in every binary is C" was measured by instruments blind to the in-function form (`progress.py`'s verbatim bucket and `verbatim_check` are file-scope detectors); 14 game functions (8 in main) were assembly in C shells all along. The README prose is corrected in this commit; the decision log carries it at T9; Drew's word on the SDK/DECOMPILE/UNCERTAIN split is asked at the T1b report. - **S97 — T2 the oracle and the probe (R37).** *The oracle* (`tools/delever_oracle.py`): every object's exact build command captured once through `make -n -W BINARY=` (4,284 recipes, 14 s at -j16 — the Makefile's own pipeline with the jtbl pad stage of main/module objects, the per-object `-O0` overrides, the twin rule); a candidate compiled IN PLACE (objects carry the source path as an STT_FILE symbol) with `-o`/`-MF` redirected to scratch, the file restored from the in-memory snapshot after every compile; verdict = whole-object byte equality with `build/`'s object of the T0 fleet run. **Calibration:** `177/177 objects byte-identical untouched; twin checks 32 (0 mismatch); positive control DIFFERS on build/src/800.o; 2.3 s — OK` (`.run/P36/delever/calibration.json`; two instrument findings on the way: a control injected BEFORE the declarations is a C89 parse error, so it goes at the end of the body; gcc 2.7.2 reports errors without the word "error" and the assembler floods stderr with `$at` warnings — the error filter keeps every non-warning line, R103). *The engine* (`tools/delever.py`): positional rewrites per class at the census's line/col on the raw text (a token mismatch REFUSES); rung A strip-all (measured with `register` dropped and kept), rung B greedy; TUs in parallel (one worker per file), **shared headers SERIAL after the TU phase** — the dry run's three "compile errors" were two workers' candidates crossing inside one includer (a header edit reaches every includer: the campaign tool must never compile a TU while any header it includes is being edited). A no-op edit is REFUSED (an identical object would prove nothing, R37). **The probe (`--probe --sample 300 --seed 11 -j 12`; `.run/P36/probe/`):** 285 distinct bodies (one exemplar per normalized class, stratified by binary kind × site count × class mix, topped up for the `$0`/initializer/instruction/cast/register/launder/keep-alive features), 283 judged (2 NOTHING-USABLE), **1,660 compiles, 151 s wall, 0.225 s per compile, 5.87 compiles per body**. | kind | bodies | A identical | A (register kept) | lever-free after B | sites | removed | needed | compiles | s/compile | |---|---:|---:|---:|---:|---:|---:|---:|---:|---:| | main | 40 | 6 | 6 | 6 | 272 | 146 | 126 | 328 | 0.386 | | resident | 16 | 4 | 4 | 4 | 31 | 9 | 22 | 53 | 0.06 | | md | 29 | 2 | 2 | 2 | 121 | 56 | 65 | 161 | 0.139 | | shared | 40 | 7 | 7 | 7 | 164 | 65 | 99 | 216 | 0.211 | | ov | 158 | 34 | 34 | 34 | 721 | 285 | 436 | 902 | 0.195 | | **all** | **283** | **53** | **53** | **53** | **1,309** | **561 (42.9 %)** | **748 (57.1 %)** | **1,660** | **0.225** | Needed by kind: pin 360 of 798 (45 %) · launder 154 of 199 (77 %) · barrier 127 of 154 (82 %) · keep-alive 36 of 44 · instruction 21 of 24 · cast 26 of 51 · decl-body volatile 16 of 27 · bare register 8 of 12. **Needed pins by register class: v0/v1 126 · a0–a3 112 · s0–s7 71 · t0–t9 36 · $0 13** (removed: s 147 · t 107 · v 90 · a 87). Residue bodies 230 of 283: 75 need only pins, 129 need at least one asm statement. Bodies with a launder 4/68 lever-free, a barrier 9/78, a `$0` pin 1/17, a cast 1/22, an initializer pin 7/32. `register` dropped vs kept: identical results (53 = 53) — the keyword is byte-neutral at -O2 on this sample. Instrument noise: rung A 1 COMPILE-ERROR + 1 REFUSED; 6 of 748 needed sites judged by a compile error (0.8 %); 9 rewrites refused (multi-instruction templates, `mult`/`mfhi`, a bare `addu $v0,$zero,$zero` with no C operands, `RTP_SND` macro-carried instructions). **Pricing (R41; population 16,064 lever bodies / 55,913 removable sites, 2,633 distinct classes by body hash):** T4 (rungs A+B fleet-wide) ≈ 94,000 compiles ≈ 5.9 CPU-h ≈ **0.5 h wall at 12 workers** — cheap, and it removes ≈ 24,000 sites (43 %) and frees ≈ 3,000 bodies (19 %). **The residue ≈ 13,000 bodies / 32,000 sites ≈ 81 % of bodies — by distinct classes ≈ 1,800 exemplars** whose copies replay: that is the campaign grind-to-zero prices (T6 recipes + permuter, then T7 waves). Where the residue sits: launders + barriers + keep-alives (317 of 748 needed = 42 %) — the CSE/scheduling steers; v0/v1 + a0–a3 pins (238 = 32 %) — argument/return-register copies (the §194-E/§17a ARGCOPY class); callee-saved pins (71 = 9 %) — the allocation-order class (R73, `alloc_table.py`); the rest casts, volatile declarations, `$0` variables, instructions. **Design consequences for T3:** per-body compiles at 0.2 s make group testing unnecessary (simplicity wins); run T4 first and publish the fall; rung R (T6) targets the three big classes in that order. - **S98 2026-09-09 — T3 the campaign tool (design at Max; the tools built, the end-to-end batch follows).** Session start at low effort; Drew: `/effort max`, "build task list and resume current phase"; the harness task list rebuilt (R28, 12 tasks; T0–T2 completed). Reconnaissance on T2's engine and probe before any design (R37/R38): three findings that CHANGE the numbers — (1) **989 of the 4,793 direct launders are ASSIGNMENTS** (`__asm__("" : "=r"(p) : "0"(&D_x))` — output ≠ input); the probe deleted them as statements, which left the variable undefined and **cc1 2.7.2 ABORTED** (the probe's one "Done" COMPILE-ERROR, `ov_SC03_124 func_80188C68` launder at 3449, reproduced 3/3: rc 134, `Aborted (core dumped) | tools/bin/gcc-2.7.2-psx/cc1`; the error filter had kept bash's job-status line and dropped the signal line) — the probe's "launder 77 % needed" is partly this; (2) the **macro-carried launders are mostly compound macros** (`XFER`/`DRAW`/`RTP_SND`/`COPY_TO_FAAC`, ~60 uses in 8 definitions: real code around the asm — the probe's rewrite deleted the whole USE statement, which is a correctness hazard; only `SHB`/`ENGINE_SHB` (416 defs / 2 texts, 399 uses) are pure launder statements and `LAUNDER_8018A180` a launder statement-expression); (3) **46 lever bodies live in `-O0` translation units** (boot.c 31 bare `register` + 6 instructions; `md_MAIN_003_o0*` / `md_MAIN_011`) — the plan's "none have pins" was about pins; they are judged by their own recipes, not refused (the ledger records `o0`). Also measured: 5 lever bodies not named `func_` (addresses from `config/symbols.us.txt`), 1 class whose members disagree on the site sequence (the replay checks it), 369 header bodies (203 with < 20 includers, 165 with 120–139), 517 file-scope `volatile` declarations in 256 TUs, 2 `volatile` parameters, 0 multi-declarator pins, nested includes only `engine_prelude.h` → `include/` (the includer scan is transitive anyway). **Design (X1, the non-obvious choices):** the verdict unit is the body, the write unit the file, the proof unit the file's FINAL compile (every body judged against the original text; all accepted edits + the file-scope volatile edits + the markers spliced once and compiled through every recipe — a twin's object, every includer of a header in parallel; DIFFERS → the file-scope edits dropped and retried → the file restored and COMBINATION-FAILED, loud); **"done" is a ledger fact keyed by normalized text** (every row carries the body's `nhash` BEFORE and AFTER; current nhash ∈ after-hashes → done, ∈ before-hashes → replay in one compile, a disagreement falls through to the full ladder and is recorded; markers are comments and do not move the hash; a reshaped body gets a new hash and is drawn again — so T6/T7 need no new bookkeeping); the launder-assignment and macro-shape rewrites above; the oracle's **COMPILE-CRASH** verdict (a signal line / rc ≥ 128, R103) distinct from COMPILE-ERROR; class C/D survivors judged, ledgered, never marked (decision 3), class A/B survivors marked `// !FAKE: — (P36