feat(phase-30 S50): the mechanical A-prop draft — 256 members banked with no agent in the loop

Final S50 state: 307 instances banked, stubs 12,468 -> 12,161, fleet 95.3% instr / 90.0%
distinct / 96.65% fn-count. R22 clean rebuild 4x, check-all 213/213 every time.

- tools/aprop_autodraft.py + tools/draft_prechecks.py: seed body + symbol_map + a MINIMAL
  synthesized preamble. The seed's decl layer never travels — that layer is family_sweep's
  dominant failure (331 of 458 S49 verdicts). 256 banked at zero agent tokens, against the
  ~20M the same work would have cost as a wave.
- Macro seeds (567 of 1196 members, all 3737 de-macroize) take the DEFINITION only; the block
  stays the decl source. Pasting it whole measured 28% vs inline's 68% — func_8016AB6C's macro
  is 1,891 lines of which 108 are the function.
- IMM is a second engine, not a wall: T2a's imm_map_tier1 resolves a per-location LITERAL like
  symbol_map resolves a per-location SYMBOL. 131 of 275 IMM members resolve.
- draft_prechecks negative-controlled against ALL 205 banked drafts: zero false positives,
  catches 39 of 67 known failures. That control found two bugs in the checks themselves —
  C89 `f()` declares UNSPECIFIED parameters (not zero), and a member's own definition read as
  a call to itself. Conservative by design: a pre-check that discards good drafts is worse
  than one that lets a few builds fail.
