mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-10-03 08:07:25 -04:00
fix(phase-30): RETRACT 2 of 3 jr wall verdicts — SS125 rewritten; my measurement was the defect
Max-effort re-measurement of the three jr refusals I ledgered earlier this session.
Two of the three verdicts were FALSE. Every number below is SHA vs config/check.<ov>.sha
from a clean tree, with the restore re-verified.
func_8018057C / ov_SC01_009 : jr_isolate_all is BYTE-NEUTRAL
-> "JR-ISOLATE-BREAKS-BYTES" RETRACTED; original failure not reproducible.
func_80191C50 / ov_SC06_018 : isolate NEUTRAL -> carve DIVERGED
(got 1b1667ea, want cbbc4f44) -> the ONE real instrument failure. CONFIRMED.
func_8017BEBC / ov_SC04_004 : carve is BYTE-NEUTRAL (body-free)
-> failure is the TEMPLATED BODY, the OPPOSITE of what SS125 first claimed.
Re-probed once more from a verified-clean tree: still gate-fail. Reclassified
BODY-TEMPLATE-GATE-FAIL.
So the tidy "two apparent walls are ONE tooling problem" conclusion was wrong: they
are two different problems, and the third target has no demonstrated problem at all.
ROOT CAUSE, and it is 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 while target 3 was measured. Separately reproduced the
SS42b stale-object trap head-on: `git checkout -- config/` WITHOUT a re-extract turned a
byte-identical overlay into [FAIL] got 8f28aa77 / want 38a3d919 (Phase-20's R22
corollary, live).
SS125 rewritten. The METHOD (split the carve from the body, one build) is kept and is
what refuted this section's own first conclusion; what is added is the instrument rules
that make its answer trustworthy: compare the SHA against config/check, never grep the
log; re-extract after every config change AND every revert; a driver that aborts a
target must revert it before the next; verify the BASELINE against canonical too.
Meta-lesson recorded: SS53 says a 0% from the wrong TOOL manufactures a doctrine — this
is the same failure one level up, a verdict from the wrong MEASUREMENT, and my own
diagnostic script is an instrument subject to R35 like any other.
Ledger corrected in place (3 entries, superseding the earlier misattributions), so the
scheduled repair is the right one. No source/config change; no bank affected; the fleet
is untouched at 140/140 (last full R22 this session, HEAD commit:1263).
This commit is contained in:
+18
-8
@@ -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) <sub>L5484</sub>
|
||||
- **§3-The** — attribution primitive (use this before calling anything a scheduling residual) <sub>L6050</sub>
|
||||
|
||||
### 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) <sub>L835</sub>
|
||||
- **Residual** — A — commutative `|`/`&`/`+` result lands in the wrong source-operand register <sub>L856</sub>
|
||||
@@ -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%) <sub>L6405</sub>
|
||||
- **§83c** — TRAP: a "dead local" in a prior draft may be gcc's OWN spill area <sub>L6438</sub>
|
||||
- **§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) <sub>L6582</sub>
|
||||
- **§3-Two** — further notes worth keeping <sub>L8241</sub>
|
||||
|
||||
### CSE / redundancy / rematerialization (2)
|
||||
|
||||
@@ -234,7 +235,7 @@
|
||||
- **§88d** — BANKING ORDER: run the §81 carve chain BEFORE banking, never after <sub>L6694</sub>
|
||||
- **§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) <sub>L7059</sub>
|
||||
- **§105** — A gate's revert must survive an EXCEPTION, not just a failure (Phase 29 T53, `jtbl_family_bank`) <sub>L7424</sub>
|
||||
- **§125** — Split the CARVE from the BODY before you call a jr family a wall (P30 SESSION-28) <sub>L8199</sub>
|
||||
- **§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**) <sub>L8199</sub>
|
||||
|
||||
### 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) <sub>L2530</sub>
|
||||
- **§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) <sub>L7870</sub>
|
||||
|
||||
### 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) <sub>L483</sub>
|
||||
- **§11** — Cross-binary dedup & code-sharing (Phase 11 — "one match unlocks many") <sub>L908</sub>
|
||||
@@ -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) <sub>L8109</sub>
|
||||
- **§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) <sub>L8146</sub>
|
||||
- **§124a** — a family sweep's `0 matched-exemplar families` may be a FILTER, not a wall <sub>L8191</sub>
|
||||
- **§125** — Split the CARVE from the BODY before you call a jr family a wall (P30 SESSION-28) <sub>L8199</sub>
|
||||
|
||||
### 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) <sub>L8077</sub>
|
||||
- **§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) <sub>L8109</sub>
|
||||
|
||||
### 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`) <sub>L530</sub>
|
||||
- **§3-The** — mechanism: game-code dedup is SOURCE-LEVEL, not an object swap (R-D1, the key lesson) <sub>L926</sub>
|
||||
@@ -485,8 +485,10 @@
|
||||
- **§90d** — Do not measure a live wave's drafts (§87 in real time) <sub>L6803</sub>
|
||||
- **§98** — `conform_decls` had three defects, and only the third needed R22 to find (Phase 29 SESSION-22, `func_8014CF04`) <sub>L7106</sub>
|
||||
- **§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`) <sub>L7463</sub>
|
||||
- **§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**) <sub>L8199</sub>
|
||||
- **§3-The** — meta-lesson <sub>L8250</sub>
|
||||
|
||||
### (unbucketed — title matched no symptom vocabulary) (83)
|
||||
### (unbucketed — title matched no symptom vocabulary) (86)
|
||||
|
||||
- **§3-How** — to use this <sub>L30</sub>
|
||||
- **§1** — Idiom catalog (asm pattern → C that produces it) <sub>L39</sub>
|
||||
@@ -571,6 +573,9 @@
|
||||
- **§118** — Ordinal (positional) immediate resolution: compare C tokens to the DIFFERING asm uses (Phase 29 T87) <sub>L7956</sub>
|
||||
- **§119** — Two levers on the SAME axis, opposite directions: test the off-diagonal (Phase 29 T89) <sub>L7990</sub>
|
||||
- **§3-The** — wiring trap that cost two attempts <sub>L8036</sub>
|
||||
- **§3-The** — method (keep this) <sub>L8206</sub>
|
||||
- **§3-The** — instrument rules that make its answer trustworthy (this is where I failed) <sub>L8216</sub>
|
||||
- **§3-The** — corrected results (each SHA-verified, from a clean tree, restore re-verified) <sub>L8231</sub>
|
||||
|
||||
|
||||
## 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) <sub>L8109</sub>
|
||||
- **§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) <sub>L8146</sub>
|
||||
- **§124a** — a family sweep's `0 matched-exemplar families` may be a FILTER, not a wall <sub>L8191</sub>
|
||||
- **§125** — Split the CARVE from the BODY before you call a jr family a wall (P30 SESSION-28) <sub>L8199</sub>
|
||||
- **§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**) <sub>L8199</sub>
|
||||
- **§3-The** — method (keep this) <sub>L8206</sub>
|
||||
- **§3-The** — instrument rules that make its answer trustworthy (this is where I failed) <sub>L8216</sub>
|
||||
- **§3-The** — corrected results (each SHA-verified, from a clean tree, restore re-verified) <sub>L8231</sub>
|
||||
- **§3-Two** — further notes worth keeping <sub>L8241</sub>
|
||||
- **§3-The** — meta-lesson <sub>L8250</sub>
|
||||
|
||||
+48
-29
@@ -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.<ov>.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.
|
||||
|
||||
Reference in New Issue
Block a user