From 1b9ffe1fbbe9100c6fa3a517fb64f6ba3bbca17a Mon Sep 17 00:00:00 2001 From: Drew T <50529377+Druthulu@users.noreply.github.com> Date: Fri, 24 Jul 2026 14:52:28 -0600 Subject: [PATCH] =?UTF-8?q?docs(phase-29):=20T16.9=20=E2=80=94=20the=20loc?= =?UTF-8?q?al=5Ftype=20class=20does=20NOT=20recover=20either=20(0/4,=20rev?= =?UTF-8?q?erted);=20=C2=A765f/=C2=A765g=20distilled?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 0 of 4 banked; reverted; make check BYTE-IDENTICAL; nothing landed. - Ordering bug found+fixed: uniquifying the draft's type also renames it inside the draft's own `extern D_x;` decls, trading `redefinition of struct T` for `conflicting types for D_x`. With uniquify moved BEFORE the reconcile one compiles -- and then DIFFs 48/53, because the data reconcile's cast-at-use changes real codegen when the body depends on its own struct layout. - func_8014C4AC: rtu MATCH but the gate returned a REAL final SHA != locked, i.e. the de-macroize edit itself shifted a macro's OWN already-matched function. The §63 failure mode relocated somewhere the per-binary gate catches it for free. MEASURED BOUNDARY: de-macroize is byte-neutral 14 of 15. - Rule recorded: read the FINAL SHA, not the verified count -- `None` = no image (compile/link break), a real hash != locked = the TU edit moved bytes. Different faults, different fixes. - Two consecutive honest negatives (T8, T9): the EXISTING transforms stop at 14/36 (39%). §65f/§65g so the next session does not re-buy this. --- docs/matching-cookbook.md | 41 +++++++++++++++++++++++++++++++++++++ phase-ends/CURRENT_PHASE.md | 23 +++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/docs/matching-cookbook.md b/docs/matching-cookbook.md index d5c130f6b..db3db4cda 100644 --- a/docs/matching-cookbook.md +++ b/docs/matching-cookbook.md @@ -5093,3 +5093,44 @@ this bought immediately: Also: `cdecl.tu_scope` runs REAL cpp (`tu_statements`, the §8c law), so it already expands instantiated macros and is authoritative about whether a conflict EXISTS. A separate macro scan is still needed, but only for **attribution** — TU text vs shared-header macro body are the same tier and different edits. + +### §65f — The de-macroize lever's BOUNDARY, measured: byte-neutral 14 times of 15, and the 15th is why the gate exists + +De-macroizing corrects a declaration that an **already-matched** function (the macro's own body) is +compiled against. Usually that is byte-neutral — but not always, and the failure is not a compile error: + +| outcome | n | signature in the gate | +|---|---|---| +| banked BYTE-IDENTICAL | 14 | `verified N / failed 0`, final SHA == locked | +| **edit shifted the macro's own matched function** | **1** | `verified 0 / failed 1`, **final SHA is a REAL hash ≠ locked** | + +`func_8014C4AC` was `rtu_match` MATCH and still failed, because the *baseline* (draft reverted, the +de-macroize edits still in place) no longer built byte-identical. **Read the final SHA, not just the +verified count:** `final SHA None` = the build produced no image (a compile/link break, e.g. §65g); +`final SHA ` ≠ locked = the TU edit itself moved bytes. Those are different faults with different +fixes, and the count alone does not distinguish them. + +So the lever's precondition is not "the draft is byte-correct" — it is **"the draft is byte-correct AND +correcting the decl does not perturb the macro's own function."** The second half is unknowable in +advance and costs one build to test. That is exactly the §63 failure mode, relocated from the fleet +(where it broke 139/140 invisibly) into a place the per-binary gate can see and reject for free. + +### §65g — Where the cheap levers STOP: the local-type and in-TU-self-decl classes did not yield + +Measured, both reverted with nothing landed: +* **`local_type` (4 fns) — 0 banked.** `canon_sig_reconcile._uniquify_draft_types` renames the draft's + colliding type (byte-neutral: a type name emits no code), but that renames the type in the draft's + own `extern D_x;` declarations too, so it **trades a `redefinition of struct T` for a + `conflicting types for D_x`**. Re-ordering (uniquify BEFORE `cast_call_sites`/`reconcile_tu` instead + of after) fixes the ordering bug and lets one compile — which then **DIFFs 48/53**, because the data + reconcile's cast-at-use changes real codegen when the body's semantics depend on its own struct + layout. A struct-TYPED data extern is the case `reconcile_tu` cannot cast. +* **`self_decl_tu` (3 fns) — 0 banked.** `normalize_self_decls` skips a literal `()` unconditionally + (blind to a RETURN-type conflict, so `func_801376E8` normalizes 0), and its narrow-param rewrite on + the other two **broke the build outright** (`final SHA None`). §57a already classes it SURGICAL-ONLY — + it edits the TU file, so a bad edit poisons the whole group and cannot be bisected per-member. + +**⇒ The recovery pass's measured yield is 14 of 36 (39%), and that is where the EXISTING transforms +stop.** The remaining ~8 blocked functions are not a matter of running one more tool; each needs a +transform that does not exist yet. Do not re-run these two classes expecting a different number — the +negative is byte-recorded here precisely so the next session does not re-buy it. diff --git a/phase-ends/CURRENT_PHASE.md b/phase-ends/CURRENT_PHASE.md index da93530b6..912f7b419 100644 --- a/phase-ends/CURRENT_PHASE.md +++ b/phase-ends/CURRENT_PHASE.md @@ -2322,3 +2322,26 @@ conditional) · main-EXE/B9 + GLM/B6 + resident's 14 walls (P30) · behemoths B7 > **⚠️ STANDING HAZARD:** `dedup_propagate --auto-from` would RE-MACROIZE the 14 de-macroized sites and > undo them. `--check-only` first; targeted `--addr` only (§55b bans `--auto-from` anyway). > **DO NOT close P29 on ROI** — burn-down floor still undetermined. + +- **⚠️ 2026-07-24 (SESSION-16, xHigh) — Task 16 / T9: the `local_type` class does NOT recover either. + 0 of 4 banked. Reverted; nothing landed; `make check` BYTE-IDENTICAL; tree clean.** + Targets `func_8014C4AC` (Blk8) · `func_80174CB0` (MATRIX/SVECTOR) · `func_80176144` (S_AF634) · + `func_80173A60` (struct-TAG `S80126B38`). + **The ordering bug I introduced and then fixed (worth the record):** uniquifying the draft's type + renames it inside the draft's own `extern D_x;` decls too, so it **trades a `redefinition of + struct T` for a `conflicting types for D_x`** — i.e. running it AFTER `reconcile_tu` re-breaks what + that pass had conformed. Re-ordered (uniquify FIRST), one compiled — and then **DIFFed 48/53**, + because the data reconcile's cast-at-use genuinely changes codegen when the body depends on its own + struct layout. A struct-TYPED data extern is the case `reconcile_tu` cannot cast. + **`func_8014C4AC` is the instructive one:** `rtu_match` MATCH, then the whole-binary gate returned + **`final SHA 6a37625c…` — a REAL hash, not `None`** — meaning the *baseline* (draft reverted, + de-macroize edits still applied) no longer built byte-identical. The de-macroize edit itself shifted + the codegen of one of the four macros' OWN already-matched functions. **That is the §63 failure mode, + relocated from the fleet (where it broke 139/140 invisibly) into a place the per-binary gate catches + for free.** Measured boundary: **de-macroize is byte-neutral 14 times of 15.** + **Read the FINAL SHA, not the verified count:** `None` = no image (compile/link break, T8's shape); + a real hash ≠ locked = the TU edit moved bytes (T9's shape). Different faults, different fixes. + **⇒ Two consecutive honest negatives (T8, T9). The EXISTING transforms stop at 14 of 36 (39%).** + The remaining ~8 are not "run one more tool" — each needs a transform that does not exist yet. + Distilled to cookbook **§65f** (the lever's measured boundary + the SHA-reading rule) and **§65g** + (where the cheap levers stop, so the next session does not re-buy this negative).