diff --git a/.run/backlog.jsonl b/.run/backlog.jsonl index e3d3e2b88..0e9590f6c 100644 --- a/.run/backlog.jsonl +++ b/.run/backlog.jsonl @@ -1295,3 +1295,6 @@ {"ts": "2026-07-31 08:07:34", "addr": "0x8018057C", "name": "func_8018057C", "reach": null, "klass": "JR-ISOLATE-BREAKS-BYTES", "nins": 897, "status": "blocked", "closeness": null, "where_stuck": "S28: SS81 step 1. jr_isolate_all --only reported success (2 jr in 1 -O2 object -> 2 region .c) but post-isolate make build was NOT byte-identical. Aborted before any bank; tree reverted. Log .run/s28_beh_ov_SC01_009_iso.log. NOT diagnosed, NOT a compiler wall.", "best_draft": ".run/beh-gate/ov_SC01_009/func_8018057C.c", "binary": null, "source": "ov_SC01_009", "residual": null, "passes_tried": null} {"ts": "2026-07-31 08:07:37", "addr": "0x80191C50", "name": "func_80191C50", "reach": null, "klass": "JTBL-CARVE-BREAKS-BYTES", "nins": 710, "status": "blocked", "closeness": null, "where_stuck": "S28: SS81 step 2. isolate CLEAN; jtbl_carve reported success (48-piece carve set, 22 tail pieces) but post-carve build NOT byte-identical. Same stage as the group-B func_8017BEBC failure -> ONE tooling problem. Log .run/s28_beh_ov_SC06_018_carve.log.", "best_draft": ".run/beh-gate/ov_SC06_018/func_80191C50.c", "binary": null, "source": "ov_SC06_018", "residual": null, "passes_tried": null} {"ts": "2026-07-31 08:07:40", "addr": "0x8017BEBC", "name": "func_8017BEBC", "reach": 13, "klass": "JTBL-CARVE-BREAKS-BYTES", "nins": 952, "status": "blocked", "closeness": null, "where_stuck": "S28 group B: 13 open members (103 already banked in an earlier phase). 3 probes 0 banks: default mode + --raw, cross-address (ov_SC02_015 @0x8017c294) AND same-address (ov_SC04_004 @0x8017bebc). ISOLATING DIAGNOSTIC: jtbl_carve ALONE on ov_SC04_004, no body spliced -> build NOT byte-identical => the failure is the CARVE, not the template. Converges with func_80191C50/ov_SC06_018.", "best_draft": null, "binary": null, "source": "ov_SC01_000", "residual": null, "passes_tried": null} +{"ts": "2026-07-31 08:19:34", "addr": "0x8018057C", "name": "func_8018057C", "reach": null, "klass": "UNREPRODUCIBLE-RETEST-NEUTRAL", "nins": 897, "status": "open", "closeness": null, "where_stuck": "S28 CORRECTION (supersedes the JR-ISOLATE-BREAKS-BYTES entry): re-measured by SHA vs config/check from a clean tree, jr_isolate_all --only IS BYTE-NEUTRAL. The earlier verdict came from a grep-based gate in a driver that did not revert on abort. Original failure NOT reproducible. Next: re-run the full isolate->carve->bank chain with the SS125 instrument rules.", "best_draft": ".run/beh-gate/ov_SC01_009/func_8018057C.c", "binary": null, "source": "ov_SC01_009", "residual": null, "passes_tried": null} +{"ts": "2026-07-31 08:19:36", "addr": "0x80191C50", "name": "func_80191C50", "reach": null, "klass": "JTBL-CARVE-BREAKS-BYTES", "nins": 710, "status": "blocked", "closeness": null, "where_stuck": "S28 CONFIRMED by SHA re-test from a clean tree: baseline OK -> jr_isolate_all NEUTRAL -> jtbl_carve DIVERGED (got 1b1667ea want cbbc4f44), restore verified. This is the ONE real instrument failure of the three. Note: carve WITHOUT the isolate refuses loudly (non-contiguous .rodata carves 0xab9f4/0xaba4c) which is the documented SS81/SS8b step-1 instruction, NOT a divergence.", "best_draft": ".run/beh-gate/ov_SC06_018/func_80191C50.c", "binary": null, "source": "ov_SC06_018", "residual": null, "passes_tried": null} +{"ts": "2026-07-31 08:19:39", "addr": "0x8017BEBC", "name": "func_8017BEBC", "reach": 13, "klass": "BODY-TEMPLATE-GATE-FAIL", "nins": 952, "status": "blocked", "closeness": null, "where_stuck": "S28 CORRECTION (supersedes the JTBL-CARVE-BREAKS-BYTES entry): the carve on ov_SC04_004 is BYTE-NEUTRAL (SHA-verified, body-free). So the 4 gate-fails (default + --raw, cross-address ov_SC02_015 + same-address ov_SC04_004, incl. one from a verified-clean tree) are the TEMPLATED BODY, not the carve. 103 members banked in an earlier phase; these 13 are the residue. Next: diff the remapped body against the sibling TU rather than re-probing the carve.", "best_draft": null, "binary": null, "source": "ov_SC01_000", "residual": null, "passes_tried": null} diff --git a/docs/cookbook-index.md b/docs/cookbook-index.md index 6d490b2c9..5f964ae65 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 / 327 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 / 332 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. @@ -57,7 +57,7 @@ - **§66d-5** — `residual_class`'s "structural ⇒ permuter CPU is waste" is WRONG for schedule permutations (measured, Phase 29 SESSION-18) L5484 - **§3-The** — attribution primitive (use this before calling anything a scheduling residual) L6050 -### register allocation & pins (30) +### register allocation & pins (31) - **§10** — Closing the regalloc/scheduling hard tail by hand (LZSS, Phase 7 session F — the full close) L835 - **Residual** — A — commutative `|`/`&`/`+` result lands in the wrong source-operand register L856 @@ -89,6 +89,7 @@ - **§83** — The parameterised-repeat law, the spill-area trap, and why a per-case edit cannot move a per-case symptom (Phase 29 SESSION-20, `func_80183814` 5,122 ins, cold-ish start → 36 structural / 99.3%) L6405 - **§83c** — TRAP: a "dead local" in a prior draft may be gcc's OWN spill area L6438 - **§86** — Pinned-exemplar templatability is a PER-FAMILY property, not a per-member rate; and the §42e pin guard is now over-conservative (Phase 29 SESSION-20) L6582 +- **§3-Two** — further notes worth keeping L8241 ### CSE / redundancy / rematerialization (2) @@ -234,7 +235,7 @@ - **§88d** — BANKING ORDER: run the §81 carve chain BEFORE banking, never after L6694 - **§97** — The gate's own tree hygiene: a refused carve, an unchecked recovery, and a snapshot that captured a dirty tree (Phase 29 SESSION-22) L7059 - **§105** — A gate's revert must survive an EXCEPTION, not just a failure (Phase 29 T53, `jtbl_family_bank`) L7424 -- **§125** — Split the CARVE from the BODY before you call a jr family a wall (P30 SESSION-28) L8199 +- **§125** — Split the CARVE from the BODY before calling a jr residue a wall — and measure it by SHA from a CLEAN tree (P30 SESSION-28; **this section's first draft was WRONG and the method caught it**) L8199 ### optimisation level (-O0/-O2) (7) @@ -246,7 +247,7 @@ - **§39** — The ×1→×134 giant-endgame: propagate a matched **-O2** giant via the NATIVE DEFINE-macro path (Phase 24 T7 §G close, 2026-07-08) L2530 - **§116** — Optimization level is a property of the FILE, not the function: read a family 0/N against the member's stub HOME (Phase 29 T79) L7870 -### family propagation & sweeps (66) +### family propagation & sweeps (65) - **§8d** — Templating a body INTO a TU must not CHANGE its declaration environment — demote the carried data externs (Phase 26 session 8, byte-proven on `func_8015AE2C` ×133) L483 - **§11** — Cross-binary dedup & code-sharing (Phase 11 — "one match unlocks many") L908 @@ -313,7 +314,6 @@ - **§123** — PROPAGATE A FAMILY WITH THE TOOL ITS TIER NEEDS: `dedup_propagate` is h_exact-only; its refusals are statements about the TOOL (P30 wave 1, 2026-07-30) L8109 - **§124** — A "not matched" verdict can mean the definition is there under a DIFFERENT C NAME: the asm-label alias blind spot (P30 SESSION-28, `func_8016191C` ×137) L8146 - **§124a** — a family sweep's `0 matched-exemplar families` may be a FILTER, not a wall L8191 -- **§125** — Split the CARVE from the BODY before you call a jr family a wall (P30 SESSION-28) L8199 ### integration / TU plumbing (32) @@ -438,7 +438,7 @@ - **§122** — GATE RAW BEFORE TRANSFORMING; the undo belongs to the WRITER, as a per-edit journal (P30 T0a, 2026-07-30) L8077 - **§123** — PROPAGATE A FAMILY WITH THE TOOL ITS TIER NEEDS: `dedup_propagate` is h_exact-only; its refusals are statements about the TOOL (P30 wave 1, 2026-07-30) L8109 -### process, measurement & doctrine (45) +### process, measurement & doctrine (47) - **§8e** — The jtbl ALIGNMENT LAW + the pad-spec filter — multi-table .rodata spans (Phase 29, byte-proven; `.run/probe_jtbl/verdict.md`) L530 - **§3-The** — mechanism: game-code dedup is SOURCE-LEVEL, not an object swap (R-D1, the key lesson) L926 @@ -485,8 +485,10 @@ - **§90d** — Do not measure a live wave's drafts (§87 in real time) L6803 - **§98** — `conform_decls` had three defects, and only the third needed R22 to find (Phase 29 SESSION-22, `func_8014CF04`) L7106 - **§106** — Persist the MEASUREMENT, derive the POLICY: a stored route let a stale file out-vote the live table (Phase 29 T54, `residual_class._ROUTE`) L7463 +- **§125** — Split the CARVE from the BODY before calling a jr residue a wall — and measure it by SHA from a CLEAN tree (P30 SESSION-28; **this section's first draft was WRONG and the method caught it**) L8199 +- **§3-The** — meta-lesson L8250 -### (unbucketed — title matched no symptom vocabulary) (83) +### (unbucketed — title matched no symptom vocabulary) (86) - **§3-How** — to use this L30 - **§1** — Idiom catalog (asm pattern → C that produces it) L39 @@ -571,6 +573,9 @@ - **§118** — Ordinal (positional) immediate resolution: compare C tokens to the DIFFERING asm uses (Phase 29 T87) L7956 - **§119** — Two levers on the SAME axis, opposite directions: test the off-diagonal (Phase 29 T89) L7990 - **§3-The** — wiring trap that cost two attempts L8036 +- **§3-The** — method (keep this) L8206 +- **§3-The** — instrument rules that make its answer trustworthy (this is where I failed) L8216 +- **§3-The** — corrected results (each SHA-verified, from a clean tree, restore re-verified) L8231 ## All sections, in order @@ -901,4 +906,9 @@ - **§123** — PROPAGATE A FAMILY WITH THE TOOL ITS TIER NEEDS: `dedup_propagate` is h_exact-only; its refusals are statements about the TOOL (P30 wave 1, 2026-07-30) L8109 - **§124** — A "not matched" verdict can mean the definition is there under a DIFFERENT C NAME: the asm-label alias blind spot (P30 SESSION-28, `func_8016191C` ×137) L8146 - **§124a** — a family sweep's `0 matched-exemplar families` may be a FILTER, not a wall L8191 -- **§125** — Split the CARVE from the BODY before you call a jr family a wall (P30 SESSION-28) L8199 +- **§125** — Split the CARVE from the BODY before calling a jr residue a wall — and measure it by SHA from a CLEAN tree (P30 SESSION-28; **this section's first draft was WRONG and the method caught it**) L8199 +- **§3-The** — method (keep this) L8206 +- **§3-The** — instrument rules that make its answer trustworthy (this is where I failed) L8216 +- **§3-The** — corrected results (each SHA-verified, from a clean tree, restore re-verified) L8231 +- **§3-Two** — further notes worth keeping L8241 +- **§3-The** — meta-lesson L8250 diff --git a/docs/matching-cookbook.md b/docs/matching-cookbook.md index fd14c4692..06d1b828f 100644 --- a/docs/matching-cookbook.md +++ b/docs/matching-cookbook.md @@ -8196,41 +8196,60 @@ defect waiting to be measured. shape as §53 (the missing carve) and §116 (the wrong opt level): a 0 from the wrong invocation is not evidence. Check the band the family map assigned before you spend a probe on the residual. -## §125 — Split the CARVE from the BODY before you call a jr family a wall (P30 SESSION-28) +## §125 — Split the CARVE from the BODY before calling a jr residue a wall — and measure it by SHA from a CLEAN tree (P30 SESSION-28; **this section's first draft was WRONG and the method caught it**) -Three targets refused the whole-binary gate this session in the jr/jtbl path. Two of them looked like -separate walls and were the **same tooling failure**; the third is a different stage entirely. The -diagnostic that separated them is one build long, and it should run before any jr residue is ledgered. - -**The diagnostic.** Run `jtbl_carve` on the sibling **with no body spliced at all**, then -`make extract && make build`: +Three jr targets refused the whole-binary gate. I ledgered all three as tooling walls on the strength +of a body-free "carve-only" probe. **Re-measured properly, two of the three verdicts were false and the +third had a different cause than I recorded.** The method below is sound; my instrument was not. Both +halves are the lesson. +### The method (keep this) +Run the carve on a sibling with **no body spliced at all**, then rebuild: ```bash -make extract BINARY=$OV && make build BINARY=$OV # baseline must be BYTE-IDENTICAL -tools/jtbl_carve.py $OV --func $FN # carve ONLY — no draft, no remap +tools/jtbl_carve.py $OV --func $FN # carve ONLY — no draft, no remap make extract BINARY=$OV && make build BINARY=$OV -# byte-identical -> the carve is neutral; the failure is the TEMPLATED BODY -# NOT identical -> the failure is the CARVE; the body was never even tested +# byte-identical -> carve is neutral; the failure is the TEMPLATED BODY +# diverged -> the failure is the CARVE; the body was never fairly tested ``` +It separates two failures that present identically at the gate, and it costs one build. -**Measured (P30 S28).** `func_8017BEBC` group B (13 open members, 103 banked in an earlier phase) had -gate-failed **3 probes in a row** — default mode *and* `--raw`, a cross-address member *and* a -same-address one. Every one of those probes was spending a build on a body that never got a fair -test: carve-only on `ov_SC04_004` broke the bytes with **nothing spliced**. The same stage had already -refused behemoth `func_80191C50` on `ov_SC06_018` (isolate clean, post-carve NOT identical). One -tooling problem, two targets that looked unrelated. +### The instrument rules that make its answer trustworthy (this is where I failed) +1. **Compare the built SHA against `config/check..sha`.** Do NOT grep the build log for `[ OK ]`. + A log-grep cannot distinguish "wrong bytes" from "the build did not get that far", and it silently + inherits whatever stale state the tree is in. +2. **Re-extract after EVERY config change AND after every revert.** `git checkout -- config/` alone + leaves `build/` holding objects from the *carved* config — the next build then links a mixture and + reports a divergence that is purely your own. (Phase-20's R22 corollary; §42b's stale-object trap. + I reproduced it exactly: a reverted config with no re-extract turned a byte-identical overlay into + `[FAIL] got 8f28aa77 / want 38a3d919`.) +3. **A driver that aborts a target MUST revert that target before the next one.** v1 of my chain + `continue`d without reverting; `config/overlays.mk` is SHARED, so target 1's half-applied isolate + was still in the tree while target 3 was measured. Every verdict after the first abort is suspect. +4. **Verify the baseline against the canonical SHA too**, not just "it built". "Identical to the + previous build" is worthless if the previous build was already wrong. -By contrast `func_8018057C` on `ov_SC01_009` failed at **step 1** (`jr_isolate_all` reported success — -2 jr in 1 `-O2` object → 2 region `.c` — but the post-isolate build was not identical). Different -stage, different bug, and grouping it with the other two would have hidden that. +### The corrected results (each SHA-verified, from a clean tree, restore re-verified) +| target | `jr_isolate_all` | `jtbl_carve` | true verdict | +|---|---|---|---| +| `func_8018057C` / ov_SC01_009 (897 ins) | **NEUTRAL** | not reached | my "isolate breaks bytes" was **FALSE**; the original failure is not reproducible | +| `func_80191C50` / ov_SC06_018 (710 ins) | NEUTRAL | **DIVERGED** | **REAL** — the carve genuinely breaks bytes here, *after* a neutral isolate | +| `func_8017BEBC` / ov_SC04_004 (group B, 13 members) | n/a | **NEUTRAL** | carve is fine ⇒ the failure is the **BODY/template**, the OPPOSITE of my first claim | -**Why this matters more than the three functions.** A jr residue is the single easiest place to -manufacture a false wall: `match_one` masks the relocations (§81), so the candidate gate says MATCH, -the real gate says DIFF, and the natural reading is "the compiler beat us." §53 is the standing -warning that a 0% from the wrong tool steered two phases of strategy. **The carve-vs-body split makes -the ambiguity cheap to resolve** — and note that BOTH tools *reported success* on every failing -target. A tool's own exit code is not the oracle; the whole-binary gate is (G3/P9). +So the tidy story I wrote first — *"two apparent walls are one tooling problem"* — was wrong. They are +**two different problems**, and the third target has no demonstrated problem at all. -**Ledger the STAGE, not the function.** `JTBL-CARVE-BREAKS-BYTES` and `JR-ISOLATE-BREAKS-BYTES` are -actionable instrument-repair tickets; "func_X is hard" is not. If a later fix lands on the carve, the -ledger already names every target it should re-open. +### Two further notes worth keeping +- `jtbl_carve` on ov_SC06_018 **refuses loudly** when run without the isolate: *"subseg would host + NON-CONTIGUOUS .rodata carves (0xab9f4 and 0xaba4c) — a single object can't leave a gap for the + unmatched jtbl between them."* That refusal is the documented §81/§8b instruction to run step 1 + first — it is the tool working, not failing. Do not confuse a loud refusal with a byte divergence. +- **Ledger the STAGE, not the function** (`JTBL-CARVE-BREAKS-BYTES`), so one instrument fix reopens + every target it covers — but only after the stage is verified by rule 1–4 above. A ledger full of + misattributed classes is worse than no ledger: it schedules the wrong repair. + +### The meta-lesson +§53 warns that a 0% from the wrong tool manufactured a doctrine that steered two phases. This is the +same failure one level up: **a verdict from the wrong *measurement* manufactures a wall just as +efficiently.** R35 says fix the instrument before trusting its measurement — and *my own diagnostic +script is an instrument*, subject to the same rule as the tools it audits. The saving grace is that +the method in this section is what refuted the section's own first conclusion, one build at a time. diff --git a/phase-ends/CURRENT_PHASE.md b/phase-ends/CURRENT_PHASE.md index deebb7ccc..e4f398bd7 100644 --- a/phase-ends/CURRENT_PHASE.md +++ b/phase-ends/CURRENT_PHASE.md @@ -100,25 +100,37 @@ dedup 1904/0 · 0 NON_MATCHING linked. Phase opened at 92.00 / 87.5 / 78.0. `func_80181CDC` (769 ins) banked via the §81 chain, R22 140/140. - **Resume item 1 RE-SCOPED (not banked)** — see below; it is T2 work, and now T2's best ×1 probe. -## 🔧 THE ONE INSTRUMENT TICKET THIS SESSION OPENED (the highest-value carry) -**`jtbl_carve` breaks bytes on a subset of overlays** — proven by a body-free diagnostic (§125): -carve ALONE on `ov_SC04_004`, nothing spliced → build NOT byte-identical. That single finding -explains **two** targets that looked like unrelated walls: -- group B `func_8017BEBC` — 13 open members (103 banked earlier), **3 probes / 0 banks** (default - AND `--raw`; cross-address `ov_SC02_015` AND same-address `ov_SC04_004`). Every probe was - spending a build on a body that never got a fair test. -- behemoth `func_80191C50` / `ov_SC06_018` — isolate clean, **post-carve** not identical. -A THIRD target fails at a *different* stage and must not be grouped with them: -- behemoth `func_8018057C` / `ov_SC01_009` — **`jr_isolate_all`** (step 1) reported success but the - post-isolate build was not identical. -**Both tools reported success on every failing target; only the whole-binary gate refused.** -Ledgered as `JTBL-CARVE-BREAKS-BYTES` / `JR-ISOLATE-BREAKS-BYTES` (the STAGE, not the function), so a -carve fix auto-reopens every target it should. **None is diagnosed ⇒ none is called a compiler wall.** +## ⚠️ THE JR RESIDUE — RE-MEASURED AND LARGELY RETRACTED (Max pass; read this, not the first version) +I first ledgered all three jr refusals as tooling walls off a body-free carve probe. **Re-measured by +SHA vs `config/check..sha` from a clean tree, two of the three verdicts were FALSE.** Verified: + +| target | `jr_isolate_all` | `jtbl_carve` | true verdict | +|---|---|---|---| +| `func_8018057C` / ov_SC01_009 (897) | **NEUTRAL** | not reached | "isolate breaks bytes" was **FALSE**; original failure NOT reproducible | +| `func_80191C50` / ov_SC06_018 (710) | NEUTRAL | **DIVERGED** (1b1667ea vs cbbc4f44) | **REAL** — the one true instrument failure | +| `func_8017BEBC` / ov_SC04_004 (group B ×13) | n/a | **NEUTRAL** | carve fine ⇒ failure is the **BODY**, the OPPOSITE of my first claim | + +**Root cause of my false verdicts (mine, not the tools'):** a grep-of-the-build-log gate inside a +driver that did not revert on abort. `config/overlays.mk` is SHARED, so target 1's half-applied +isolate was still in the tree when target 3 was measured. Also reproduced the §42b stale-object trap +directly: `git checkout -- config/` WITHOUT a re-extract turned a byte-identical overlay into +`[FAIL] got 8f28aa77 / want 38a3d919`. **The tidy "two walls are one tooling problem" story was wrong +— they are two different problems and the third has no demonstrated problem at all.** +§125 rewritten with the instrument rules (SHA not grep · re-extract after every change AND every +revert · revert-on-abort · verify the baseline against canonical too). Ledger classes corrected to +`UNREPRODUCIBLE-RETEST-NEUTRAL` / `JTBL-CARVE-BREAKS-BYTES` / `BODY-TEMPLATE-GATE-FAIL`. ## ▶ RESUME HERE (nothing blocked except where noted) -1. **[INSTRUMENT, highest ROI] Diagnose `jtbl_carve`'s byte-break** (§125 + the two ledger classes). - It gates group B's 13 members AND a 710-ins behemoth today, and every future jr family routes - through it. R35 says fix the instrument before spending more probes against it. +1. **[REAL, and now correctly scoped] `jtbl_carve` diverges on ov_SC06_018 after a neutral isolate** + — the ONE confirmed instrument failure (blocks the 710-ins `func_80191C50`). Compare against + `ov_SC05_010`, whose full chain succeeded this session; §8e's interior-pad law + `JTBL_PADS` and + the `--order` interleave are the suspects. Note a carve run WITHOUT the isolate refuses loudly + (non-contiguous `.rodata` 0xab9f4/0xaba4c) — that is the documented §81/§8b step-1 instruction, + not a divergence. +1b. **group B `func_8017BEBC` ×13 is a BODY problem** — diff the remapped body against the sibling + TU; stop re-probing the carve. 4 gate-fails incl. one from a verified-clean tree. +1c. **`func_8018057C` / ov_SC01_009** — just re-run the full isolate→carve→bank chain under the §125 + instrument rules; its blocker was never demonstrated. 2. **T2 `-O0` carve-within-a-carve.** Open with the **×1 probe on the 4th region** (below) — smaller blast radius than the planned `ov_SC07_007` and it is the Arm-A `%lo +0x20` shift oracle. 3. **Next wave**: 3,873 fresh cached cores across 119 binaries (`.run/p30w4_pool.json`), dealt ACROSS