diff --git a/docs/cookbook-index.md b/docs/cookbook-index.md index 8ca383caa..6e509d0ca 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 / 399 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 / 404 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. @@ -273,7 +273,7 @@ - **§127a** — §71 (sibling-first) is the strongest `-O0` lever, and it beats the index L8370 - **§132** — The `JR-PAIR-IN-ONE-O0-OBJECT` "wall" was TWO instrument defects: a merged-double span the carve could not see, and a truncated object no rule deleted (P30 S29, `func_8013B83C` + `func_8013BD74`) L8563 -### family propagation & sweeps (68) +### family propagation & sweeps (69) - **§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 @@ -343,6 +343,7 @@ - **§134** — MULTI-LINE BLINDNESS: one root cause, four faces, in `family_remap`'s preamble scanner (P30 S6, 190 zero-crack families) L8704 - **§136c** — SIBLING-FIRST is a DERIVATION shortcut, not just a conflict fix (the fastest route in a family wave) L9059 - **§138** — The propagation lanes: a gate refusal is a DECLARATION, and which lever you owe depends on blast radius L9405 +- **§142** — An open stub whose `h_exact` class is MATCHED elsewhere is FREE. Propagate the body; do not gate a draft. (P30 S39, +7,710 ins in two commands) L9768 ### integration / TU plumbing (36) @@ -383,7 +384,7 @@ - **Reconciling** — a gate-refused draft: which way you edit depends on WHERE the TU's decl is L9555 - **§3-The** — same swallow, twice more, in the integration spine L9699 -### build graph, splat & the harness (97) +### build graph, splat & the harness (99) - **§4** — Flag/toolchain gotchas L190 - **Build** — mechanism — per-file opt override (splat resegmentation) L288 @@ -482,8 +483,10 @@ - **Reconciling** — a gate-refused draft: which way you edit depends on WHERE the TU's decl is L9555 - **§139** — A GATE THAT GREPS FOR VERDICTS MUST ASSERT 1:1 ACCOUNTING; and a `--src` filter must not survive a carve (P30 S38, wave 6: 10 of 16 drafts vanished) L9584 - **§140** — A METRIC IS NOT A MEASUREMENT UNTIL IT IS REPRODUCIBLE FROM THE COMMITTED TREE (P30 S1e: a phantom regression that gated the session's best lever) L9650 +- **§142** — An open stub whose `h_exact` class is MATCHED elsewhere is FREE. Propagate the body; do not gate a draft. (P30 S39, +7,710 ins in two commands) L9768 +- **§3-The** — measurement (do this before any wave; it is ~20 lines and needs no builds) L9780 -### process, measurement & doctrine (54) +### process, measurement & doctrine (56) - **§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 @@ -539,8 +542,10 @@ - **§136j** — The failure MIX flips with function size (measured across four bands, one session) L9292 - **Rank** — the lane by measured concentration, not by class count L9471 - **§140** — A METRIC IS NOT A MEASUREMENT UNTIL IT IS REPRODUCIBLE FROM THE COMMITTED TREE (P30 S1e: a phantom regression that gated the session's best lever) L9650 +- **§3-The** — measurement (do this before any wave; it is ~20 lines and needs no builds) L9780 +- **§3-And** — the report-vs-bytes lesson attached to it L9812 -### (unbucketed — title matched no symptom vocabulary) (115) +### (unbucketed — title matched no symptom vocabulary) (117) - **§3-How** — to use this L30 - **§1** — Idiom catalog (asm pattern → C that produces it) L39 @@ -657,6 +662,8 @@ - **§3-The** — three-line proof (do this before diagnosing any metric movement) L9670 - **§3-The** — two instrument defects it exposed L9679 - **§3-Two** — wrong mechanisms I chased first, and why they were wrong L9710 +- **§3-The** — trap that hid it — SAME FUNCTION, TWO ROUTES, ONLY ONE IS FREE L9795 +- **Route** — selection (why `--addr` sometimes says "nothing changed") L9804 ## All sections, in order @@ -1060,3 +1067,8 @@ - **§3-The** — same swallow, twice more, in the integration spine L9699 - **§3-Two** — wrong mechanisms I chased first, and why they were wrong L9710 - **§141** — The §134 class is CLOSED: every line-shape decision now routes through `cdecl._mask` (P30 S39) L9730 +- **§142** — An open stub whose `h_exact` class is MATCHED elsewhere is FREE. Propagate the body; do not gate a draft. (P30 S39, +7,710 ins in two commands) L9768 +- **§3-The** — measurement (do this before any wave; it is ~20 lines and needs no builds) L9780 +- **§3-The** — trap that hid it — SAME FUNCTION, TWO ROUTES, ONLY ONE IS FREE L9795 +- **Route** — selection (why `--addr` sometimes says "nothing changed") L9804 +- **§3-And** — the report-vs-bytes lesson attached to it L9812 diff --git a/docs/matching-cookbook.md b/docs/matching-cookbook.md index 9f6d6b367..9cede84f7 100644 --- a/docs/matching-cookbook.md +++ b/docs/matching-cookbook.md @@ -9762,3 +9762,59 @@ divergence waiting to happen, and it diverges silently. **Symptom line for the index:** **"a scanner miscounts braces/semicolons"** · **"two tools disagree about what a line is"**. + +--- + +## §142 — An open stub whose `h_exact` class is MATCHED elsewhere is FREE. Propagate the body; do not gate a draft. (P30 S39, +7,710 ins in two commands) + +**The cheapest thing on the board is the thing nobody looks for**: a stub that is *byte-identical* to +a function already matched somewhere else in the fleet. + +`h_exact` is the SHA1 of RAW INSTRUCTION BYTES (`tools/sig_image.py`), so two instances sharing one +are identical **including their `jal`/`lui`/`%lo` reloc immediates** — same callees, same data +addresses, same symbols. Therefore the body that compiles byte-identically at one member compiles +byte-identically at the other **with no remap at all**. This is why `dup_report` calls `h_exact` +"guaranteed byte-match" and `h_norm` "candidate-only", and it is the same correctness argument +`dedup_extend` is built on. + +### The measurement (do this before any wave; it is ~20 lines and needs no builds) + +For every sig entry: is its address a stub in *its own* binary? Build `class -> matched-anywhere?` +and `class -> [open instances]`; the free pool is the intersection. + + OPEN stubs whose h_exact class IS matched elsewhere: + 215 function-instances / 8,763 instructions across 33 classes + ...and ONE class was 86% of it: + func_801758FC — 55 ins, SAME address in all 138 overlays, + matched in ov_SC01_000 only, OPEN in the other 137 => 7,535 ins + + tools/dedup_propagate.py --addr 0x801758fc + [ OK ] 138 overlays byte-identical after propagation + fleet instr +7,535 EXACTLY; R22 140/140. + +### The trap that hid it — SAME FUNCTION, TWO ROUTES, ONLY ONE IS FREE + +`func_801758FC` had been sitting in the stored-draft backlog for two overlays, and was **re-gated +"no" earlier the same night**. Both facts are true and not in tension: gating a *stored draft* asks +"does this hand-written C reproduce the bytes?", which is a hard question with an ~8% yield. The +right question for an `h_exact` class is "who already matched this, and can I stamp that body here?", +which is free and gated at 100%. **A function's presence in the near-miss backlog is not evidence +that it is hard — it may only be evidence that it was attacked from the wrong side.** + +### Route selection (why `--addr` sometimes says "nothing changed") + +`dedup_propagate --addr` needs a source overlay holding an **inline definition** to extract. Where +the source is itself a `DEFINE_func_*()` macro instantiation (the ~1,600 shared bodies), it refuses — +that is `dedup_extend`'s job (extend an existing macro-backed group to a binary that lacks it). +Measured tonight: of 33 free classes, `--addr` reached 9 (+7,710 ins); the remaining 25 classes / +66 instances / 1,061 ins are all macro-backed and need the `dedup_extend` route. + +### And the report-vs-bytes lesson attached to it + +The frontier report claimed the whale was "open only in SC07_006/007/010/011". **Three of those four +were already banked.** Its pool numbers were carried with an explicit R14 caveat and the caveat was +right. **Re-measure the pool from the sigs before acting on any published count** — the measurement +above is cheap enough that trusting a stale number is never worth it. + +**Symptom lines for the index:** **"a stub is byte-identical to something already matched"** · +**"dedup_propagate --addr says nothing changed"** · **"a backlog function turns out to be free"**.