mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-28 06:49:47 -04:00
fix(phase-31): wire the S56 findings into the tools, SETUP.md and memory
Audit after "did you update tooling for those findings" found three gaps
beyond the four committed fixes:
- R21: docs/SETUP.md had no record of any of it. Adds the "four flow traps"
table — each trap, its measured cost, and where it is now caught.
- family_sweep --only had no coverage assertion, so the 3-vs-50 mis-scope
could recur silently. It now resolves member addrs to their family, always
prints the coverage line, and refuses when it resolves to zero families.
- pregate_check modelled the banking driver's typedef strip but never checked
the consequence. Adds [DROP-RISK] §203 USE-BEFORE-TYPEDEF. R39 NC: flags
the known-bad splice, 0 false positives on the post-hoist file and all 7
other wave-Z TUs (first draft read a typedef named in its own comment).
Also corrects §203 and the phase log: the text that banked was the RENAMED
variant, because gate_stage's backlog.save_draft() overwrote the original on
the failed attempt. Bytes are correct (R22 213/213); the claim "draft
byte-unchanged" was not.
This commit is contained in:
@@ -842,3 +842,32 @@ min 0.009 / p50 0.08 / p90 0.26 / max 0.53, and hand-checking below the threshol
|
||||
co-occurrence ("delay slot" matching every section that says "delay slot"). Emitting those is worse
|
||||
than emitting nothing: an empty list costs a reader nothing, a plausible-but-wrong section costs a
|
||||
read. At 0.15 it reports 14 confident candidates out of 67 rather than 51 mostly-noise ones.
|
||||
|
||||
### Crack-wave toolchain — the four flow traps, and where each is now caught (P31 S56)
|
||||
|
||||
Every one of these was a capability that was **silently off**: the tool ran, exited zero, and
|
||||
reported a true number about a scope narrower than the caller believed. None was found by the
|
||||
byte-gate, because the byte-gate is a perfect correctness oracle and a null coverage oracle (R34).
|
||||
Each now asserts its own coverage (R32) or cannot be mis-called (R33).
|
||||
|
||||
| trap | what it cost | where it is caught NOW |
|
||||
|---|---|---|
|
||||
| **`wave_snapshot.py` assumed `asm/<bin>/nonmatchings/<bin>/`** — right only for single-TU binaries; every split-TU overlay lives under its own TU stem. Found 9 of 75 wave-Z targets. Its R32 assertion fired correctly, so the snapshot step got hand-rolled instead — **and the S46 validity gate living inside it came off the path for waves T–Z.** | 6 waves ran with no phantom-target check | `wave_snapshot` now honors the card's `sub` (then the old convention, then a single-hit glob). NC: 9/9 legacy targets byte-identical, 66/66 split-TU recovered. |
|
||||
| **The S46 validity gate was only reachable through the snapshot step.** Its own comment says "a gate that is a separate command is a gate someone forgets" — and then a path bug forgot it. | S46 measured ~29 phantom targets × 3 tiers = 87 wasted agents, 9.7M tokens | Wired into **`build_wave_atlas`**, where cards are BORN, with an `--allow-invalid` escape. `validate_targets._key` also accepts the card spelling `fn` (it knew only `name`/`n`, so every card-shaped dict silently read MALFORMED). |
|
||||
| **`family_sweep --hseq --only` is keyed on the FAMILY EXEMPLAR address**, but the natural thing to pass after a wave is the addresses you just banked — which are family *members*. Strictly keyed, that selects almost nothing and reports success. | wave Z: 15 addrs → 2 families → **3 banked**. Re-derived through membership: 21 families / 196 open members → **50 banked**. A 17× miss that looked like work. | `--only` now resolves member addrs to their family, **always prints the coverage line** (`N addrs -> M families, K unresolved`), and REFUSES when it resolves to zero families. |
|
||||
| **`decl_prior._ASM_SYM`'s leading `\b` bound to the whole alternation**, demanding a word boundary before `%` — impossible in a `.s`, where that position follows a space. The `%hi/%lo` arm had **never fired**: the card's promised GLOBAL-TYPE row was 0 of 1,210 across four waves. | four waves of cards missing every data-symbol prior | Fixed (cookbook §204-E). NC over 75 wave-Z targets: `jal` 306 → 306 **zero regressions**, data **0 → 299** symbols recovered. |
|
||||
|
||||
**A fifth, in the banking driver rather than the wave tools:** when two slate-mates share a typedef,
|
||||
`harvest_verify.strip_provided_typedefs` drops the duplicate from both drafts and the one surviving
|
||||
definition sits wherever its owner splices — so if the *other* function is earlier in ADDRESS order,
|
||||
its externs reference a type the file has not defined yet (`parse error before '<symbol>'`, which
|
||||
reads like a codegen residual). `pregate_check` modelled the driver faithfully but never checked the
|
||||
consequence; it now reports `[DROP-RISK] §203 USE-BEFORE-TYPEDEF` with the fix (hoist to the top of
|
||||
the TU — never rename in one draft, which gives one symbol two types and just moves the failure).
|
||||
NC: flags the known-bad pre-hoist splice, 0 false positives on the post-hoist file and on all 7 other
|
||||
wave-Z TUs (the first draft of the check read a typedef named in its own *comment* as a use — it now
|
||||
searches a comment-blanked copy with offsets preserved).
|
||||
|
||||
**The standing lesson for this flow:** after any wave step that reports a count, ask what
|
||||
denominator that count is a fraction of. `3 banked` and `50 banked` were the same tool, same tree,
|
||||
same day — the only difference was whether the scope was asserted.
|
||||
|
||||
+28
-28
@@ -1,6 +1,6 @@
|
||||
# P30 S49 — cousin-unit survey (similarity tier over the open frontier)
|
||||
|
||||
> Generated by `tools/family_cousins.py` at HEAD `commit:2541` from `.run/family_hseq.json` + the binary sigs (R32-checked against an independent stub recount — a stale map fails loud). Compare digests only at the same HEAD.
|
||||
> Generated by `tools/family_cousins.py` at HEAD `commit:2562` from `.run/family_hseq.json` + the binary sigs (R32-checked against an independent stub recount — a stale map fails loud). Compare digests only at the same HEAD.
|
||||
>
|
||||
> **A unit is a CANDIDATE grouping** — same-source cousins split by skeleton drift (insertion/deletion; the li-expansion class). Cousins need a per-member seeded CRACK, never a `family_sweep` remap. The whole-binary byte-gate stays the sole arbiter.
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
|
||||
| category | units | open fns | open ins | lever |
|
||||
|---|--:|--:|--:|---|
|
||||
| A-prop | 442 | 2099 | 94202 | family_sweep (propagation) |
|
||||
| seeded | 360 | 888 | 33691 | seeded crack — edit a >=0.85-similar MATCHED body |
|
||||
| cousin-multi | 1170 | 4015 | 162666 | 1 crack seeds the unit's other members |
|
||||
| cold | 2878 | 2878 | 183157 | full-price crack (the honest unique tail) |
|
||||
| **total** | **4850** | **9880** | **473716** | |
|
||||
| A-prop | 438 | 2053 | 92382 | family_sweep (propagation) |
|
||||
| seeded | 356 | 882 | 33412 | seeded crack — edit a >=0.85-similar MATCHED body |
|
||||
| cousin-multi | 1163 | 3995 | 160575 | 1 crack seeds the unit's other members |
|
||||
| cold | 2823 | 2823 | 178507 | full-price crack (the honest unique tail) |
|
||||
| **total** | **4780** | **9753** | **464876** | |
|
||||
|
||||
## Top units by open instructions (whole-cluster weight)
|
||||
|
||||
@@ -36,25 +36,25 @@
|
||||
| 16 | A-prop | 1035 | 11 | 5 | 1.0 | `ov_SC06_018:0x80187320` | `ov_SC02_011:0x80188250` (94 ins ×4) |
|
||||
| 17 | A-prop | 987 | 3 | 1 | 1.0 | `ov_SC01_000:0x8013c414` | `ov_SC01_077:0x8013c414` (329 ins ×3 jr) |
|
||||
| 18 | A-prop | 979 | 18 | 11 | 1.0 | `ov_SC06_024:0x8017d474` | `ov_SC06_022:0x8017d6e0` (59 ins ×4) |
|
||||
| 19 | A-prop | 964 | 12 | 3 | 1.0 | `md_SC03_073:0x801efc94` | `md_SC03_079:0x801efb94` (87 ins ×4) |
|
||||
| 20 | A-prop | 914 | 8 | 4 | 1.0 | `ov_SC02_017:0x8017f92c` | `ov_SC02_017:0x8017f92c` (115 ins ×4) |
|
||||
| 21 | A-prop | 908 | 19 | 6 | 1.0 | `ov_SC02_041:0x80182ccc` | `ov_SC02_041:0x80182ccc` (45 ins ×9) |
|
||||
| 22 | A-prop | 889 | 7 | 1 | 1.0 | `ov_SC01_000:0x80145cec` | `ov_SC01_077:0x80145cec` (127 ins ×7) |
|
||||
| 23 | A-prop | 872 | 4 | 1 | 1.0 | `ov_MAIN_012:0x8017cf3c` | `ov_MAIN_012:0x8017cf3c` (218 ins ×4 jr) |
|
||||
| 24 | A-prop | 816 | 3 | 1 | 1.0 | `ov_SC01_000:0x8013b83c` | `ov_SC01_077:0x8013b83c` (272 ins ×3 jr) |
|
||||
| 25 | cousin-multi | 810 | 10 | 2 | · | · | `ov_SC01_005:0x8017e108` (84 ins ×5) |
|
||||
| 26 | A-prop | 798 | 3 | 1 | 1.0 | `ov_SC01_000:0x80130d48` | `ov_SC01_077:0x80130d48` (266 ins ×3) |
|
||||
| 27 | cousin-multi | 784 | 4 | 1 | · | · | `ov_SC03_108:0x8017ffd0` (196 ins ×4 jr) |
|
||||
| 28 | cousin-multi | 767 | 15 | 7 | 0.839 | · | `ov_SC03_028:0x8018966c` (63 ins ×4) |
|
||||
| 29 | seeded | 752 | 14 | 10 | 0.921 | `ov_SC02_027:0x8017f6d4` | `ov_SC02_027:0x8017f858` (48 ins ×3) |
|
||||
| 30 | A-prop | 684 | 6 | 5 | 1.0 | `md_SC03_077:0x801ef9c0` | `ov_SC02_000:0x80181e70` (122 ins ×2) |
|
||||
| 31 | cousin-multi | 680 | 8 | 2 | 0.7 | · | `md_SC03_077:0x801efb58` (87 ins ×4 jr) |
|
||||
| 32 | cousin-multi | 668 | 3 | 3 | · | · | `ov_SC02_017:0x80186770` (230 ins ×1) |
|
||||
| 33 | cousin-multi | 658 | 14 | 5 | · | · | `ov_SC04_018:0x80181124` (52 ins ×4) |
|
||||
| 34 | cold | 657 | 1 | 1 | · | · | `md_MAIN_003:0x800d12d0` (657 ins ×1) |
|
||||
| 35 | A-prop | 656 | 29 | 10 | 1.0 | `ov_SC03_001:0x8017f0ec` | `ov_SC03_001:0x8017f0ec` (20 ins ×13) |
|
||||
| 36 | A-prop | 655 | 16 | 6 | 1.0 | `ov_SC02_005:0x8017df78` | `ov_SC02_005:0x8017df78` (39 ins ×10) |
|
||||
| 37 | A-prop | 647 | 16 | 6 | 1.0 | `ov_SC01_074:0x8017dba0` | `ov_SC01_077:0x8017d840` (39 ins ×9) |
|
||||
| 38 | A-prop | 642 | 16 | 5 | 1.0 | `ov_SC01_000:0x8017d024` | `ov_SC01_000:0x8017d024` (38 ins ×8) |
|
||||
| 39 | A-prop | 630 | 42 | 1 | 1.0 | `md_SC03_073:0x801ef5f4` | `ov_SC01_077:0x80130d0c` (15 ins ×42) |
|
||||
| 40 | A-prop | 609 | 3 | 1 | 1.0 | `ov_SC01_004:0x8017e804` | `ov_SC01_004:0x8017e804` (203 ins ×3) |
|
||||
| 19 | A-prop | 914 | 8 | 4 | 1.0 | `ov_SC02_017:0x8017f92c` | `ov_SC02_017:0x8017f92c` (115 ins ×4) |
|
||||
| 20 | A-prop | 908 | 19 | 6 | 1.0 | `ov_SC02_041:0x80182ccc` | `ov_SC02_041:0x80182ccc` (45 ins ×9) |
|
||||
| 21 | A-prop | 889 | 7 | 1 | 1.0 | `ov_SC01_000:0x80145cec` | `ov_SC01_077:0x80145cec` (127 ins ×7) |
|
||||
| 22 | A-prop | 872 | 4 | 1 | 1.0 | `ov_MAIN_012:0x8017cf3c` | `ov_MAIN_012:0x8017cf3c` (218 ins ×4 jr) |
|
||||
| 23 | A-prop | 816 | 3 | 1 | 1.0 | `ov_SC01_000:0x8013b83c` | `ov_SC01_077:0x8013b83c` (272 ins ×3 jr) |
|
||||
| 24 | cousin-multi | 810 | 10 | 2 | · | · | `ov_SC01_005:0x8017e108` (84 ins ×5) |
|
||||
| 25 | A-prop | 798 | 3 | 1 | 1.0 | `ov_SC01_000:0x80130d48` | `ov_SC01_077:0x80130d48` (266 ins ×3) |
|
||||
| 26 | cousin-multi | 784 | 4 | 1 | · | · | `ov_SC03_108:0x8017ffd0` (196 ins ×4 jr) |
|
||||
| 27 | cousin-multi | 767 | 15 | 7 | 0.839 | · | `ov_SC03_028:0x8018966c` (63 ins ×4) |
|
||||
| 28 | seeded | 752 | 14 | 10 | 0.921 | `ov_SC02_027:0x8017f6d4` | `ov_SC02_027:0x8017f858` (48 ins ×3) |
|
||||
| 29 | cousin-multi | 680 | 8 | 2 | 0.7 | · | `md_SC03_077:0x801efb58` (87 ins ×4 jr) |
|
||||
| 30 | cousin-multi | 668 | 3 | 3 | · | · | `ov_SC02_017:0x80186770` (230 ins ×1) |
|
||||
| 31 | cousin-multi | 658 | 14 | 5 | · | · | `ov_SC04_018:0x80181124` (52 ins ×4) |
|
||||
| 32 | cold | 657 | 1 | 1 | · | · | `md_MAIN_003:0x800d12d0` (657 ins ×1) |
|
||||
| 33 | A-prop | 656 | 29 | 10 | 1.0 | `ov_SC03_001:0x8017f0ec` | `ov_SC03_001:0x8017f0ec` (20 ins ×13) |
|
||||
| 34 | A-prop | 656 | 8 | 2 | 1.0 | `md_SC03_073:0x801efc94` | `md_SC03_079:0x801efb94` (87 ins ×4) |
|
||||
| 35 | A-prop | 655 | 16 | 6 | 1.0 | `ov_SC02_005:0x8017df78` | `ov_SC02_005:0x8017df78` (39 ins ×10) |
|
||||
| 36 | A-prop | 647 | 16 | 6 | 1.0 | `ov_SC01_074:0x8017dba0` | `ov_SC01_077:0x8017d840` (39 ins ×9) |
|
||||
| 37 | A-prop | 642 | 16 | 5 | 1.0 | `ov_SC01_000:0x8017d024` | `ov_SC01_000:0x8017d024` (38 ins ×8) |
|
||||
| 38 | A-prop | 630 | 42 | 1 | 1.0 | `md_SC03_073:0x801ef5f4` | `ov_SC01_077:0x80130d0c` (15 ins ×42) |
|
||||
| 39 | A-prop | 609 | 3 | 1 | 1.0 | `ov_SC01_004:0x8017e804` | `ov_SC01_004:0x8017e804` (203 ins ×3) |
|
||||
| 40 | cousin-multi | 602 | 2 | 2 | · | · | `ov_SC01_001:0x8017fee0` (305 ins ×1) |
|
||||
|
||||
+4
-4
@@ -5,13 +5,13 @@
|
||||
|
||||
> Generated by `tools/family_hseq.py` from the 212 binary sigs + per-binary src stubs. Ranked by TEMPLATABLE byte-weight (PURE+IMM members × nins × 4). The byte-gate is the arbiter.
|
||||
>
|
||||
> **Scope (212 binaries): 141 location overlays + 70 md_* modules + the resident · MAIN IS EXCLUDED** · generated at HEAD `commit:2559` · stub set derived from `corpus.stubs` — the same oracle `progress.py` counts, so same-tree overlay totals agree by construction; compare digests only at the same HEAD.
|
||||
> **Scope (212 binaries): 141 location overlays + 70 md_* modules + the resident · MAIN IS EXCLUDED** · generated at HEAD `commit:2562` · stub set derived from `corpus.stubs` — the same oracle `progress.py` counts, so same-tree overlay totals agree by construction; compare digests only at the same HEAD.
|
||||
|
||||
**Fleet (overlays):** 97.3% fn / 96.5% instr / 92.8% distinct-code matched. Unmatched: 9,806 instances / 467,271 ins (8,442 distinct classes).
|
||||
**Fleet (overlays):** 97.3% fn / 96.5% instr / 92.8% distinct-code matched. Unmatched: 9,753 instances / 464,876 ins (8,404 distinct classes).
|
||||
|
||||
**Tail cross-check (Phase-25 close):** 6,452 tail fns / 307,802 ins → 367 h_seq families ≥2, **42 substantial (nins≥80) / 23,013 ins**.
|
||||
**Tail cross-check (Phase-25 close):** 6,436 tail fns / 307,262 ins → 365 h_seq families ≥2, **41 substantial (nins≥80) / 22,755 ins**.
|
||||
|
||||
**Full frontier (all unmatched by h_seq):** 1817 target families (≥2 members or a matched sibling) + 3958 singletons (Step-D residue). Substantial: **168 families / 65,255 templatable ins**, 70 with a matched sibling (zero-crack). Substantial member classes: 403 PURE · 17 IMM · 6 STRUCT-excluded.
|
||||
**Full frontier (all unmatched by h_seq):** 1806 target families (≥2 members or a matched sibling) + 3958 singletons (Step-D residue). Substantial: **167 families / 64,997 templatable ins**, 69 with a matched sibling (zero-crack). Substantial member classes: 400 PURE · 17 IMM · 6 STRUCT-excluded.
|
||||
|
||||
|
||||
## Top substantial families (by templatable byte-weight)
|
||||
|
||||
+20
-20
@@ -1,40 +1,40 @@
|
||||
# The Frontier Atlas (P31 T5)
|
||||
|
||||
> Generated at HEAD `commit:2541` by `tools/atlas.py` — REGENERATE, never edit. Groups are ADVISORY (the byte-gate is the arbiter). Calibration: warm merge at norm-ratio ≥ 0.7, kNN floor 0.55.
|
||||
> Generated at HEAD `commit:2562` by `tools/atlas.py` — REGENERATE, never edit. Groups are ADVISORY (the byte-gate is the arbiter). Calibration: warm merge at norm-ratio ≥ 0.7, kNN floor 0.55.
|
||||
|
||||
**Scope:** 10632 open instances / 6406 skeletons across 213 binaries (main: 752 — atlas-layer join (family maps stay non-main)).
|
||||
**Tiers:** T1.5 h_seqn merges 2 · warm merges 868 (from 17018 ratio calls) · seed sweep: 4586 skeletons carry a ≥0.55 seed from the 3587-skeleton matched pool.
|
||||
**Scope:** 10505 open instances / 6331 skeletons across 213 binaries (main: 752 — atlas-layer join (family maps stay non-main)).
|
||||
**Tiers:** T1.5 h_seqn merges 2 · warm merges 866 (from 16565 ratio calls) · seed sweep: 4556 skeletons carry a ≥0.55 seed from the 3657-skeleton matched pool.
|
||||
|
||||
## Groups by category
|
||||
|
||||
| cat | groups | instances | ins |
|
||||
|---|--:|--:|--:|
|
||||
| A-prop | 441 | 2131 | 94475 |
|
||||
| cold | 1971 | 1971 | 155174 |
|
||||
| cousin-multi | 1364 | 5163 | 199906 |
|
||||
| A-prop | 437 | 2085 | 92655 |
|
||||
| cold | 1920 | 1920 | 150803 |
|
||||
| cousin-multi | 1355 | 5139 | 197536 |
|
||||
| main-only | 314 | 314 | 27589 |
|
||||
| seeded | 360 | 890 | 33715 |
|
||||
| seeded | 356 | 884 | 33436 |
|
||||
| tiny | 97 | 163 | 827 |
|
||||
|
||||
## Groups by lever (confidence)
|
||||
|
||||
| lever | groups | instances | ins |
|
||||
|---|--:|--:|--:|
|
||||
| head-crack[default] | 933 | 3069 | 109454 |
|
||||
| UNKNOWN[none] | 1585 | 1585 | 101713 |
|
||||
| head-crack[default] | 924 | 3045 | 107088 |
|
||||
| UNKNOWN[none] | 1536 | 1536 | 97537 |
|
||||
| extend-tell[tell] | 582 | 1042 | 78266 |
|
||||
| jtbl-carve[tell] | 191 | 286 | 46068 |
|
||||
| redraft[measured] | 236 | 973 | 37467 |
|
||||
| family-sweep[default] | 230 | 891 | 32253 |
|
||||
| integration[measured] | 47 | 483 | 20618 |
|
||||
| seeded-crack[default] | 272 | 591 | 19205 |
|
||||
| len-vein[measured] | 146 | 659 | 13375 |
|
||||
| plumbing[ledger] | 39 | 188 | 9526 |
|
||||
| redraft[measured] | 234 | 971 | 37272 |
|
||||
| family-sweep[default] | 226 | 866 | 30820 |
|
||||
| integration[measured] | 46 | 481 | 20473 |
|
||||
| seeded-crack[default] | 268 | 585 | 18926 |
|
||||
| len-vein[measured] | 146 | 653 | 13186 |
|
||||
| swaprepeat-tell[tell] | 70 | 119 | 9316 |
|
||||
| plumbing[ledger] | 39 | 173 | 9301 |
|
||||
| o0-lane[tell] | 31 | 69 | 6564 |
|
||||
| cc1[measured] | 12 | 104 | 6382 |
|
||||
| cc1[ledger] | 16 | 70 | 5489 |
|
||||
| needs-autopsy[measured] | 52 | 263 | 5090 |
|
||||
| cc1[ledger] | 17 | 71 | 5643 |
|
||||
| needs-autopsy[measured] | 52 | 264 | 5104 |
|
||||
| frame-172[measured] | 8 | 32 | 4078 |
|
||||
| needs-autopsy[ledger] | 10 | 34 | 4036 |
|
||||
| near-crack[measured] | 10 | 63 | 1829 |
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
| gid | cat | lever | inst | ins | exemplar | seed |
|
||||
|---|---|---|--:|--:|---|---|
|
||||
| 527622c1c114 | cousin-multi | integration[measured] | 257 | 5926 | ov_SC01_084:func_80180CBC (31) | 0.72 |
|
||||
| 152063fd6de6 | cousin-multi | integration[measured] | 256 | 5908 | ov_SC01_084:func_80180CBC (31) | 0.72 |
|
||||
| e8bf2260391b | cousin-multi | frame-172[measured] | 16 | 3936 | ov_SC01_077:func_8017C294 (246) | |
|
||||
| b0e41839e641 | cousin-multi | redraft[measured] | 111 | 2848 | main:func_8001FB8C (31) | 0.72 |
|
||||
| 4a254010e122 | A-prop | needs-autopsy[ledger] | 4 | 2444 | ov_SC03_001:func_801898E4 (611) | 1.00 |
|
||||
@@ -69,7 +69,6 @@
|
||||
| 93cd03e11398 | A-prop | cc1[ledger] | 11 | 1035 | ov_SC06_032:func_801820C4 (113) | 1.00 |
|
||||
| 4109ef56e262 | A-prop | jtbl-carve[tell] | 3 | 987 | ov_MAIN_012:func_8013C414 (329) | 1.00 |
|
||||
| 435e948b661b | A-prop | extend-tell[tell] | 18 | 979 | ov_SC03_100:func_8017EC84 (67) | 0.84 |
|
||||
| 75f80de517ba | A-prop | family-sweep[default] | 12 | 964 | md_SC03_079:func_801EFB94 (87) | 0.94 |
|
||||
| 4f680d0642d8 | A-prop | extend-tell[tell] | 8 | 914 | ov_SC02_011:func_80182B88 (118) | 0.99 |
|
||||
| dd647efa7db9 | cousin-multi | extend-tell[tell] | 8 | 912 | main:func_8001E378 (188) | 0.59 |
|
||||
| 9ec470fd06a4 | A-prop | family-sweep[default] | 19 | 908 | ov_SC02_026:func_80182318 (52) | 0.85 |
|
||||
@@ -85,4 +84,5 @@
|
||||
| 334bc03beb1f | cousin-multi | integration[measured] | 68 | 760 | md_SC07_003:func_801A38A8 (15) | 0.90 |
|
||||
| 89269e496a2d | cousin-multi | extend-tell[tell] | 23 | 760 | ov_SC03_092:func_8017E6A0 (45) | 0.75 |
|
||||
| ab1569f4386c | seeded | redraft[measured] | 14 | 752 | ov_SC03_096:func_8017D130 (66) | 0.83 |
|
||||
| 6f8c3c72cc0f | A-prop | len-vein[measured] | 6 | 684 | ov_SC02_000:func_80181E70 (122) | 0.96 |
|
||||
| b1da4f0f7f14 | cousin-multi | jtbl-carve[tell] | 8 | 680 | md_SC03_077:func_801EFB58 (87) | 0.68 |
|
||||
| bb7d0989abd9 | main-only | UNKNOWN[none] | 1 | 670 | main:func_800226C0 (670) | |
|
||||
|
||||
@@ -21480,7 +21480,16 @@ stripper delete the draft's copy as designed:
|
||||
typedef struct { u8 f0; u8 f1; u8 f2; u8 f3; } Quad4_800CCB14;
|
||||
```
|
||||
|
||||
Banked on the next gate (commit `commit:2558`), draft byte-unchanged from the wave's MATCH.
|
||||
Banked on the next gate (commit `commit:2558`).
|
||||
|
||||
**Correction, recorded because it bit the writer of this section (P31 S56).** The text that banked
|
||||
is the RENAMED variant, not the original draft — `gate_stage` calls `backlog.save_draft()` on
|
||||
failure, so the failed rename attempt OVERWROTE `.run/backlog_drafts/func_800CC310.c`, and copying
|
||||
"the original" back copied the rename. The BYTES are correct (whole-binary gate + R22 213/213), but
|
||||
the TU now carries two names for one 4-byte shape, and a symbol-rewriting transform mangled prose
|
||||
*inside a comment* (`not (*(Quad4_800CCAD0 *)&D_800CCB14)`). Two lessons: **a backlog draft path is
|
||||
not a stable original** — snapshot the text you mean to re-gate; and **a transform that rewrites
|
||||
symbols must skip comments** (H5).
|
||||
|
||||
**The general law.** *A type shared by two functions in one TU belongs at the TOP of that TU, not
|
||||
beside whichever of them happened to bank first.* `pregate_check` already hoists for main's
|
||||
|
||||
@@ -347,6 +347,10 @@ R22 clean-fleet **213/213** after every banked batch · tools-health green · 0
|
||||
`func_800CC310`'s duplicate, and `func_800CC310` splices EARLIER in address order — survivor below
|
||||
its uses. First fix (rename to dodge the stripper) was WRONG and the gate caught it: one symbol,
|
||||
two types. Hoisting the typedef to the top of the TU banked it (`commit:2558`). Cookbook **§203**.
|
||||
**Correction (same session):** the text that banked is the RENAMED variant — `gate_stage`'s
|
||||
`backlog.save_draft()` overwrote the original draft on the failed attempt, so "copying the
|
||||
original back" copied the rename. Bytes are correct (R22 213/213); the TU carries two names for
|
||||
one shape and a transform mangled a COMMENT. A backlog draft path is not a stable original.
|
||||
`func_8018280C` (ov_SC05_001) — the reconciler's IMMOVABLE §183.3 DEF-SIDE-RETURN wall (asm proves
|
||||
`s32`, TU declares `void` at three sites with live callers). The **§200 alias applied to a
|
||||
DEFINITION** — `s32 aF8018280C(s32) __asm__("func_8018280C")` — banked first try (`commit:2559`),
|
||||
@@ -381,6 +385,20 @@ R22 clean-fleet **213/213** after every banked batch · tools-health green · 0
|
||||
bound to the whole alternation, demanding a word boundary before `%` — impossible in a .s — so the
|
||||
`%hi/%lo` arm had NEVER fired (0 of 1,210 over four waves). NC over the 75 wave-Z targets: **jal
|
||||
306 -> 306, zero regressions; data 0 -> 299 symbols recovered.**
|
||||
- **Flow hardening after Drew asked whether the findings were actually wired in (S56).** The audit
|
||||
found three gaps beyond the four fixes already committed: (a) **R21 violation — `docs/SETUP.md`
|
||||
was not updated**; now carries a "Crack-wave toolchain — the four flow traps" table naming each
|
||||
trap, its measured cost and where it is caught. (b) **`family_sweep --only` had no coverage
|
||||
assertion**, so my 3-vs-50 mis-scope could recur silently; it now resolves member addrs to their
|
||||
family, ALWAYS prints `--only: N addr(s) -> M family(ies) (... K unresolved)`, and REFUSES on zero
|
||||
(replaying the exact wave-Z call now prints `15 -> 3, 12 unresolved` instead of quietly sweeping
|
||||
nothing). (c) **`pregate_check` modelled the driver's typedef strip but never checked the
|
||||
consequence**; it now reports `[DROP-RISK] §203 USE-BEFORE-TYPEDEF` — R39 bidirectional NC: flags
|
||||
the known-bad pre-hoist splice, 0 false positives on the post-hoist file and on all 7 other
|
||||
wave-Z TUs (its first draft read a typedef named in its own COMMENT as a use, so it searches a
|
||||
comment-blanked copy with offsets preserved). Memories: `crack-wave-sweep-map-regen` rewritten
|
||||
with the exemplar-vs-member keying, and a new `silently-narrowed-tool-scope` recording all four
|
||||
instances as one defect class.
|
||||
- Outstanding: `func_8018675C` (ov_SC02_005, closeness 6) — its agent ran ~35 variants and attributed
|
||||
the residual to cse.c:5278's unconditional constant-second swap for symbol-valued pointer bases
|
||||
(retires "reorder the addends" as a lever). **Permuter fuel, not a hand lever.**
|
||||
|
||||
+34
-1
@@ -558,7 +558,40 @@ def hseq_sweep(a):
|
||||
if bands:
|
||||
fams = [f for f in fams if f["band"] in bands]
|
||||
if only is not None:
|
||||
fams = [f for f in fams if int(f["exemplar"]["addr"], 16) in only]
|
||||
# ---- R32/R33 (P31 S56): --only IS KEYED ON THE FAMILY'S EXEMPLAR ADDRESS, and the caller
|
||||
# almost never has those. The natural thing to pass after a crack wave is the addresses you
|
||||
# just BANKED -- which are family MEMBERS. Keyed strictly, that silently selects almost
|
||||
# nothing: wave Z passed 15 banked addrs, matched 2 families, swept 4 candidates and banked
|
||||
# 3, reporting success. Re-derived through member lookup it was 21 families / 196 open
|
||||
# members / 50 banked. A 17x difference, invisible, because the tool answered exactly what
|
||||
# was asked. So: resolve member addrs to their family too, and ALWAYS report the coverage.
|
||||
by_ex = {int(f["exemplar"]["addr"], 16): f for f in fams}
|
||||
member_of = {}
|
||||
for f in fams:
|
||||
for m in list(f.get("members", [])) + list(f.get("matched_members", [])):
|
||||
member_of.setdefault(int(m[1], 16), f)
|
||||
picked, via_member, unresolved = {}, 0, []
|
||||
for addr in only:
|
||||
f = by_ex.get(addr)
|
||||
if f is None:
|
||||
f = member_of.get(addr)
|
||||
if f is not None:
|
||||
via_member += 1
|
||||
if f is None:
|
||||
unresolved.append(addr)
|
||||
else:
|
||||
picked[id(f)] = f
|
||||
print(f"[hseq] --only: {len(only)} addr(s) -> {len(picked)} family(ies) "
|
||||
f"({len(only) - via_member - len(unresolved)} matched an exemplar directly, "
|
||||
f"{via_member} resolved via family MEMBERSHIP, {len(unresolved)} unresolved)")
|
||||
if unresolved:
|
||||
print("[hseq] UNRESOLVED (not an exemplar and not a member of any sweepable family): "
|
||||
+ ", ".join(f"0x{x:08x}" for x in sorted(unresolved)[:12]))
|
||||
if not picked:
|
||||
sys.exit("[hseq] REFUSING: --only resolved to ZERO families. Passing addresses that are "
|
||||
"not exemplars and not members yields a silent no-op that reads as a clean 0. "
|
||||
"Check the addrs against .run/family_hseq.json, or drop --only.")
|
||||
fams = list(picked.values())
|
||||
if a.reconcile_raw: # only families with a raw crack to reconcile
|
||||
fams = [f for f in fams if os.path.exists(
|
||||
os.path.join(REPO, a.reconcile_raw, f"func_{int(f['exemplar']['addr'], 16):08X}.c"))]
|
||||
|
||||
@@ -238,6 +238,54 @@ def check_text(path, text):
|
||||
return findings
|
||||
|
||||
|
||||
def _typedef_use_before_def(text):
|
||||
defs = {}
|
||||
for st in cdecl.split_statements(text):
|
||||
if not re.match(r'\s*typedef\b', st.text):
|
||||
continue
|
||||
try:
|
||||
ds = cdecl.parse(st.text)
|
||||
except Exception: # noqa: BLE001 - a parse miss must not sink the check
|
||||
continue
|
||||
for d in ds:
|
||||
if getattr(d, 'storage', None) == 'typedef' and d.name and d.name not in defs:
|
||||
defs[d.name] = st.start
|
||||
# Search for the first use in a COMMENT-BLANKED copy, offsets preserved. The first draft of
|
||||
# this check searched the raw text and flagged a typedef named in its own explanatory comment
|
||||
# (R39 negative control: 1 false positive on md_MAIN_034 AFTER it banked). A checker that
|
||||
# refuses a good slate over prose is worse than no checker -- it discards work silently.
|
||||
blanked = _blank_comments(text)
|
||||
bad = []
|
||||
for name, pos in sorted(defs.items(), key=lambda kv: kv[1]):
|
||||
m = re.search(r'\b%s\b' % re.escape(name), blanked)
|
||||
if m and m.start() < pos:
|
||||
bad.append((name, m.start(), pos))
|
||||
return bad
|
||||
|
||||
|
||||
def _blank_comments(text):
|
||||
"""Replace /*...*/ and //... with spaces, preserving every byte offset."""
|
||||
out = list(text)
|
||||
i, n = 0, len(text)
|
||||
while i < n:
|
||||
if text.startswith('/*', i):
|
||||
j = text.find('*/', i + 2)
|
||||
j = n if j < 0 else j + 2
|
||||
for k in range(i, j):
|
||||
if out[k] != '\n':
|
||||
out[k] = ' '
|
||||
i = j
|
||||
elif text.startswith('//', i):
|
||||
j = text.find('\n', i)
|
||||
j = n if j < 0 else j
|
||||
for k in range(i, j):
|
||||
out[k] = ' '
|
||||
i = j
|
||||
else:
|
||||
i += 1
|
||||
return ''.join(out)
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument('slate')
|
||||
@@ -258,6 +306,28 @@ def main():
|
||||
|
||||
_n, texts = gm.substitute(kept, write=False, transform=_driver_transform)
|
||||
|
||||
# ---- §203: A DEDUPED TYPEDEF MUST PRECEDE EVERY SPLICE POINT (P31 S56).
|
||||
# The transform above is faithful to the driver, and that is exactly the hazard: when two
|
||||
# slate-mates share a type, harvest_verify strips the duplicate from BOTH drafts, and the one
|
||||
# surviving definition sits wherever its owner splices. If the OTHER function is earlier in
|
||||
# ADDRESS order, its externs reference a type the file has not defined yet, and the whole batch
|
||||
# loses that draft to `parse error before '<symbol>'` -- a PLUMBING failure that reads like a
|
||||
# codegen residual. Measured: wave Z's md_MAIN_034 group banked 6 of 7 exactly this way; the
|
||||
# drop cost a gate cycle, three oracles and a wrong first fix to diagnose (cookbook §203).
|
||||
# Cheap to detect here, because we already hold the post-transform text.
|
||||
order_defects = []
|
||||
for _tu, _text in (texts.items() if isinstance(texts, dict) else texts):
|
||||
for name, use_at, def_at in _typedef_use_before_def(_text):
|
||||
line = _text.count('\n', 0, use_at) + 1
|
||||
dline = _text.count('\n', 0, def_at) + 1
|
||||
order_defects.append((_tu, name, line, dline))
|
||||
for tu, name, uline, dline in order_defects:
|
||||
print(f'[DROP-RISK] §203 USE-BEFORE-TYPEDEF: {tu}: `{name}` is used at line {uline} but '
|
||||
f'defined at line {dline}. Two slate-mates share this type and the earlier-addressed '
|
||||
f'one lost its copy to strip_provided_typedefs. FIX: hoist the typedef to the top of '
|
||||
f'the TU (above every splice point); do NOT rename it in one draft -- that gives one '
|
||||
f'symbol two types and the failure just moves.')
|
||||
|
||||
# R32 COVERAGE ASSERTION (P31 S54). Until `gate_main` learned per-binary stub maps, an OVERLAY
|
||||
# slate resolved to zero stubs and this tool printed "checking 0 substituted file(s) ... clean"
|
||||
# -- a green light from a checker that had examined nothing, on exactly the slates (overlay
|
||||
|
||||
Reference in New Issue
Block a user