- The A-prop pool is now priced exactly: PURE 437/37,376 ins, IMM 275/8,849, STRUCT 238/4,259.
- Cookbook §171a; SETUP rows; CURRENT_PHASE S50 FINAL checkpoint.
This commit is contained in:
Drew T
2026-08-14 07:42:19 -06:00
parent f398dce9bf
commit e903713b71
10 changed files with 1422 additions and 1036 deletions
+2
View File
@@ -674,6 +674,8 @@ Every script under `tools/` (plus the two report make-targets), grouped by purpo
| | `tools/prefetch_fleet.py` | **The fleet Ghidra-C prefetch batch** (P30 T0.5): one representative per remaining h_seq distinct class + ALL main/resident stubs → `.run/ghidra_c/`, resumable (skips cached), serial on the project lock; auto-stops a serving MCP (R23 — R29 applies at next MCP use); imports a missing overlay program on demand (`ghidra_import_raw.sh`, blob via `family_remap.img_path`, vram via the splat yaml). `--dry-run` / `--limit-programs N` (probe-first). R32: per-program outcome report, batch continues past failures. |
| | `tools/family_cousins.py` | **(P30 S49, cookbook §168)** The COUSIN-UNIT survey — the similarity tier ABOVE h_seq. h_seq is an exact skeleton hash, so ±1 instruction (li-expansion, table-size drift) fragments same-source families into "singletons"; this tool clusters the distinct open skeletons by mnemonic-stream similarity (≥0.85, union-find) and attaches the best MATCHED-skeleton seed per unit → `.run/family_cousins.json` + `docs/family-cousins.md`. Categories A-prop / seeded / cousin-multi / cold. `--targets N --wave waveN` emits the crack_wave.js slate ranked by whole-UNIT open ins, with each seed's C body location (engine_core.h macro or inline src file) resolved. R32 both ways: fails loud on a stale family map (independent stub recount) and on a partition defect. RANKS AND SEEDS ONLY — cousins need a per-member seeded CRACK (skeleton drift ⇒ recompile), never a `family_sweep` remap; the whole-binary byte-gate stays the sole arbiter. |
| | `tools/aprop_symfix.py` | **(P30 S50, cookbook §171)** The stale-SEED-SYMBOL guard for the adapt/A-prop lanes — the second, DISAGREEING oracle (R34) for the one class `match_one` is structurally blind to. A per-location data symbol (`D_8018xxxx`) carried out of a seed body unrebased scores MATCH standalone (encodings identical; the scorer cannot see a relocation's target NAME) and dies in the host TU at link with `undefined reference`. Audits every draft's vram-suffixed symbols against the symbols the TARGET's own `.s` relocates; `--fix` rewrites the 1:1 cases and emits a `gate_lane`-shaped slate. Deterministic, no build — run it BEFORE the gate, never after. Measured on the S49 A-prop residue: 24 of 24 concentrated failures were this class, 23 banked after the rebase (A-prop conversion 57% -> 87%). Its primitives are imported by `family_cousins.py`, whose `--aprop-cards` members now carry an explicit `sym_map` of `{seed -> member}` renames. |
| | `tools/aprop_autodraft.py` | **(P30 S50, cookbook §171a)** Mechanically drafts lane-A members with NO agent in the loop — seed body + `family_remap.symbol_map` (positional reloc zip) + a MINIMAL preamble synthesized from scratch, so the seed's declaration layer never travels (that layer is `family_sweep`'s dominant failure: 331 of 458 S49 verdicts). Handles inline AND `DEFINE_<fn>()` macro seeds (take the DEFINITION; the block is only the decl source — pasting it whole scored 28% vs inline's 68%), and applies T2a's `imm_map_tier1` so a per-location LITERAL resolves like a per-location symbol (131 of 275 IMM members). REFUSES at generation time what cannot work: non-PURE members, arity conflicts, undefined data, and `.s` files carrying data or a jtbl. **256 banked at zero agent tokens.** Every draft is a candidate — gate via `gate_lane.py`. |
| | `tools/draft_prechecks.py` | **(P30 S50)** Static pre-checks shared by the draft tools: arity disagreement vs the destination's own declaration, and symbols nothing in the destination binary defines. Both are real measured build failures and both are decidable WITHOUT compiling — at ~1 min per gate group that difference is the run. Negative-controlled against all 205 banked drafts of the first run (zero false positives; catches 39 of 67 known failures); that control found two bugs in the checks themselves — C89 `f()` declares UNSPECIFIED parameters (not zero), and a member's own definition read as a call to itself. Deliberately CONSERVATIVE: flags only `decl > call` on named parameters, because a pre-check that discards good drafts is worse than one that lets a few builds fail. |
| **Disc/.CD extraction** (`tools/bfm_extract/`) | `extract.py` | Walk the disc / extract root files (`make extract`). |
| | `extract_exe.py` | Extract & verify `SLUS_007.26` (`--verify-disc`, owns `EXPECTED_EXE_SHA1`). |
| | `extract_proto_exe.py` | Extract the prototype/demo EXE for cross-checking. |
+1006 -869
View File
File diff suppressed because it is too large Load Diff
+6 -3
View File
@@ -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 / 512 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 / 513 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.
@@ -116,7 +116,7 @@
- **§83d** — CSE's quantity budget is WHOLE-FUNCTION, so a local rewrite cannot fix a local symptom <sub>L6452</sub>
- **§153** — THE ADDRESS-REMATERIALISATION LAUNDER: a third zero-emission asm lever (P30 S43, `func_8018D98C`, 710 ins) <sub>L10463</sub>
### loops & induction variables (9)
### loops & induction variables (10)
- **§3-T1** — Loop pointer: top-of-body for `addu` induction, not constant-folded `addiu` <sub>L71</sub>
- **§34** — The `func_80138ED0` giant crack: gcc-2.7.2's **3-qty sort bug** + the **zero-byte asm allocation toolkit** + the **giv-init fence** (Phase 24 T5; Opus→close=21, Fable5→MATCH ×134) <sub>L2454</sub>
@@ -127,6 +127,7 @@
- **§70** — The giv-init base register: walk the PARAMETER, not a copy of it (Phase 29 SESSION-18, `func_801777BC`) <sub>L5619</sub>
- **§145** — Three loop/combine levers from the S40 wave-2 drafters (16/16 match_one) <sub>L9924</sub>
- **§148** — The loop.c hoisting THRESHOLD is arithmetic you can compute, and the `?:` clamp that folds to MIN_EXPR (P30 S42, `func_8017C6F4`, 947 ins) <sub>L10142</sub>
- **§171a** — THE MECHANICAL A-PROP DRAFT (P30 S50): 256 members banked with no agent in the loop <sub>L16398</sub>
### structs, block moves & memcpy (35)
@@ -308,7 +309,7 @@
- **§127a** — §71 (sibling-first) is the strongest `-O0` lever, and it beats the index <sub>L8377</sub>
- **§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`) <sub>L8570</sub>
### family propagation & sweeps (84)
### family propagation & sweeps (85)
- **§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>
@@ -394,6 +395,7 @@
- **§163z** — THE UNVETTED REMAINDER (do not cite as law; each needs a dedupe pass) <sub>L11825</sub>
- **§3-The** — ADDRESS-CLASS TABLE: which load/store pairs even REACH the `/s` clause (P30 S48 wave 4, `func_80185B44`, ov_SC03_014) <sub>L14339</sub>
- **§168** — THE COUSIN TIER (P30 S49, 2026-08-12): h_seq's exact-hash brittleness, measured — and the similarity map above it <sub>L16208</sub>
- **§171a** — THE MECHANICAL A-PROP DRAFT (P30 S50): 256 members banked with no agent in the loop <sub>L16398</sub>
### integration / TU plumbing (39)
@@ -1312,3 +1314,4 @@
- **§169** — THE MICRO-ADAPT LANE (P30 S49): edit a proven body, don't crack a new one <sub>L16260</sub>
- **§170** — THE A-PROP WORD-DIFF CARD (P30 S49): the lane that had no owner <sub>L16307</sub>
- **§171** — THE STALE SEED SYMBOL (P30 S50, 2026-08-13): why §170's 91%→57% was never codegen <sub>L16351</sub>
- **§171a** — THE MECHANICAL A-PROP DRAFT (P30 S50): 256 members banked with no agent in the loop <sub>L16398</sub>
+32 -32
View File
@@ -1,6 +1,6 @@
# P30 S49 — cousin-unit survey (similarity tier over the open frontier)
> Generated by `tools/family_cousins.py` at HEAD `commit:1843` 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:1901` 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 | 239 | 1700 | 76419 | family_sweep (propagation) |
| A-prop | 239 | 1606 | 74209 | family_sweep (propagation) |
| seeded | 364 | 1152 | 33618 | seeded crack — edit a >=0.85-similar MATCHED body |
| cousin-multi | 1542 | 5409 | 248330 | 1 crack seeds the unit's other members |
| cold | 3240 | 3240 | 215454 | full-price crack (the honest unique tail) |
| **total** | **5385** | **11501** | **573821** | |
| **total** | **5385** | **11407** | **571611** | |
## Top units by open instructions (whole-cluster weight)
@@ -26,35 +26,35 @@
| 6 | seeded | 2166 | 3 | 3 | 0.987 | `ov_SC06_010:0x8017cad4` | `ov_SC06_010:0x8017bebc` (753 ins ×1) |
| 7 | cousin-multi | 1628 | 3 | 3 | · | · | `md_MAIN_011:0x800d1254` (555 ins ×1) |
| 8 | A-prop | 1628 | 4 | 1 | 1.0 | `ov_MAIN_012:0x8017c3bc` | `ov_MAIN_012:0x8017c3bc` (407 ins ×4 jr) |
| 9 | A-prop | 1554 | 59 | 3 | 1.0 | `md_SC05_023:0x801edc18` | `md_SC05_023:0x801edc18` (26 ins ×56) |
| 10 | seeded | 1466 | 6 | 3 | 0.93 | `ov_SC07_006:0x801802ec` | `ov_SC07_006:0x8017f9ac` (275 ins ×2) |
| 11 | cousin-multi | 1395 | 5 | 1 | · | · | `ov_SC01_005:0x8017f2d4` (279 ins ×5 jr) |
| 9 | seeded | 1466 | 6 | 3 | 0.93 | `ov_SC07_006:0x801802ec` | `ov_SC07_006:0x8017f9ac` (275 ins ×2) |
| 10 | cousin-multi | 1395 | 5 | 1 | · | · | `ov_SC01_005:0x8017f2d4` (279 ins ×5 jr) |
| 11 | A-prop | 1320 | 50 | 3 | 1.0 | `md_SC03_076:0x801f1cd8` | `md_SC03_076:0x801f1cd8` (26 ins ×47) |
| 12 | A-prop | 1316 | 7 | 1 | 1.0 | `ov_SC01_000:0x8016ab6c` | `ov_SC01_077:0x8016ab6c` (188 ins ×7 jr) |
| 13 | A-prop | 1309 | 7 | 1 | 1.0 | `ov_SC01_000:0x8013dd68` | `ov_SC01_077:0x8013dd68` (187 ins ×7) |
| 14 | A-prop | 1304 | 4 | 1 | 1.0 | `ov_MAIN_012:0x8017d730` | `ov_MAIN_012:0x8017d730` (326 ins ×4 jr) |
| 15 | A-prop | 1195 | 30 | 6 | 1.0 | `ov_SC01_077:0x8017d840` | `ov_SC01_077:0x8017d840` (39 ins ×21) |
| 16 | A-prop | 1164 | 4 | 1 | 1.0 | `ov_MAIN_012:0x8017d2a4` | `ov_MAIN_012:0x8017d2a4` (291 ins ×4 jr) |
| 17 | A-prop | 1089 | 3 | 1 | 1.0 | `ov_SC01_000:0x8015444c` | `ov_SC01_077:0x8015444c` (363 ins ×3 jr) |
| 18 | A-prop | 1049 | 4 | 3 | 1.0 | `ov_SC03_028:0x80183e04` | `ov_SC03_028:0x80183e04` (265 ins ×2) |
| 19 | A-prop | 1035 | 11 | 5 | 1.0 | `ov_SC06_018:0x80187320` | `ov_SC02_011:0x80188250` (94 ins ×4) |
| 20 | A-prop | 996 | 46 | 10 | 1.0 | `ov_SC03_001:0x8017f0ec` | `ov_SC03_001:0x8017f0ec` (20 ins ×30) |
| 21 | A-prop | 987 | 3 | 1 | 1.0 | `ov_SC01_000:0x8013c414` | `ov_SC01_077:0x8013c414` (329 ins ×3 jr) |
| 22 | A-prop | 979 | 18 | 11 | 1.0 | `ov_SC06_024:0x8017d474` | `ov_SC06_022:0x8017d6e0` (59 ins ×4) |
| 23 | A-prop | 964 | 12 | 3 | 1.0 | `md_SC03_073:0x801efc94` | `md_SC03_079:0x801efb94` (87 ins ×4) |
| 24 | A-prop | 924 | 21 | 1 | 1.0 | `ov_SC02_026:0x80185634` | `ov_SC02_026:0x80185634` (44 ins ×21) |
| 25 | A-prop | 914 | 8 | 4 | 1.0 | `ov_SC02_017:0x8017f92c` | `ov_SC02_017:0x8017f92c` (115 ins ×4) |
| 26 | A-prop | 908 | 19 | 6 | 1.0 | `ov_SC02_041:0x80182ccc` | `ov_SC02_041:0x80182ccc` (45 ins ×9) |
| 27 | A-prop | 889 | 7 | 1 | 1.0 | `ov_SC01_000:0x80145cec` | `ov_SC01_077:0x80145cec` (127 ins ×7) |
| 28 | A-prop | 872 | 4 | 1 | 1.0 | `ov_MAIN_012:0x8017cf3c` | `ov_MAIN_012:0x8017cf3c` (218 ins ×4 jr) |
| 29 | A-prop | 816 | 3 | 1 | 1.0 | `ov_SC01_000:0x8013b83c` | `ov_SC01_077:0x8013b83c` (272 ins ×3 jr) |
| 30 | A-prop | 810 | 54 | 1 | 1.0 | `md_SC03_073:0x801ef5f4` | `ov_SC01_077:0x80130d0c` (15 ins ×54) |
| 31 | cousin-multi | 810 | 10 | 2 | · | · | `ov_SC01_005:0x8017e108` (84 ins ×5) |
| 32 | A-prop | 798 | 3 | 1 | 1.0 | `ov_SC01_000:0x80130d48` | `ov_SC01_077:0x80130d48` (266 ins ×3) |
| 33 | cousin-multi | 784 | 4 | 1 | · | · | `ov_SC03_108:0x8017ffd0` (196 ins ×4 jr) |
| 34 | cousin-multi | 781 | 8 | 4 | · | · | `ov_SC02_011:0x8018c5a4` (100 ins ×3) |
| 35 | cousin-multi | 778 | 7 | 5 | · | · | `ov_SC03_118:0x80181e58` (113 ins ×2) |
| 36 | cousin-multi | 767 | 15 | 7 | 0.735 | · | `ov_SC03_028:0x8018966c` (63 ins ×4) |
| 37 | seeded | 752 | 14 | 10 | 0.921 | `ov_SC02_027:0x8017f6d4` | `ov_SC02_027:0x8017f858` (48 ins ×3) |
| 38 | A-prop | 726 | 33 | 4 | 1.0 | `md_SC05_023:0x801ed99c` | `md_SC05_023:0x801ed99c` (22 ins ×27) |
| 39 | A-prop | 725 | 31 | 10 | 1.0 | `ov_SC04_018:0x80183248` | `ov_SC04_018:0x8017f500` (25 ins ×6) |
| 40 | cousin-multi | 702 | 7 | 3 | · | · | `ov_SC03_014:0x80188828` (99 ins ×3) |
| 15 | A-prop | 1164 | 4 | 1 | 1.0 | `ov_MAIN_012:0x8017d2a4` | `ov_MAIN_012:0x8017d2a4` (291 ins ×4 jr) |
| 16 | A-prop | 1089 | 3 | 1 | 1.0 | `ov_SC01_000:0x8015444c` | `ov_SC01_077:0x8015444c` (363 ins ×3 jr) |
| 17 | A-prop | 1049 | 4 | 3 | 1.0 | `ov_SC03_028:0x80183e04` | `ov_SC03_028:0x80183e04` (265 ins ×2) |
| 18 | A-prop | 1035 | 11 | 5 | 1.0 | `ov_SC06_018:0x80187320` | `ov_SC02_011:0x80188250` (94 ins ×4) |
| 19 | A-prop | 987 | 3 | 1 | 1.0 | `ov_SC01_000:0x8013c414` | `ov_SC01_077:0x8013c414` (329 ins ×3 jr) |
| 20 | A-prop | 979 | 18 | 11 | 1.0 | `ov_SC06_024:0x8017d474` | `ov_SC06_022:0x8017d6e0` (59 ins ×4) |
| 21 | A-prop | 964 | 12 | 3 | 1.0 | `md_SC03_073:0x801efc94` | `md_SC03_079:0x801efb94` (87 ins ×4) |
| 22 | A-prop | 914 | 8 | 4 | 1.0 | `ov_SC02_017:0x8017f92c` | `ov_SC02_017:0x8017f92c` (115 ins ×4) |
| 23 | A-prop | 908 | 19 | 6 | 1.0 | `ov_SC02_041:0x80182ccc` | `ov_SC02_041:0x80182ccc` (45 ins ×9) |
| 24 | A-prop | 889 | 7 | 1 | 1.0 | `ov_SC01_000:0x80145cec` | `ov_SC01_077:0x80145cec` (127 ins ×7) |
| 25 | A-prop | 872 | 4 | 1 | 1.0 | `ov_MAIN_012:0x8017cf3c` | `ov_MAIN_012:0x8017cf3c` (218 ins ×4 jr) |
| 26 | A-prop | 816 | 3 | 1 | 1.0 | `ov_SC01_000:0x8013b83c` | `ov_SC01_077:0x8013b83c` (272 ins ×3 jr) |
| 27 | cousin-multi | 810 | 10 | 2 | · | · | `ov_SC01_005:0x8017e108` (84 ins ×5) |
| 28 | A-prop | 798 | 3 | 1 | 1.0 | `ov_SC01_000:0x80130d48` | `ov_SC01_077:0x80130d48` (266 ins ×3) |
| 29 | cousin-multi | 784 | 4 | 1 | · | · | `ov_SC03_108:0x8017ffd0` (196 ins ×4 jr) |
| 30 | cousin-multi | 781 | 8 | 4 | · | · | `ov_SC02_011:0x8018c5a4` (100 ins ×3) |
| 31 | cousin-multi | 778 | 7 | 5 | · | · | `ov_SC03_118:0x80181e58` (113 ins ×2) |
| 32 | cousin-multi | 767 | 15 | 7 | 0.735 | · | `ov_SC03_028:0x8018966c` (63 ins ×4) |
| 33 | seeded | 752 | 14 | 10 | 0.921 | `ov_SC02_027:0x8017f6d4` | `ov_SC02_027:0x8017f858` (48 ins ×3) |
| 34 | A-prop | 727 | 18 | 6 | 1.0 | `ov_SC01_074:0x8017dba0` | `ov_SC01_077:0x8017d840` (39 ins ×9) |
| 35 | A-prop | 725 | 31 | 10 | 1.0 | `ov_SC04_018:0x80183248` | `ov_SC04_018:0x8017f500` (25 ins ×6) |
| 36 | cousin-multi | 702 | 7 | 3 | · | · | `ov_SC03_014:0x80188828` (99 ins ×3) |
| 37 | cousin-multi | 696 | 10 | 3 | · | · | `ov_SC02_041:0x80181164` (72 ins ×4) |
| 38 | A-prop | 694 | 17 | 6 | 1.0 | `ov_SC02_005:0x8017df78` | `ov_SC02_005:0x8017df78` (39 ins ×11) |
| 39 | cousin-multi | 680 | 8 | 2 | 0.7 | · | `md_SC03_077:0x801efb58` (87 ins ×4 jr) |
| 40 | cousin-multi | 668 | 3 | 3 | · | · | `ov_SC02_017:0x80186770` (230 ins ×1) |
+3 -3
View File
@@ -5,11 +5,11 @@
> 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:1843` · 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:1901` · 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):** 96.8% fn / 95.7% instr / 91.1% distinct-code matched. Unmatched: 11,501 instances / 573,821 ins (9,892 distinct classes).
**Fleet (overlays):** 96.8% fn / 95.7% instr / 91.1% distinct-code matched. Unmatched: 11,407 instances / 571,611 ins (9,824 distinct classes).
**Tail cross-check (Phase-25 close):** 7,541 tail fns / 372,807 ins → 440 h_seq families ≥2, **72 substantial (nins≥80) / 30,992 ins**.
**Tail cross-check (Phase-25 close):** 7,520 tail fns / 372,305 ins → 440 h_seq families ≥2, **72 substantial (nins≥80) / 30,992 ins**.
**Full frontier (all unmatched by h_seq):** 2014 target families (≥2 members or a matched sibling) + 4504 singletons (Step-D residue). Substantial: **266 families / 94,856 templatable ins**, 59 with a matched sibling (zero-crack). Substantial member classes: 671 PURE · 29 IMM · 6 STRUCT-excluded.
+50
View File
@@ -16394,3 +16394,53 @@ symbol audit is the second oracle that can disagree with it, and it costs no bui
macro seed, an AMBIGUOUS on every 1:1 rename) were case mismatches — the same class §128/R35 keeps
naming. Compare function identities case-insensitively, and strip the `DEFINE_` prefix, or the
seed's own name reads as a stale symbol.
## §171a — THE MECHANICAL A-PROP DRAFT (P30 S50): 256 members banked with no agent in the loop
**The claim.** A lane-A member shares its family's `h_seq` with a MATCHED sibling, so its body IS
that sibling's body with the per-location environment rebased. Two mechanisms had each taken a run
at that population and each left it on the table:
- **`family_sweep --hseq`** remaps mechanically but CARRIES the seed's declaration layer, and its
dominant failure is decl-agreement — 331 of the 458 verdicts in S49's post-repair ledger.
The body was never the problem; the decls it dragged along were.
- **the A-prop agent wave** re-derives the same body at ~80k tokens per banked function — and got
the per-location symbol wrong every time it mattered (§171).
`tools/aprop_autodraft.py` does neither: seed body + `family_remap.symbol_map` (positional reloc
zip, three-oracle target spelling) + a **minimal preamble synthesized from scratch** — one `extern`
per symbol the body actually references, plus only those seed typedefs the body names and the
destination does not already define. Nothing else travels. **256 banked at zero agent tokens**
(222 + 34), against ~20M tokens the same work would have cost as a wave.
**THE SELECTOR IS THE TOOL.** Everything below was learned by launching at scale and stopping when
the verdicts disagreed with the plan. Each fix moves a failure from *build time* to *generation
time*, and at ~1 min per gate group that difference IS the run:
| Refusal | Why a draft cannot work | Measured |
|---|---|---|
| `classify_member != PURE` | a rename reaches a **RELOC** site and nothing else | first 5 failures were 5/5 IMM or STRUCT |
| no definition after rename | the seed name was recovered by scanning the body for the first `func_XXXX(` — in a de-macroized block that is the first *extern declaration*, so a CALLEE got the member's name and the definition kept the seed's | 48 caught; the symptom was `undefined reference to <member>` |
| arity conflict | the destination already declares a callee with **named** parameters the body underfills | 17 on one symbol alone |
| undefined data | the draft references a symbol nothing in the DESTINATION binary defines — the seed's environment does not exist there | 43 + 33 on two symbols |
| `.s` carries data or a jtbl | the data lives INSIDE the stub being replaced, or the carve path refuses | 90 of 584 |
**Macro seeds are the majority and they are a trap.** 567 of 1,196 members sit behind a
`DEFINE_<fn>()` engine_core macro (all 3,737 de-macroize cleanly). Pasting the de-macroized block
whole reintroduces exactly the decl-agreement failure this design exists to avoid: measured
**inline 145/213 (68%) vs macro 77/276 (28%)**, with the macro failures reading `parse error before
'*'` and `too few arguments`. `func_8016AB6C`'s macro block is **1,891 lines of which 108 are the
function**. Take the DEFINITION; keep the block only as the decl source.
**IMM is not a wall, it is a second engine.** T2a's `imm_map_tier1` resolves a per-location LITERAL
exactly as `symbol_map` resolves a per-location SYMBOL: **131 of 275 IMM members** resolve with zero
unresolved sites. Only STRUCT (register/opcode drift, 238 members / 4,259 ins) genuinely needs a
per-member edit.
**Negative-control every refusal before you ship it** (`tools/draft_prechecks.py`, run against ALL
205 banked drafts of the first run: **zero false positives**, catches 39 of 67 known failures). That
control found two bugs in the checks themselves, both of which would have thrown away good work
silently: **C89 `f()` declares UNSPECIFIED parameters, not zero** — so `decl 0 vs call 1` is no
conflict at all — and a member's own definition read as a call to itself. A pre-check that discards
good drafts is worse than one that lets a few builds fail; when in doubt make it CONSERVATIVE
(flag only `decl > call`, on named parameters).
+123 -123
View File
@@ -4,16 +4,16 @@
# cross-binary collapsible-byte leverage: docs/duplicates.cross.md.
# THREE progress metrics (all matter — see the labels):
FLEET fn-count byte-ident: 350715 / 363163 = 96.57% (REAL+LINKED+empties; FUNCTION-count, ×134-inflated — one crack counts per overlay)
FLEET instr-weighted : 12873171 / 13523856 = 95.2% (shipped .text across main + resident + 211 overlays; the decomp.dev-DISPLAY number)
FLEET distinct-code(uniq): 5260690 / 5851963 = 89.9% (81104/90928 unique fns; the DISTINCT-RE number)
FLEET fn-count byte-ident: 350995 / 363163 = 96.65% (REAL+LINKED+empties; FUNCTION-count, ×134-inflated — one crack counts per overlay)
FLEET instr-weighted : 12882877 / 13523856 = 95.3% (shipped .text across main + resident + 211 overlays; the decomp.dev-DISPLAY number)
FLEET distinct-code(uniq): 5267836 / 5851963 = 90.0% (81310/90928 unique fns; the DISTINCT-RE number)
MAIN game-code weighted : 436 / 79510 = 0.5% (INCLUDED in the fleet numbers above since 2026-07-22 — roadmap §1 metrics contract; LINKED-excluding Ghidra sig dated 2026-08-05; caveat is R34: no independent second oracle for a PS-X EXE, NOT drift)
(fleet EXCLUDING main, for continuity with pre-2026-07-22 readings: 12872735 / 13444346 = 95.7%)
(fleet EXCLUDING main, for continuity with pre-2026-07-22 readings: 12882441 / 13444346 = 95.8%)
FLEET REAL substantive : 348545 (of which dedup-shared 254400 via 2043 groups / 254474 instances)
FLEET REAL substantive : 348825 (of which dedup-shared 254437 via 2059 groups / 254511 instances)
FLEET LINKED PsyQ objs : 959
FLEET NON_MATCHING : 7 (0 in any default build — G4)
FLEET INCLUDE_ASM stubs : 12441
FLEET INCLUDE_ASM stubs : 12161
FLEET matchable : 363163
| binary | REAL | shared | LINKED | byte-ident | matchable | byte-ident % |
@@ -31,22 +31,22 @@ FLEET matchable : 363163
| md_MAIN_017 | 4 | 0 | 0 | 4 | 10 | 40.0% |
| md_MAIN_018 | 3 | 0 | 0 | 4 | 11 | 36.4% |
| md_MAIN_019 | 8 | 0 | 0 | 8 | 22 | 36.4% |
| md_MAIN_020 | 8 | 0 | 0 | 9 | 14 | 64.3% |
| md_MAIN_020 | 9 | 0 | 0 | 10 | 14 | 71.4% |
| md_MAIN_021 | 4 | 0 | 0 | 5 | 11 | 45.5% |
| md_MAIN_022 | 18 | 0 | 0 | 20 | 33 | 60.6% |
| md_MAIN_022 | 19 | 0 | 0 | 21 | 33 | 63.6% |
| md_MAIN_023 | 3 | 0 | 0 | 4 | 6 | 66.7% |
| md_MAIN_024 | 3 | 0 | 0 | 5 | 6 | 83.3% |
| md_MAIN_025 | 5 | 0 | 0 | 5 | 30 | 16.7% |
| md_MAIN_025 | 6 | 0 | 0 | 6 | 30 | 20.0% |
| md_MAIN_026 | 7 | 0 | 0 | 7 | 24 | 29.2% |
| md_MAIN_027 | 9 | 0 | 0 | 11 | 29 | 37.9% |
| md_MAIN_028 | 4 | 0 | 0 | 4 | 22 | 18.2% |
| md_MAIN_028 | 5 | 0 | 0 | 5 | 22 | 22.7% |
| md_MAIN_029 | 3 | 0 | 0 | 4 | 11 | 36.4% |
| md_MAIN_030 | 4 | 0 | 0 | 4 | 10 | 40.0% |
| md_MAIN_031 | 4 | 0 | 0 | 4 | 18 | 22.2% |
| md_MAIN_032 | 5 | 0 | 0 | 5 | 10 | 50.0% |
| md_MAIN_033 | 4 | 0 | 0 | 4 | 19 | 21.1% |
| md_MAIN_034 | 5 | 0 | 0 | 6 | 28 | 21.4% |
| md_MAIN_035 | 10 | 0 | 0 | 11 | 16 | 68.8% |
| md_MAIN_035 | 11 | 0 | 0 | 12 | 16 | 75.0% |
| md_MAIN_036 | 9 | 0 | 0 | 10 | 28 | 35.7% |
| md_MAIN_037 | 4 | 0 | 0 | 4 | 17 | 23.5% |
| md_MAIN_038 | 7 | 0 | 0 | 7 | 20 | 35.0% |
@@ -56,41 +56,41 @@ FLEET matchable : 363163
| md_MAIN_042 | 0 | 0 | 0 | 0 | 4 | 0.0% |
| md_MAIN_043 | 4 | 0 | 0 | 5 | 23 | 21.7% |
| md_MAIN_044 | 12 | 0 | 0 | 13 | 44 | 29.5% |
| md_MAIN_045 | 3 | 0 | 0 | 4 | 21 | 19.0% |
| md_MAIN_046 | 8 | 0 | 0 | 9 | 39 | 23.1% |
| md_MAIN_045 | 5 | 0 | 0 | 6 | 21 | 28.6% |
| md_MAIN_046 | 10 | 0 | 0 | 11 | 39 | 28.2% |
| md_MAIN_047 | 3 | 0 | 0 | 4 | 12 | 33.3% |
| md_SC02_009 | 5 | 0 | 0 | 5 | 40 | 12.5% |
| md_SC03_073 | 24 | 10 | 0 | 24 | 28 | 85.7% |
| md_SC03_074 | 22 | 10 | 0 | 22 | 29 | 75.9% |
| md_SC03_075 | 26 | 10 | 0 | 26 | 41 | 63.4% |
| md_SC03_076 | 31 | 0 | 0 | 33 | 66 | 50.0% |
| md_SC03_073 | 25 | 10 | 0 | 25 | 28 | 89.3% |
| md_SC03_074 | 23 | 10 | 0 | 23 | 29 | 79.3% |
| md_SC03_075 | 27 | 10 | 0 | 27 | 41 | 65.9% |
| md_SC03_076 | 34 | 0 | 0 | 36 | 66 | 54.5% |
| md_SC03_077 | 23 | 0 | 0 | 25 | 35 | 71.4% |
| md_SC03_078 | 22 | 9 | 0 | 22 | 27 | 81.5% |
| md_SC03_079 | 22 | 0 | 0 | 24 | 29 | 82.8% |
| md_SC03_132 | 22 | 0 | 0 | 24 | 28 | 85.7% |
| md_SC03_133 | 20 | 1 | 0 | 22 | 29 | 75.9% |
| md_SC03_134 | 24 | 1 | 0 | 26 | 41 | 63.4% |
| md_SC03_135 | 28 | 0 | 0 | 30 | 66 | 45.5% |
| md_SC03_136 | 19 | 0 | 0 | 21 | 35 | 60.0% |
| md_SC03_137 | 19 | 1 | 0 | 21 | 27 | 77.8% |
| md_SC03_138 | 23 | 1 | 0 | 27 | 37 | 73.0% |
| md_SC04_024 | 22 | 0 | 0 | 24 | 28 | 85.7% |
| md_SC04_025 | 19 | 0 | 0 | 21 | 29 | 72.4% |
| md_SC04_026 | 23 | 0 | 0 | 25 | 41 | 61.0% |
| md_SC04_027 | 28 | 0 | 0 | 30 | 66 | 45.5% |
| md_SC04_028 | 20 | 0 | 0 | 22 | 35 | 62.9% |
| md_SC04_029 | 18 | 0 | 0 | 20 | 27 | 74.1% |
| md_SC04_030 | 21 | 0 | 0 | 25 | 31 | 80.6% |
| md_SC03_078 | 24 | 9 | 0 | 24 | 27 | 88.9% |
| md_SC03_079 | 23 | 0 | 0 | 25 | 29 | 86.2% |
| md_SC03_132 | 25 | 0 | 0 | 27 | 28 | 96.4% |
| md_SC03_133 | 21 | 1 | 0 | 23 | 29 | 79.3% |
| md_SC03_134 | 25 | 1 | 0 | 27 | 41 | 65.9% |
| md_SC03_135 | 32 | 0 | 0 | 34 | 66 | 51.5% |
| md_SC03_136 | 21 | 0 | 0 | 23 | 35 | 65.7% |
| md_SC03_137 | 21 | 1 | 0 | 23 | 27 | 85.2% |
| md_SC03_138 | 24 | 1 | 0 | 28 | 37 | 75.7% |
| md_SC04_024 | 24 | 0 | 0 | 26 | 28 | 92.9% |
| md_SC04_025 | 20 | 0 | 0 | 22 | 29 | 75.9% |
| md_SC04_026 | 24 | 0 | 0 | 26 | 41 | 63.4% |
| md_SC04_027 | 31 | 0 | 0 | 33 | 66 | 50.0% |
| md_SC04_028 | 21 | 0 | 0 | 23 | 35 | 65.7% |
| md_SC04_029 | 20 | 0 | 0 | 22 | 27 | 81.5% |
| md_SC04_030 | 22 | 0 | 0 | 26 | 31 | 83.9% |
| md_SC05_023 | 22 | 0 | 0 | 24 | 28 | 85.7% |
| md_SC05_024 | 18 | 0 | 0 | 20 | 29 | 69.0% |
| md_SC05_025 | 22 | 0 | 0 | 24 | 41 | 58.5% |
| md_SC05_026 | 25 | 0 | 0 | 27 | 66 | 40.9% |
| md_SC05_027 | 17 | 0 | 0 | 19 | 35 | 54.3% |
| md_SC05_028 | 17 | 0 | 0 | 19 | 27 | 70.4% |
| md_SC05_029 | 20 | 0 | 0 | 24 | 31 | 77.4% |
| md_SC07_003 | 17 | 0 | 0 | 17 | 100 | 17.0% |
| md_SC05_024 | 20 | 0 | 0 | 22 | 29 | 75.9% |
| md_SC05_025 | 24 | 0 | 0 | 26 | 41 | 63.4% |
| md_SC05_026 | 30 | 0 | 0 | 32 | 66 | 48.5% |
| md_SC05_027 | 20 | 0 | 0 | 22 | 35 | 62.9% |
| md_SC05_028 | 20 | 0 | 0 | 22 | 27 | 81.5% |
| md_SC05_029 | 22 | 0 | 0 | 26 | 31 | 83.9% |
| md_SC07_003 | 18 | 0 | 0 | 18 | 100 | 18.0% |
| md_SC07_004 | 43 | 0 | 0 | 43 | 315 | 13.7% |
| ov_MAIN_012 | 2222 | 1690 | 0 | 2301 | 2403 | 95.8% |
| ov_MAIN_012 | 2225 | 1690 | 0 | 2304 | 2403 | 95.9% |
| ov_SC01_000 | 2390 | 1809 | 0 | 2390 | 2403 | 99.5% |
| ov_SC01_001 | 2399 | 1811 | 0 | 2401 | 2466 | 97.4% |
| ov_SC01_004 | 2399 | 1802 | 0 | 2400 | 2414 | 99.4% |
@@ -102,131 +102,131 @@ FLEET matchable : 363163
| ov_SC01_077 | 2568 | 1764 | 0 | 2570 | 2586 | 99.4% |
| ov_SC01_080 | 2426 | 1806 | 0 | 2426 | 2512 | 96.6% |
| ov_SC01_084 | 2450 | 1811 | 0 | 2455 | 2579 | 95.2% |
| ov_SC02_000 | 2533 | 1851 | 0 | 2533 | 2683 | 94.4% |
| ov_SC02_003 | 2532 | 1851 | 0 | 2532 | 2683 | 94.4% |
| ov_SC02_000 | 2533 | 1852 | 0 | 2533 | 2683 | 94.4% |
| ov_SC02_003 | 2532 | 1852 | 0 | 2532 | 2683 | 94.4% |
| ov_SC02_004 | 2391 | 1806 | 0 | 2391 | 2401 | 99.6% |
| ov_SC02_005 | 2542 | 1802 | 0 | 2552 | 2927 | 87.2% |
| ov_SC02_011 | 2640 | 1810 | 0 | 2650 | 2893 | 91.6% |
| ov_SC02_011 | 2643 | 1810 | 0 | 2653 | 2893 | 91.7% |
| ov_SC02_015 | 2402 | 1808 | 0 | 2402 | 2414 | 99.5% |
| ov_SC02_016 | 2484 | 1809 | 0 | 2487 | 2545 | 97.7% |
| ov_SC02_017 | 2555 | 1809 | 0 | 2563 | 2732 | 93.8% |
| ov_SC02_017 | 2556 | 1809 | 0 | 2564 | 2732 | 93.9% |
| ov_SC02_021 | 2407 | 1808 | 0 | 2407 | 2437 | 98.8% |
| ov_SC02_026 | 2513 | 1807 | 0 | 2519 | 2572 | 97.9% |
| ov_SC02_027 | 2567 | 1828 | 0 | 2576 | 2692 | 95.7% |
| ov_SC02_028 | 2577 | 1827 | 0 | 2587 | 2701 | 95.8% |
| ov_SC02_031 | 2499 | 1808 | 0 | 2504 | 2562 | 97.7% |
| ov_SC02_035 | 2496 | 1806 | 0 | 2499 | 2520 | 99.2% |
| ov_SC02_037 | 2335 | 1704 | 0 | 2417 | 2516 | 96.1% |
| ov_SC02_031 | 2501 | 1809 | 0 | 2506 | 2562 | 97.8% |
| ov_SC02_035 | 2497 | 1806 | 0 | 2500 | 2520 | 99.2% |
| ov_SC02_037 | 2339 | 1704 | 0 | 2421 | 2516 | 96.2% |
| ov_SC02_039 | 2397 | 1806 | 0 | 2397 | 2416 | 99.2% |
| ov_SC02_041 | 2487 | 1806 | 0 | 2490 | 2561 | 97.2% |
| ov_SC03_001 | 2685 | 1807 | 0 | 2702 | 2869 | 94.2% |
| ov_SC02_041 | 2489 | 1806 | 0 | 2492 | 2561 | 97.3% |
| ov_SC03_001 | 2698 | 1807 | 0 | 2715 | 2869 | 94.6% |
| ov_SC03_002 | 2549 | 1815 | 0 | 2564 | 2631 | 97.5% |
| ov_SC03_003 | 2400 | 1806 | 0 | 2401 | 2423 | 99.1% |
| ov_SC03_006 | 2564 | 1813 | 0 | 2573 | 2767 | 93.0% |
| ov_SC03_007 | 2467 | 1806 | 0 | 2471 | 2623 | 94.2% |
| ov_SC03_003 | 2401 | 1806 | 0 | 2402 | 2423 | 99.1% |
| ov_SC03_006 | 2568 | 1813 | 0 | 2577 | 2767 | 93.1% |
| ov_SC03_007 | 2469 | 1806 | 0 | 2473 | 2623 | 94.3% |
| ov_SC03_010 | 2419 | 1806 | 0 | 2419 | 2471 | 97.9% |
| ov_SC03_011 | 2419 | 1806 | 0 | 2425 | 2527 | 96.0% |
| ov_SC03_012 | 2390 | 1806 | 0 | 2391 | 2406 | 99.4% |
| ov_SC03_013 | 2424 | 1806 | 0 | 2424 | 2493 | 97.2% |
| ov_SC03_014 | 2593 | 1838 | 0 | 2593 | 2685 | 96.6% |
| ov_SC03_015 | 2370 | 1838 | 0 | 2370 | 2468 | 96.0% |
| ov_SC03_023 | 2403 | 1806 | 0 | 2404 | 2435 | 98.7% |
| ov_SC03_024 | 2527 | 1812 | 0 | 2534 | 2641 | 95.9% |
| ov_SC03_028 | 2465 | 1807 | 0 | 2469 | 2664 | 92.7% |
| ov_SC03_029 | 2503 | 1809 | 0 | 2513 | 2644 | 95.0% |
| ov_SC03_030 | 2420 | 1811 | 0 | 2422 | 2495 | 97.1% |
| ov_SC03_031 | 2449 | 1807 | 0 | 2452 | 2514 | 97.5% |
| ov_SC03_089 | 2523 | 1811 | 0 | 2530 | 2581 | 98.0% |
| ov_SC03_090 | 2540 | 1811 | 0 | 2548 | 2625 | 97.1% |
| ov_SC03_091 | 2554 | 1828 | 0 | 2562 | 2640 | 97.0% |
| ov_SC03_092 | 2514 | 1811 | 0 | 2526 | 2588 | 97.6% |
| ov_SC03_093 | 2527 | 1828 | 0 | 2531 | 2563 | 98.8% |
| ov_SC03_094 | 2517 | 1806 | 0 | 2523 | 2577 | 97.9% |
| ov_SC03_011 | 2421 | 1806 | 0 | 2427 | 2527 | 96.0% |
| ov_SC03_012 | 2391 | 1806 | 0 | 2392 | 2406 | 99.4% |
| ov_SC03_013 | 2425 | 1806 | 0 | 2425 | 2493 | 97.3% |
| ov_SC03_014 | 2593 | 1841 | 0 | 2593 | 2685 | 96.6% |
| ov_SC03_015 | 2375 | 1841 | 0 | 2375 | 2468 | 96.2% |
| ov_SC03_023 | 2404 | 1806 | 0 | 2405 | 2435 | 98.8% |
| ov_SC03_024 | 2530 | 1813 | 0 | 2537 | 2641 | 96.1% |
| ov_SC03_028 | 2466 | 1807 | 0 | 2470 | 2664 | 92.7% |
| ov_SC03_029 | 2504 | 1809 | 0 | 2514 | 2644 | 95.1% |
| ov_SC03_030 | 2423 | 1811 | 0 | 2425 | 2495 | 97.2% |
| ov_SC03_031 | 2449 | 1808 | 0 | 2452 | 2514 | 97.5% |
| ov_SC03_089 | 2524 | 1811 | 0 | 2531 | 2581 | 98.1% |
| ov_SC03_090 | 2542 | 1811 | 0 | 2550 | 2625 | 97.1% |
| ov_SC03_091 | 2556 | 1828 | 0 | 2564 | 2640 | 97.1% |
| ov_SC03_092 | 2515 | 1811 | 0 | 2527 | 2588 | 97.6% |
| ov_SC03_093 | 2528 | 1828 | 0 | 2532 | 2563 | 98.8% |
| ov_SC03_094 | 2519 | 1806 | 0 | 2525 | 2577 | 98.0% |
| ov_SC03_095 | 2440 | 1806 | 0 | 2443 | 2474 | 98.7% |
| ov_SC03_096 | 2437 | 1806 | 0 | 2440 | 2465 | 99.0% |
| ov_SC03_097 | 2538 | 1827 | 0 | 2545 | 2603 | 97.8% |
| ov_SC03_098 | 2516 | 1828 | 0 | 2519 | 2541 | 99.1% |
| ov_SC03_097 | 2540 | 1827 | 0 | 2547 | 2603 | 97.8% |
| ov_SC03_098 | 2517 | 1828 | 0 | 2520 | 2541 | 99.2% |
| ov_SC03_099 | 2489 | 1806 | 0 | 2492 | 2504 | 99.5% |
| ov_SC03_100 | 2524 | 1828 | 0 | 2528 | 2539 | 99.6% |
| ov_SC03_101 | 2488 | 1811 | 0 | 2492 | 2528 | 98.6% |
| ov_SC03_101 | 2490 | 1811 | 0 | 2494 | 2528 | 98.7% |
| ov_SC03_102 | 2473 | 1806 | 0 | 2476 | 2492 | 99.4% |
| ov_SC03_103 | 2497 | 1808 | 0 | 2500 | 2510 | 99.6% |
| ov_SC03_104 | 2549 | 1811 | 0 | 2556 | 2616 | 97.7% |
| ov_SC03_105 | 2451 | 1807 | 0 | 2458 | 2597 | 94.6% |
| ov_SC03_107 | 2291 | 1690 | 0 | 2374 | 2497 | 95.1% |
| ov_SC03_108 | 2403 | 1806 | 0 | 2403 | 2443 | 98.4% |
| ov_SC03_104 | 2551 | 1811 | 0 | 2558 | 2616 | 97.8% |
| ov_SC03_105 | 2452 | 1807 | 0 | 2459 | 2597 | 94.7% |
| ov_SC03_107 | 2298 | 1690 | 0 | 2381 | 2497 | 95.4% |
| ov_SC03_108 | 2404 | 1806 | 0 | 2404 | 2443 | 98.4% |
| ov_SC03_109 | 2409 | 1807 | 0 | 2411 | 2424 | 99.5% |
| ov_SC03_110 | 2443 | 1830 | 0 | 2443 | 2468 | 99.0% |
| ov_SC03_111 | 2480 | 1806 | 0 | 2483 | 2510 | 98.9% |
| ov_SC03_112 | 2448 | 1808 | 0 | 2450 | 2526 | 97.0% |
| ov_SC03_113 | 2443 | 1808 | 0 | 2446 | 2468 | 99.1% |
| ov_SC03_110 | 2444 | 1830 | 0 | 2444 | 2468 | 99.0% |
| ov_SC03_111 | 2482 | 1806 | 0 | 2485 | 2510 | 99.0% |
| ov_SC03_112 | 2452 | 1808 | 0 | 2454 | 2526 | 97.1% |
| ov_SC03_113 | 2445 | 1808 | 0 | 2448 | 2468 | 99.2% |
| ov_SC03_114 | 2391 | 1806 | 0 | 2393 | 2415 | 99.1% |
| ov_SC03_115 | 2434 | 1806 | 0 | 2436 | 2472 | 98.5% |
| ov_SC03_115 | 2436 | 1806 | 0 | 2438 | 2472 | 98.6% |
| ov_SC03_116 | 2402 | 1806 | 0 | 2405 | 2438 | 98.6% |
| ov_SC03_117 | 2478 | 1806 | 0 | 2484 | 2557 | 97.1% |
| ov_SC03_118 | 2565 | 1834 | 0 | 2566 | 2684 | 95.6% |
| ov_SC03_119 | 2562 | 1834 | 0 | 2563 | 2685 | 95.5% |
| ov_SC03_117 | 2483 | 1806 | 0 | 2489 | 2557 | 97.3% |
| ov_SC03_118 | 2570 | 1839 | 0 | 2571 | 2684 | 95.8% |
| ov_SC03_119 | 2569 | 1839 | 0 | 2570 | 2685 | 95.7% |
| ov_SC03_121 | 2406 | 1807 | 0 | 2408 | 2459 | 97.9% |
| ov_SC03_124 | 2594 | 1802 | 0 | 2614 | 2741 | 95.4% |
| ov_SC03_125 | 2533 | 1815 | 0 | 2545 | 2588 | 98.3% |
| ov_SC03_126 | 2402 | 1808 | 0 | 2402 | 2423 | 99.1% |
| ov_SC04_000 | 2477 | 1810 | 0 | 2486 | 2546 | 97.6% |
| ov_SC04_002 | 2515 | 1806 | 0 | 2519 | 2636 | 95.6% |
| ov_SC04_003 | 2442 | 1813 | 0 | 2445 | 2502 | 97.7% |
| ov_SC04_004 | 2472 | 1806 | 0 | 2474 | 2558 | 96.7% |
| ov_SC04_005 | 2509 | 1806 | 0 | 2515 | 2612 | 96.3% |
| ov_SC04_006 | 2431 | 1812 | 0 | 2433 | 2454 | 99.1% |
| ov_SC04_007 | 2502 | 1806 | 0 | 2506 | 2569 | 97.5% |
| ov_SC03_124 | 2597 | 1802 | 0 | 2617 | 2741 | 95.5% |
| ov_SC03_125 | 2534 | 1815 | 0 | 2546 | 2588 | 98.4% |
| ov_SC03_126 | 2403 | 1808 | 0 | 2403 | 2423 | 99.2% |
| ov_SC04_000 | 2477 | 1811 | 0 | 2486 | 2546 | 97.6% |
| ov_SC04_002 | 2517 | 1806 | 0 | 2521 | 2636 | 95.6% |
| ov_SC04_003 | 2443 | 1813 | 0 | 2446 | 2502 | 97.8% |
| ov_SC04_004 | 2475 | 1807 | 0 | 2477 | 2558 | 96.8% |
| ov_SC04_005 | 2511 | 1806 | 0 | 2517 | 2612 | 96.4% |
| ov_SC04_006 | 2432 | 1812 | 0 | 2434 | 2454 | 99.2% |
| ov_SC04_007 | 2503 | 1807 | 0 | 2507 | 2569 | 97.6% |
| ov_SC04_008 | 2402 | 1806 | 0 | 2402 | 2415 | 99.5% |
| ov_SC04_009 | 2428 | 1806 | 0 | 2431 | 2441 | 99.6% |
| ov_SC04_010 | 2405 | 1806 | 0 | 2406 | 2419 | 99.5% |
| ov_SC04_011 | 2519 | 1811 | 0 | 2525 | 2803 | 90.1% |
| ov_SC04_012 | 2401 | 1806 | 0 | 2402 | 2420 | 99.3% |
| ov_SC04_015 | 2541 | 1807 | 0 | 2552 | 2611 | 97.7% |
| ov_SC04_011 | 2520 | 1811 | 0 | 2526 | 2803 | 90.1% |
| ov_SC04_012 | 2402 | 1806 | 0 | 2403 | 2420 | 99.3% |
| ov_SC04_015 | 2545 | 1807 | 0 | 2556 | 2611 | 97.9% |
| ov_SC04_016 | 2402 | 1806 | 0 | 2404 | 2440 | 98.5% |
| ov_SC04_018 | 2702 | 1853 | 0 | 2702 | 2857 | 94.6% |
| ov_SC04_019 | 2694 | 1853 | 0 | 2694 | 2857 | 94.3% |
| ov_SC04_020 | 2519 | 1815 | 0 | 2531 | 2567 | 98.6% |
| ov_SC04_021 | 2401 | 1808 | 0 | 2401 | 2423 | 99.1% |
| ov_SC04_018 | 2707 | 1858 | 0 | 2707 | 2857 | 94.7% |
| ov_SC04_019 | 2703 | 1858 | 0 | 2703 | 2857 | 94.6% |
| ov_SC04_020 | 2520 | 1815 | 0 | 2532 | 2567 | 98.6% |
| ov_SC04_021 | 2403 | 1808 | 0 | 2403 | 2423 | 99.2% |
| ov_SC05_000 | 2407 | 1810 | 0 | 2410 | 2422 | 99.5% |
| ov_SC05_001 | 2483 | 1807 | 0 | 2488 | 2574 | 96.7% |
| ov_SC05_001 | 2485 | 1807 | 0 | 2490 | 2574 | 96.7% |
| ov_SC05_002 | 2431 | 1806 | 0 | 2434 | 2442 | 99.7% |
| ov_SC05_003 | 2417 | 1806 | 0 | 2418 | 2481 | 97.5% |
| ov_SC05_004 | 2431 | 1806 | 0 | 2433 | 2464 | 98.7% |
| ov_SC05_003 | 2419 | 1806 | 0 | 2420 | 2481 | 97.5% |
| ov_SC05_004 | 2433 | 1806 | 0 | 2435 | 2464 | 98.8% |
| ov_SC05_005 | 2439 | 1812 | 0 | 2440 | 2491 | 98.0% |
| ov_SC05_006 | 2424 | 1807 | 0 | 2424 | 2430 | 99.8% |
| ov_SC05_007 | 2434 | 1806 | 0 | 2439 | 2482 | 98.3% |
| ov_SC05_007 | 2436 | 1806 | 0 | 2441 | 2482 | 98.3% |
| ov_SC05_008 | 2443 | 1806 | 0 | 2445 | 2543 | 96.1% |
| ov_SC05_009 | 2410 | 1806 | 0 | 2414 | 2438 | 99.0% |
| ov_SC05_010 | 2452 | 1807 | 0 | 2456 | 2588 | 94.9% |
| ov_SC05_010 | 2454 | 1807 | 0 | 2458 | 2588 | 95.0% |
| ov_SC05_011 | 2397 | 1806 | 0 | 2398 | 2409 | 99.5% |
| ov_SC05_017 | 2661 | 1803 | 0 | 2672 | 2842 | 94.0% |
| ov_SC05_018 | 2552 | 1814 | 0 | 2565 | 2673 | 96.0% |
| ov_SC05_019 | 2401 | 1808 | 0 | 2401 | 2423 | 99.1% |
| ov_SC06_000 | 2540 | 1816 | 0 | 2543 | 2691 | 94.5% |
| ov_SC06_006 | 2424 | 1806 | 0 | 2425 | 2511 | 96.6% |
| ov_SC05_017 | 2672 | 1803 | 0 | 2683 | 2842 | 94.4% |
| ov_SC05_018 | 2553 | 1814 | 0 | 2566 | 2673 | 96.0% |
| ov_SC05_019 | 2403 | 1808 | 0 | 2403 | 2423 | 99.2% |
| ov_SC06_000 | 2543 | 1817 | 0 | 2546 | 2691 | 94.6% |
| ov_SC06_006 | 2425 | 1806 | 0 | 2426 | 2511 | 96.6% |
| ov_SC06_008 | 2501 | 1808 | 0 | 2507 | 2542 | 98.6% |
| ov_SC06_010 | 2472 | 1806 | 0 | 2477 | 2517 | 98.4% |
| ov_SC06_010 | 2473 | 1806 | 0 | 2478 | 2517 | 98.5% |
| ov_SC06_011 | 2417 | 1806 | 0 | 2421 | 2468 | 98.1% |
| ov_SC06_013 | 2407 | 1806 | 0 | 2408 | 2425 | 99.3% |
| ov_SC06_014 | 2418 | 1806 | 0 | 2420 | 2453 | 98.7% |
| ov_SC06_015 | 2412 | 1806 | 0 | 2412 | 2421 | 99.6% |
| ov_SC06_016 | 2455 | 1807 | 0 | 2457 | 2549 | 96.4% |
| ov_SC06_018 | 2543 | 1807 | 0 | 2550 | 2665 | 95.7% |
| ov_SC06_020 | 2469 | 1808 | 0 | 2470 | 2518 | 98.1% |
| ov_SC06_022 | 2518 | 1806 | 0 | 2526 | 2642 | 95.6% |
| ov_SC06_024 | 2536 | 1806 | 0 | 2542 | 2667 | 95.3% |
| ov_SC06_018 | 2547 | 1807 | 0 | 2554 | 2665 | 95.8% |
| ov_SC06_020 | 2472 | 1808 | 0 | 2473 | 2518 | 98.2% |
| ov_SC06_022 | 2523 | 1806 | 0 | 2531 | 2642 | 95.8% |
| ov_SC06_024 | 2541 | 1806 | 0 | 2547 | 2667 | 95.5% |
| ov_SC06_025 | 2453 | 1806 | 0 | 2458 | 2572 | 95.6% |
| ov_SC06_027 | 2392 | 1806 | 0 | 2393 | 2408 | 99.4% |
| ov_SC06_029 | 2479 | 1807 | 0 | 2491 | 2662 | 93.6% |
| ov_SC06_030 | 2414 | 1807 | 0 | 2414 | 2456 | 98.3% |
| ov_SC06_032 | 2524 | 1807 | 0 | 2531 | 2658 | 95.2% |
| ov_SC06_033 | 2526 | 1807 | 0 | 2533 | 2631 | 96.3% |
| ov_SC07_000 | 2436 | 1810 | 0 | 2438 | 2521 | 96.7% |
| ov_SC07_001 | 2406 | 1806 | 0 | 2408 | 2454 | 98.1% |
| ov_SC06_030 | 2415 | 1807 | 0 | 2415 | 2456 | 98.3% |
| ov_SC06_032 | 2534 | 1807 | 0 | 2541 | 2658 | 95.6% |
| ov_SC06_033 | 2531 | 1807 | 0 | 2538 | 2631 | 96.5% |
| ov_SC07_000 | 2438 | 1811 | 0 | 2440 | 2521 | 96.8% |
| ov_SC07_001 | 2406 | 1807 | 0 | 2408 | 2454 | 98.1% |
| ov_SC07_002 | 2465 | 1807 | 0 | 2469 | 2579 | 95.7% |
| ov_SC07_006 | 2330 | 1625 | 0 | 2410 | 2456 | 98.1% |
| ov_SC07_007 | 2341 | 1660 | 0 | 2425 | 2612 | 92.8% |
| ov_SC07_007 | 2351 | 1660 | 0 | 2435 | 2612 | 93.2% |
| ov_SC07_008 | 2386 | 1806 | 0 | 2386 | 2386 | 100.0% |
| ov_SC07_009 | 2398 | 1806 | 0 | 2400 | 2430 | 98.8% |
| ov_SC07_010 | 2323 | 1682 | 0 | 2405 | 2523 | 95.3% |
+46 -1
View File
@@ -181,7 +181,52 @@ stub on a named wall/behemoth/queue ledger** — 140/140 byte-identical througho
---
# 🛑 SESSION S50 CHECKPOINT (2026-08-13) — FRESH SESSION SAFE HERE
# 🛑 SESSION S50 CHECKPOINT — FINAL (2026-08-14) — FRESH SESSION SAFE HERE
> **Tree CLEAN** but for R23 `db.*.gbf` churn, a regenerable `.run/backlog.jsonl` edit, and two
> stray `gccdump.*` cc1 dumps at the repo root — never stage any of them. **Nothing running.**
> Gate: **`check-all` 213 passed / 0 failed of 213** from a CLEAN rebuild (R22 run **4x** this
> session, 213/213 every time).
> **Fleet: 95.3% instr · 90.0% distinct · 96.65% fn-count · INCLUDE_ASM stubs 12,161**
> (was 12,468). **307 instances banked**, ~all of them at **ZERO agent tokens**. dedup 2,043/0.
> Cookbook **§171 §171a**; §170's open hypothesis STRUCK. Decision-log filed (R31). SETUP rows.
## ✅ S50 SUMMARY — the A-prop lane, closed three ways
1. **§170's TU-collision hypothesis REFUTED** (see the S50 block below) — the cause was the
**stale seed symbol**, 24 of 24, and 23/24 banked after a mechanical rebase.
2. **The `func_801EDC18` carry blocker CLEARED** — 4/4, and re-priced from "83 members" to 4.
3. **`tools/aprop_autodraft.py` (§171a): 256 members banked with NO AGENT IN THE LOOP** — seed body
+ `symbol_map` + a minimal synthesized preamble. The same work as a wave would have cost ~20M
tokens. Plus `tools/draft_prechecks.py`, negative-controlled at zero false positives.
## ▶ RESUME HERE
1. **The A-prop pool is now priced EXACTLY** (open, by `classify_member`): **PURE 437 members /
37,376 ins** (autodraft's own remaining reach — blocked members are decl/def cases and the 90
whose `.s` carries data or a jtbl) · **IMM 275 / 8,849** (131 resolve mechanically via
`imm_map_tier1`; the rest need an edit) · **STRUCT 238 / 4,259** (register/opcode drift — the
only genuinely agent-shaped slice, and it is small).
2. **Autodraft's next reach, in cost order:** (a) the 90 data/jtbl members — carry the data
DEFINITION with the member's own bytes (the hand-built `func_801EDC18` fix is the template,
4/4); (b) the 48 "no definition after rename" and 61 "no seed decl" refusals; (c) the 144
unresolved-IMM members via T2a Tier 2.
3. **Still open from S49:** **`func_8017C294`** (x16, 246 ins, NEAR at 2). Its `.run/s43/wave/
8017CE58/NOTES.md` is a full byte-measured dossier: the residual is a **cse1 elision-count**
fact, the permuter floor is confirmed from BOTH basins, ~70 probes refuted. Do NOT re-grind it
blind — the one named lever left is a construct giving the MAX pass's operands a different RTL
address form from the MIN pass's.
4. **12 A-prop drafts are genuine `DIFF`** (11 singletons + `func_801659DC`) — redraft fuel.
## 🔑 THE ONE THING TO CARRY FORWARD
**Three runs launched at scale, three stopped early — and every stop was right.** The verdicts the
tools already write (`harvest_failed.<binary>.classified.txt`) named each defect within the first
handful of groups: a selector that drafted IMM/STRUCT members a rename cannot reach; a seed name
recovered by scanning for the first `func_XXXX(` (in a de-macroized block, that is a *callee
declaration*); a macro decl layer of 1,891 lines pasted into every destination. **Read the first
ten results of any long run before trusting the other 190** — and when a check is added to refuse
work, NEGATIVE-CONTROL it against everything that already succeeded. That control found two bugs
in my own pre-checks (C89 `f()` is UNSPECIFIED parameters, not zero; a definition read as a call
to itself), either of which would have silently discarded good drafts.
# ▶ (superseded by FINAL) SESSION S50 CHECKPOINT (2026-08-13)
> **Tree CLEAN** but for R23 `db.*.gbf` churn, a regenerable `.run/backlog.jsonl` edit, and two
> stray `gccdump.*` cc1 dumps at the repo root — never stage any of them. **Nothing running.**
> Gate: **`check-all` 213 passed / 0 failed of 213** from a CLEAN rebuild (`make clean &&
+36 -5
View File
@@ -29,6 +29,7 @@ import argparse, collections, glob, json, os, re, sys
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import aprop_symfix as ASF
import corpus
import draft_prechecks as PRE
import family_cousins as FC
import family_remap as FR
@@ -148,6 +149,13 @@ def build_draft(body, seed_name, member_name, renames, seed_text, dest_text,
old = next((k for k, v in renames.items() if v == s), s)
d = decl_for(old, seed_text)
if d is None:
# No decl in the seed — but if the DESTINATION already declares it, none is needed.
# Refusing here cost 55 macro-seeded members whose definition references a symbol the
# destination TU knows perfectly well (R32 should refuse the UNKNOWN, not the
# already-satisfied).
if re.search(rf'^[ \t]*(extern|const|static)?[^\n;]*\b{re.escape(s)}\b[^\n;]*;',
dest_text, re.M):
continue
missing.append(s)
continue
decls.append(re.sub(rf'\b{re.escape(old)}\b', s, d))
@@ -199,23 +207,46 @@ def main():
# (per-location literal) or a STRUCT (register/opcode drift) site needs a real edit, and
# drafting one spends a full binary build to learn what classify_member already knows —
# the first 5 such members gated 0/5, every one IMM or STRUCT.
cls, _pos = FR.classify_member(
seed_words, FR.stream_words(m["binary"], int(m["addr"], 16), c["nins"]))
if cls != "PURE" and not a.allow_impure:
skip[f"not PURE ({cls}: a rename cannot reach it)"] += 1
sib_words = FR.stream_words(m["binary"], int(m["addr"], 16), c["nins"])
cls, _pos = FR.classify_member(seed_words, sib_words)
if cls == "STRUCT" and not a.allow_impure:
skip["not templatable (STRUCT: register/opcode drift needs a real edit)"] += 1
continue
member_body, imm_map = body, {}
if cls == "IMM":
# T2a's immediate engine resolves a per-location LITERAL the same way symbol_map
# resolves a per-location symbol. Measured: 131 of 275 IMM members resolve with no
# unresolved sites — the rest genuinely need an edit.
imm_map, unresolved, member_body = FR.imm_map_tier1(body, seed_words, sib_words)
if unresolved and not a.allow_impure:
skip[f"IMM unresolved ({unresolved[0][1]})"] += 1
continue
if not imm_map and member_body == body:
skip["IMM with no resolvable literal edit"] += 1
continue
ren, err = FR.symbol_map(int(seed["addr"], 16), seed["binary"],
m["binary"], int(m["addr"], 16))
if err:
skip["symbol_map: " + err.split("(")[0].strip()] += 1
continue
dest = "".join(open(p).read() for p in sorted(glob.glob(f"src/{m['binary']}/*.c")))
draft, why = build_draft(body, sb.get("name") or seed["name"],
if imm_map:
member_body = FR.apply_remap(member_body, imm_map)
draft, why = build_draft(member_body, sb.get("name") or seed["name"],
m["name"], ren, seed_text, dest,
already_self_contained=False)
if draft is None:
skip[why.split(" for ")[0]] += 1
continue
# STATIC PRE-CHECKS (S50): both classes below were measured as real build failures and
# both are decidable without compiling. Negative-controlled against all 205 banked
# drafts of run 1: zero false positives; catches 39 of 67 known failures.
syms = ASF.syms_in_text(draft)
bad = (PRE.arity_conflicts(draft, dest, syms, self_name=m["name"])
+ PRE.undefined_data(m["binary"], dest, syms, self_name=m["name"], body=draft))
if bad and not a.allow_impure:
skip["pre-check: " + bad[0].split("(")[0]] += 1
continue
d = os.path.join(a.outdir, m["binary"])
os.makedirs(d, exist_ok=True)
p = os.path.join(d, m["name"] + ".c")
+118
View File
@@ -0,0 +1,118 @@
"""Static pre-checks that turn a BUILD-time draft failure into a GENERATION-time skip.
Every class here was measured as a real failure in the S50 autodraft runs, and every one is
decidable without compiling anything. That is the whole point: a build spent to learn something a
regex knows is a build wasted, and at ~1 min/group over ~100 groups the waste is the run.
1. ARITY DISAGREEMENT — `too few arguments to function 'func_80146C3C'`.
The destination TU already declares a callee with a different parameter count than the seed's
body passes. Neither emitting the seed's decl (conflicting types) nor relying on the
destination's (too few arguments) can work; the member needs a real edit.
2. UNDEFINED DATA — `undefined reference to 'D_801E9C44'`.
The draft references a symbol nothing in the DESTINATION binary defines. The seed's own data
symbol survived into the draft because it sits at no relocation slot symbol_map covers.
"""
import glob
import os
import re
def _decl_arity(text, sym):
"""Parameter count of the first declaration/definition of `sym` in `text`, or None."""
m = re.search(rf'^[ \t]*(?:extern\s+)?[A-Za-z_][\w \*]*\b{re.escape(sym)}\s*\(([^;{{)]*)\)',
text, re.M)
if not m:
return None
args = m.group(1).strip()
if args == '':
return None # C89: `f()` declares UNSPECIFIED parameters, not zero — never a conflict
if args == 'void':
return 0
return len([a for a in args.split(',') if a.strip()])
def _call_arity(body, sym):
"""Argument count at the first CALL of `sym` in `body`, or None. Depth-aware so a nested call
or a comma inside a cast does not miscount."""
m = re.search(rf'\b{re.escape(sym)}\s*\(', body)
if not m:
return None
depth, args, cur = 0, [], ''
for ch in body[m.end() - 1:]:
if ch == '(':
depth += 1
if depth == 1:
continue
elif ch == ')':
depth -= 1
if depth == 0:
args.append(cur)
break
if depth == 1 and ch == ',':
args.append(cur)
cur = ''
continue
if depth >= 1:
cur += ch
return len([a for a in args if a.strip()])
def arity_conflicts(body, dest_text, syms, self_name=None):
"""Symbols the body CALLS with an argument count the destination's own declaration refuses."""
bad = []
for s in syms:
if not s.startswith('func_') or (self_name and s.lower() == self_name.lower()):
continue # the member's own definition is not a call to itself
d, c = _decl_arity(dest_text, s), _call_arity(body, s)
# CONSERVATIVE by measurement: flag only when the destination declares NAMED parameters and
# the body passes fewer. Every true positive had that shape (`dest decl 1 vs call 0`) and
# every false positive the other one (`dest decl 0 vs call 1`) — where the `0` comes from a
# `(void)` my parser reads out of a declaration it should not have matched. A pre-check that
# throws away good drafts is worse than one that lets a few builds fail.
if d is not None and c is not None and d > c:
bad.append(f"{s}(dest decl {d} vs call {c})")
return bad
_DEF_CACHE = {}
def defined_in_binary(binary, sym):
"""True if `sym` is defined anywhere in the destination binary — its asm (a dlabel/glabel, or
a symbol file entry) or its C. Cached per binary: the asm scan is the expensive part."""
key = binary
if key not in _DEF_CACHE:
defs = set()
for p in glob.glob(f"asm/{binary}/**/*.s", recursive=True):
for m in re.finditer(r'^(?:dlabel|glabel|jlabel)\s+([A-Za-z_]\w*)', open(p).read(), re.M):
defs.add(m.group(1))
for p in glob.glob(f"config/symbols.{binary}*.txt"):
for m in re.finditer(r'^([A-Za-z_]\w*)\s*=', open(p).read(), re.M):
defs.add(m.group(1))
_DEF_CACHE[key] = defs
return sym in _DEF_CACHE[key]
def undefined_data(binary, dest_text, syms, self_name=None, body=""):
"""Referenced symbols nothing in the destination binary defines, and the destination TU does
not define locally either.
A symbol the DRAFT ITSELF defines is not undefined — its own function name above all, which
has no `glabel` left in asm precisely BECAUSE it is now C. Skipping that was 38 of 38 false
positives in the negative control."""
out = []
for s in syms:
if self_name and s.lower() == self_name.lower():
continue
if re.search(rf'^[^\n=;]*\b{re.escape(s)}\b[^\n;]*\)\s*\{{', body, re.M) or \
re.search(rf'^[ \t]*(?:const\s+|static\s+)*[A-Za-z_][\w \*]*\b{re.escape(s)}\b'
rf'(?:\s*\[[^\]]*\])?\s*=', body, re.M):
continue
if defined_in_binary(binary, s):
continue
if re.search(rf'^[ \t]*(?:const\s+|static\s+)*[A-Za-z_][\w \*]*\b{re.escape(s)}\b[^\n;]*[=;]',
dest_text, re.M):
continue
out.append(s)
return out