diff --git a/docs/accelerators.md b/docs/accelerators.md index 548cc71a48..693fea77b9 100644 --- a/docs/accelerators.md +++ b/docs/accelerators.md @@ -771,3 +771,9 @@ definition; a load-bearing `[][1]` extern vs the TU's `[]`). Copying the TU unde `src/shared` beside it, editing the declaration THERE and passing `--tu ` to `rtu_match` reproduced every residual (1/2/3) with zero commits to `src/` — the byte-neutral TU edit is deferred to the day a row reaches closeness 0. Accelerator: `rtu_match --tu` accepts any path; a sandbox costs one `mkdir` + two symlinks. + +**(9) A lever that measures worse may be a cascade (P32 T4b, `func_800391D4`, §501).** The hand pass measured the right +lever (explicit promotion before `off = 0`) at 18 and moved on; the agent's `.loop` dump showed the 18 was ONE hoist that the +lever's -2 in-loop instructions had flipped past loop.c's desirability threshold, paid back with two more `__asm__("")` pads → +MATCH. Accelerator: on any regression of a mechanism-grounded lever, diff the pass dumps for a second change before discarding +the lever; treat `insn_count` pads as a dial that must be re-counted after every in-loop instruction change. diff --git a/docs/cookbook-index.md b/docs/cookbook-index.md index a44313de93..def566c8d2 100644 --- a/docs/cookbook-index.md +++ b/docs/cookbook-index.md @@ -2,7 +2,7 @@ > **Generated by `tools/cookbook_index.py` — do not hand-edit** (R33). Regenerate after adding a cookbook section. > -> `docs/matching-cookbook.md` is ~716 KB / 1168 sections. Grepping it blind is how three P30 wave-1 agents each "discovered" an idiom that was already written down. **Start here, then read the section.** A section appears under every symptom it addresses. +> `docs/matching-cookbook.md` is ~716 KB / 1169 sections. Grepping it blind is how three P30 wave-1 agents each "discovered" an idiom that was already written down. **Start here, then read the section.** A section appears under every symptom it addresses. **How to use:** name what you SEE in the diff (a stolen delay slot, an extra `la`, a swapped register pair, a `conflicting types` error), find that symptom below, read those sections first. If nothing fits, THEN grind — and add a section when you win. @@ -205,7 +205,7 @@ - **§476** — 🔴 A HARD-REGISTER PIN DESTROYS TWO THINGS COMBINE AND SCHED1 NEED (`func_800226C0`, 670 ins → MATCH) L35612 - **§482** — ★★★ — TWO INDEPENDENT RE-TIES, ORDERED: WHEN ONE BARRIER FIXES ONE RESIDUAL AND CREATES THE OTHER (P31 S77, `main:func_8006252C`, 30 ins → MATCH) L35932 -### register allocation & pins (138) +### register allocation & pins (139) - **§10** — Closing the regalloc/scheduling hard tail by hand (LZSS, Phase 7 session F — the full close) L854 - **Residual** — A — commutative `|`/`&`/`+` result lands in the wrong source-operand register L875 @@ -345,6 +345,7 @@ - **§463** — 🔴 SPILL SLOTS ARE 8 BYTES, AND THE §41b "LOAD ABOVE THE PROLOGUE" WALL IS REFUTED L35677 - **§478** — 🔴 — A VERBATIM DRAFT IS THE STRONGEST *FALSE* SIGNAL YOUR SCOPING TOOL CAN EMIT L35787 - **§499** — ★★★ — A NEVER-ONBOARDED PAYLOAD PINS ITS OWN BASE STATICALLY, AND THE FIRST BUILD CANNOT (P32 T2a/T2b: the parked five onboarded, 213 → 218 binaries, 0 UNCLAIMED) L36748 +- **§501** — ★★★ — A LEVER THAT MEASURES WORSE MAY BE A CASCADE: READ THE `.loop` DUMP FOR THE DESIRABILITY FLIP BEFORE DISCARDING IT (P32 T4b, `main:func_800391D4`, a pinned wall banked by a Fable agent) L37147 ### CSE / redundancy / rematerialization (50) @@ -399,7 +400,7 @@ - **§470** — FOUR CSE/SCHED LEVERS FROM `main:func_800301C8` (170 ins, 133 → 18) L35437 - **§475** — THE `"memory"` FENCE AS A *CSE INVALIDATOR*, AND `(b*3)<<3` INSTEAD OF `b*24` L35581 -### loops & induction variables (49) +### loops & induction variables (50) - **§3-T1** — Loop pointer: top-of-body for `addu` induction, not constant-folded `addiu` L71 - **§34** — The `func_80138ED0` giant crack: gcc-2.7.2's **3-qty sort bug** + the **zero-byte asm allocation toolkit** + the **giv-init fence** (Phase 24 T5; Opus→close=21, Fable5→MATCH ×134) L2473 @@ -450,6 +451,7 @@ - **§418** — ★★★ — TWO LOOP-STRUCTURE LEVERS: MAKE THE SECOND INDEX A GIV, AND KEEP A TABLE ADDRESS UNFOLDED (P31 S71; byte-proven `ov_SC04_016/func_8017DF8C`, 184 ins, 32 → 0 in seven compiles) L33632 - **§430** — ★★★ — A GOTO INTO A LOOP IS FINE; HAND-HOIST THE CONSTANTS IT COSTS YOU (P31 S73 — **this section previously said the OPPOSITE and was wrong; the refutation is kept below**) L34073 - **§472** — 🔴 §148-A's HOIST THRESHOLD IS 29, NOT 58, WHEN THE LOOP CONTAINS A CALL L35489 +- **§501** — ★★★ — A LEVER THAT MEASURES WORSE MAY BE A CASCADE: READ THE `.loop` DUMP FOR THE DESIRABILITY FLIP BEFORE DISCARDING IT (P32 T4b, `main:func_800391D4`, a pinned wall banked by a Fable agent) L37147 ### structs, block moves & memcpy (92) @@ -1312,7 +1314,7 @@ - **§499** — ★★★ — A NEVER-ONBOARDED PAYLOAD PINS ITS OWN BASE STATICALLY, AND THE FIRST BUILD CANNOT (P32 T2a/T2b: the parked five onboarded, 213 → 218 binaries, 0 UNCLAIMED) L36748 - **§500** — ★★★ — THE T3 WAVE HARVEST (P32 T3, 2026-09-05): 31 one-agent-per-function drafters → 20 MATCH / 9 NEAR / 2 FAIL, every closer, two NEW named gcc mechanisms, and the wave-process defects L36789 -### process, measurement & doctrine (141) +### process, measurement & doctrine (142) - **§8e** — The jtbl ALIGNMENT LAW + the pad-spec filter — multi-table .rodata spans (Phase 29, byte-proven; `.run/probe_jtbl/verdict.md`) L549 - **§3-The** — mechanism: game-code dedup is SOURCE-LEVEL, not an object swap (R-D1, the key lesson) L945 @@ -1455,6 +1457,7 @@ - **§473** — 🔴 §265's "HANDWRITTEN" VERDICT FOR `ov_SC07_002:func_8017DC80` IS REFUTED (324 → 89) L35519 - **§463** — 🔴 SPILL SLOTS ARE 8 BYTES, AND THE §41b "LOAD ABOVE THE PROLOGUE" WALL IS REFUTED L35677 - **§479** — ★★★ — WHERE THE PERMUTER ACTUALLY PAYS: A MEASURED YIELD CURVE (P31 S77, 8 candidates) L35807 +- **§501** — ★★★ — A LEVER THAT MEASURES WORSE MAY BE A CASCADE: READ THE `.loop` DUMP FOR THE DESIRABILITY FLIP BEFORE DISCARDING IT (P32 T4b, `main:func_800391D4`, a pinned wall banked by a Fable agent) L37147 ### (unbucketed — title matched no symptom vocabulary) (337) @@ -2967,6 +2970,7 @@ - **§498** — ★★★ — A CARVE THAT DROPS THE BINARY'S `--pre` CLAUSE, AND A GATE THAT IGNORED THE EXTRACT'S EXIT CODE: HOW A BYTE-CORRECT DRAFT WAS BOOKED "DIFF" (P32 T1a; resident `func_800D128C` BANKED 243 ins after two instrument fixes) L36718 - **§499** — ★★★ — A NEVER-ONBOARDED PAYLOAD PINS ITS OWN BASE STATICALLY, AND THE FIRST BUILD CANNOT (P32 T2a/T2b: the parked five onboarded, 213 → 218 binaries, 0 UNCLAIMED) L36748 - **§500** — ★★★ — THE T3 WAVE HARVEST (P32 T3, 2026-09-05): 31 one-agent-per-function drafters → 20 MATCH / 9 NEAR / 2 FAIL, every closer, two NEW named gcc mechanisms, and the wave-process defects L36789 +- **§501** — ★★★ — A LEVER THAT MEASURES WORSE MAY BE A CASCADE: READ THE `.loop` DUMP FOR THE DESIRABILITY FLIP BEFORE DISCARDING IT (P32 T4b, `main:func_800391D4`, a pinned wall banked by a Fable agent) L37147 --- @@ -4147,3 +4151,4 @@ Notes routinely quote that as a section id. This table resolves it. Grep bait: ` | L36718 | §498 | ★★★ — A CARVE THAT DROPS THE BINARY'S `--pre` CLAUSE, AND A GATE THAT IGNORED THE EXTRACT' | | L36748 | §499 | ★★★ — A NEVER-ONBOARDED PAYLOAD PINS ITS OWN BASE STATICALLY, AND THE FIRST BUILD CANNOT ( | | L36789 | §500 | ★★★ — THE T3 WAVE HARVEST (P32 T3, 2026-09-05): 31 one-agent-per-function drafters → 20 MA | +| L37147 | §501 | ★★★ — A LEVER THAT MEASURES WORSE MAY BE A CASCADE: READ THE `.loop` DUMP FOR THE DESIRABI | diff --git a/docs/matching-cookbook.md b/docs/matching-cookbook.md index 803dac7946..7a69c87ff0 100644 --- a/docs/matching-cookbook.md +++ b/docs/matching-cookbook.md @@ -37143,3 +37143,33 @@ and a build-instrument collision fixed at the consumer.** line; `exclude_audit --assert-fresh` 7/7. Unpinned candidate with a cited mechanism: `md_MAIN_003:func_800CF3E8` 27 (§500-H). * **Law.** A wall's CC1 FAIL in its TU is evidence about the TU's declaration environment, never about the body; re-probe before any verdict, and prefer a sandbox TU over a src/ edit when the row is not going to bank. + +#### §501 ★★★ — A LEVER THAT MEASURES WORSE MAY BE A CASCADE: READ THE `.loop` DUMP FOR THE DESIRABILITY FLIP BEFORE DISCARDING IT (P32 T4b, `main:func_800391D4`, a pinned wall banked by a Fable agent) + +**The row.** Pinned since S79 (closeness 3, "move_movables splices hoisted invariants after preheader flow code, so +`off`'s init cannot follow arg1's hoisted sign-extend from C"); four attempts + permuter null; T4 re-probed 3 in a sandbox TU. +**The S83 hand pass tried the obvious lever** — write the `s16` parameter's promotion as preheader SOURCE code +(`a1v = arg1;` before `off = 0;`, compare against `a1v`) — measured **18** and recorded it as worse. It was the RIGHT lever. + +**What the 18 really was (the agent read `dumps/*.i.loop`).** Making the extend explicit moved its two insns OUT of the loop +body: `Loop from 38 to 189: 59 real insns` → 57. `move_movables`' desirability test (loop.c:1631) +`threshold * savings * lifetime >= insn_count` with `threshold = 2 * (1 + 28) = 58` (no call in the loop) flipped for the +`lui/addiu D_800C6DD0` address (savings 1, lifetime 1): `58 < 59` "not desirable" became `58 >= 57` "moved" — +2 preheader +insns and a register cascade. **Every one of the 18 rows was that single hoist.** The fix is to restore the knife-edge: the +S79 draft's seven `__asm__("")` pads (each counts as a real insn for `insn_count`, emits nothing) become NINE. Then the +preheader tail is the target's `sll $5,$5,16 / sra $5,$5,16 / move $8,$0`, and rtu_match MATCH 75/75 → `gate_main` BANKED. + +**Laws.** +1. **When a mechanism-grounded lever regresses, do not trust the number — diff the `.loop`/`.greg` dump of the lever variant + against the seed and look for a SECOND change** (a hoist, a spill, a coalescing) that the lever triggered. Fix the second + change with its own zero-byte dial (pads for `insn_count`, a fence for a live range, a pin for an allocno) and re-measure. +2. **`insn_count` is a dial and a knife-edge.** `__asm__("")` pads count as real insns for loop.c's threshold and emit nothing; + any source change that adds or removes in-loop instructions (hoisting a promotion, folding a temp) must be paid for by + re-counting the pads so the SAME movables stay un-hoisted. The S79 seed had already discovered the pads; the S83 hand pass + did not re-count them after moving the extend. +3. **A `register … __asm__("$N")` pin on the loop counter keeps it from being a biv** (loop.c:3572: hard regs are not bivs), so + `D[i]` is never a giv — the target's per-iteration `sll/lui/addu/lw` survives. Keep such pins when the target shows an + un-strength-reduced index. +4. The verdict chain for a wall row: hand pass names the mechanism (done S83), the agent reads the dump the hand pass did not + (the `.loop` desirability lines), and the byte gate decides. Cost: one Fable agent, two interruptions by usage limits, the + draft written before the first crash — recovered from `.run/P32/t5x/fable/` (write deliverables EARLY, R55). diff --git a/phase-ends/CURRENT_PHASE.md b/phase-ends/CURRENT_PHASE.md index 550e943056..1f872d4e6c 100644 --- a/phase-ends/CURRENT_PHASE.md +++ b/phase-ends/CURRENT_PHASE.md @@ -99,7 +99,7 @@ Scale estimate: 3–5 sessions. `func_80011380` → `.run/m3/opus/func_80011380.c`; `func_801834A4` → `.run/S71_gate14/ov_SC03_105*/`), `exclude_audit --write`, `backlog.py render`; a T3 idiom naming a wall's mechanism re-opens that row (bounded: one attempt, permuter first). Wall table into this file; cookbook §496+; decision log; accelerators. -- [ ] **T4b — crack and bank the final 15 (ADDED 2026-09-05 by Drew's directive, supersedes the kill gate: "anything that isn't the original hand-written asm or the PsyQ libs needs to be cracked and banked before we finish"; "before you spawn Fable agents, hand crack each and figure out the blocker to fix it")** (xHigh→Max recommended; Fable agents authorised AFTER the hand pass): for each of the 15 rows (8 NEAR + 7 walls) the coordinator hand-cracks — read the diff + the recorded mechanism, read the compiler (dumps + source), find the lever the record did not try, measure, bank through the verified chain (rtu in the real TU → bank.sh / gate_main) — and only then hands the leftovers to one Fable agent each (brief `.run/P32/t5x/BRIEF.md`). Plumbing landed first: `src/800_c.c` decl/extern edits byte-neutral (this commit). Work dirs `.run/P32/t4b//`. **Hand pass DONE 2026-09-05 (S83): all 15 rows read against their diffs and the compiler; 22 spellings measured (all regressions), 0 banks; every row's blocker refined to a named mechanism with the untried lever written in `.run/P32/t4b//NOTES.md` (func_80032A74: the transient caller-save area — reload1.c order proven; func_8017DF28: the block-move pseudo reuse vs reorg's branch-target hoist; func_80011380: the target's assignment shape; func_801834A4: sign-hoist vs const-hoist thresholds; …). TU plumbing for func_80039DEC/func_800391D4 committed byte-neutral (`commit:3953`). NEXT: one Fable agent per row from `.run/P32/t5x/` (BRIEF.md + packs + the NOTES), then bank per result.** +- [ ] **T4b — crack and bank the final 15 (ADDED 2026-09-05 by Drew's directive, supersedes the kill gate: "anything that isn't the original hand-written asm or the PsyQ libs needs to be cracked and banked before we finish"; "before you spawn Fable agents, hand crack each and figure out the blocker to fix it")** (xHigh→Max recommended; Fable agents authorised AFTER the hand pass): for each of the 15 rows (8 NEAR + 7 walls) the coordinator hand-cracks — read the diff + the recorded mechanism, read the compiler (dumps + source), find the lever the record did not try, measure, bank through the verified chain (rtu in the real TU → bank.sh / gate_main) — and only then hands the leftovers to one Fable agent each (brief `.run/P32/t5x/BRIEF.md`). Plumbing landed first: `src/800_c.c` decl/extern edits byte-neutral (this commit). Work dirs `.run/P32/t4b//`. **Hand pass DONE 2026-09-05 (S83): all 15 rows read against their diffs and the compiler; 22 spellings measured (all regressions), 0 banks; every row's blocker refined to a named mechanism with the untried lever written in `.run/P32/t4b//NOTES.md` (func_80032A74: the transient caller-save area — reload1.c order proven; func_8017DF28: the block-move pseudo reuse vs reorg's branch-target hoist; func_80011380: the target's assignment shape; func_801834A4: sign-hoist vs const-hoist thresholds; …). TU plumbing for func_80039DEC/func_800391D4 committed byte-neutral (`commit:3953`). 15 Fable agents launched ~13:05 MDT (two usage-limit outages, resumed each time via SendMessage). **T4b (1): `main:func_800391D4` BANKED 143dbb89 (`commit:3956`) — a pinned wall: explicit promotion + insn_count pads 7→9 (§501); pin dropped (6 remain).** Remaining 14 in flight.** - [ ] **T5 — PhaseEnd** (Max, Tier 1 — prompt R27): P7 checkbox walk; milestone demo (R22 fleet N/N, tools-health, `verbatim_check --strict`, final census, wall ledger, parked-5 dispositions via `make audit-disc`, `make report` all three metrics + main `143dbb89…` with/without SDK dirs, corrected denominators); **WAIT