Commit Graph

256 Commits

Author SHA1 Message Date
Drew T bf15795e84 feat(decomp): worker gate — +3 fns x0 propagated (fleet 95.2%) 2026-08-14 02:07:17 -06:00
Drew T 05f924e9f2 feat(phase-30 S49): propagate func_8017DEA0 (adapt lane) 2026-08-14 01:37:37 -06:00
Drew T e3aadd9150 feat(decomp): worker gate — +10 fns x0 propagated (fleet 95.2%) 2026-08-13 23:33:39 -06:00
Drew T dc6bbf5983 feat(decomp): worker gate — +12 fns x0 propagated (fleet 95.2%) 2026-08-13 23:32:27 -06:00
Drew T 94818c30c2 feat(decomp): worker gate — +1 fns x0 propagated (fleet 95.2%) 2026-08-13 23:28:25 -06:00
Drew T a3d748faa5 feat(phase-30 S49): propagate func_80184374 (adapt lane) 2026-08-13 17:38:33 -06:00
Drew T 596afa1385 feat(phase-30 S49): propagate func_80183890 (adapt lane) 2026-08-13 17:38:23 -06:00
Drew T 4c13e9b379 feat(phase-30 S49): propagate func_80182A7C (adapt lane) 2026-08-13 17:38:13 -06:00
Drew T 894b51e0ae feat(phase-30 S49): propagate func_801811F4 (adapt lane) 2026-08-13 17:38:03 -06:00
Drew T 60f54c33da feat(phase-30 S49): propagate func_80180190 (adapt lane) 2026-08-13 17:37:54 -06:00
Drew T c23bc5ef8f feat(phase-30 S49): propagate func_80181538 (adapt lane) 2026-08-13 17:34:36 -06:00
Drew T 77bb2039c8 feat(phase-30 S49): propagate func_801E2AF4 (adapt lane) 2026-08-13 17:31:57 -06:00
Drew T ce64886855 feat(phase-30 S49): propagate func_801EF964 (adapt lane) 2026-08-13 17:29:26 -06:00
Drew T 3a5397c529 feat(phase-30 S49): propagate func_80180954 (adapt lane) 2026-08-13 11:42:04 -06:00
Drew T 9ae5c5b334 feat(phase-30 S49): propagate func_80182C24 (adapt lane) 2026-08-13 11:41:39 -06:00
Drew T b4b578e52d feat(phase-30 S49): propagate func_8018042C (adapt lane) 2026-08-13 11:41:29 -06:00
Drew T 5205be4118 feat(phase-30 S49): propagate func_80188990 (adapt lane) 2026-08-13 11:40:56 -06:00
Drew T c85fc8853b feat(phase-30 S49): propagate func_80188748 (adapt lane) 2026-08-13 11:40:37 -06:00
Drew T 5fc7f16978 feat(phase-30 S49): propagate func_8018B388 to its cousins (wave 7a) 2026-08-13 06:53:52 -06:00
Drew T dabd2d4cb7 feat(phase-30 S49): propagate func_80183838 to its cousins (wave 7a) 2026-08-13 06:52:50 -06:00
Drew T ad7ffe5e6e feat(decomp): worker gate — +1 fns x7 propagated (fleet 95.1%) 2026-08-13 04:36:57 -06:00
Drew T 7f82d95468 feat(decomp): worker gate — +1 fns x8 propagated (fleet 95.1%) 2026-08-13 04:34:15 -06:00
Drew T 49cf2dc15a feat(decomp): worker gate — +1 fns x17 propagated (fleet 95.1%) 2026-08-12 22:56:40 -06:00
Drew T 527c7ffa7d feat(decomp): worker gate — +1 fns x1 propagated (fleet 95.1%) 2026-08-12 22:51:00 -06:00
Drew T 63bb8f8959 feat(decomp): worker gate — +1 fns x36 propagated (fleet 95.1%) 2026-08-12 22:47:24 -06:00
Drew T 019fd51883 feat(decomp): worker gate — +1 fns x9 propagated (fleet 95.1%) 2026-08-12 22:22:06 -06:00
Drew T ce85242084 fix(phase-30 S47-0a.2): conform func_80175414 — 1,845 decls / 1,061 files; R22 213/213
The new head plumbing class after the symbol-kind fix: `conflicting types for func_80175414` (27
member-rows). Byte-true DEF is `void func_80175414(s32 _arg0)` (its DEFINE_ macro). The fleet
declared it 1,845 times in four spellings, of which three are the SAME TYPE (parameter names do not
participate) — the outlier was 28 sites declaring `(void)`.

conform_decls REFUSED the naive conform and was right to: 29 ZERO-ARG CALL SITES exist across 28
files, so conforming the declaration alone turns each into `too few arguments` — a fleet-wide
COMPILE break the per-binary gate cannot see (the tool cites 138/140 binaries, measured). It named
the count, the consequence, why the cheap check misses it, and the flag that repairs it, then
forced the two-step: --cast-zero-arg-calls (29 sites cast to the 0-arg fn-ptr shape, §17a-1 — gcc
folds the cast of a known symbol to a direct jal, so it is codegen-neutral), then the conform.

Result: 1,845 declaration sites rewritten across 1,061 files, 0 non-canonical remaining (axis
complete, R32). R22 clean-fleet: check-all 213 passed / 0 failed of 213.

WORTH RECORDING AS A TOOLCHAIN STANDARD: this is the instrument that has not wasted a cycle today.
Every other one reported SUCCESS over a defect — a classifier that discarded every gcc-2.7.2 hard
error (no `error:` prefix), a diff that miscounted 116 data-bundled .s files, a --verified-out
truncated to zero bytes over 62 real banks, a --band default that reported "0 families" on a real
135-member family, and a scope stamp describing the filesystem instead of the run. conform_decls
reports FAILURE with a repair path. A guard must state its COVERAGE, not just its verdict; the
in-repo exemplars are this tool and the §53 jr interlock.
2026-08-11 14:15:01 -06:00
Drew T 206b279ffc feat(phase-30 S47-F4): canonicalize the 2 incompatible memcpy decls (+29); the feared class was 2 lines
engine_core.h carried memcpy in 5 spellings across 9 macro-local declarations. SEVEN already agreed
in TYPE — only parameter NAMES differed, which does not conflict, and u32 IS unsigned int. Exactly
two were incompatible, and both are safe for reasons verified against the code, not assumed:

  * DEFINE_func_801325B8 declared `void memcpy()` — return type void against every draft's void*,
    which is the actual collision in ov_MAIN_012. Its only plain calls are `memcpy(dv, sv, n * 8)`
    with a VARIABLE size, which gcc cannot inline-expand, so it emits a library call under either
    prototype; the return value is discarded, so the return-type change is invisible.
  * DEFINE_func_801638A0 declared `(void *, void *, s32)` but NEVER CALLS memcpy — the body uses
    __builtin_memcpy, which is expanded directly and is unaffected by the declaration. Vestigial.

Both canonicalized to `extern void *memcpy(void *, const void *, u32);`. All 9 decls are now one
type. Gated byte-identical on ov_MAIN_012 and ov_SC03_099 BEFORE sweeping; 142 binaries instantiate
DEFINE_func_801325B8, so R22 is the real arbiter: check-all 213 passed / 0 failed of 213.

Sweep: banked +29, failures 699 -> 670.

The documented hazard (ov_MAIN_012.c:14333 — an `extern memcpy` turning an inlined block-move into
a CALL) is real but applies to a case neither macro has: a CONSTANT-size call under a
builtin-compatible prototype. The checkpoint's caution was correct; the danger just did not apply
to these two. Task B was right to defer this rather than sweep it blind.
2026-08-10 22:53:22 -06:00
Drew T 320a14921c fix(phase-30 S47): CdFileLoc_80128C98 aliases CdFileLoc — clears 136 sweep conflicts
`conflicting types for cdFileLocTable` was the single largest remaining propagation-sweep failure
class (136 of 875). Cause: engine_types.h defined the SAME layout twice —

    typedef struct { s32 word0; s32 word4; } CdFileLoc;
    typedef struct { s32 word0; s32 word4; } CdFileLoc_80128C98;

Each anonymous struct definition mints a DISTINCT C type, so a TU holding both
`extern CdFileLoc_80128C98 cdFileLocTable[]` (137 sites) and `extern CdFileLoc cdFileLocTable[]`
(9 sites) is declaring one object with two incompatible types. This is the same type-IDENTITY
collision scope_data_externs documents for S_AF634: no type-STRING compare can see it, and
cdecl.compatible correctly answers "compatible".

Fix is one line — `typedef CdFileLoc CdFileLoc_80128C98;` — so the two NAMES denote one type.
Byte-neutral by construction: identical layout, so indexing scales by the same 8 bytes either way.

NOT unified with the 3 `extern u8 cdFileLocTable[]` sites: element size drives index scaling and
those sites carry their own explicit `<< 3` (note at resident.c:656). Folding them in would change
codegen, which is exactly the memcpy-class trap.

Verified byte-identical on ov_SC01_077 and ov_SC03_099. Committed ahead of the re-sweep so the
sweep's per-member revert cannot undo it mid-run; fleet R22 lands with the sweep batch.
2026-08-10 20:36:33 -06:00
Drew T 9ab9120e04 feat(phase-30 S47-B): conform 8 declaration axes (~10,930 sites); 3 guard defects fixed; 213/213
Task B, re-scoped from evidence. The 129 dedup_extend failures are 106 conflicting-types /
21 CC1-FAIL / 4 undefined-ref / 3 DIFF — real byte divergence is 2%, and memcpy is 17 of 106,
not the story. Direction reversed too: the byte-true DEF of func_80128ED8 is what the target
.c files already declare; engine_core.h's macro-local extern was the stub-era guess.

Conformed 8 axes to byte-truth (func_8012F14C 2843, func_8012E5CC 2052, func_8012F038 2214,
func_8014C568 1816, func_80128ED8 1524, func_8012C750 406, func_8012C0EC 50, func_80144A04 25).
R22 clean-fleet: check-all 213 passed / 0 failed of 213. Zero functions banked by design.

Tooling (R33/R35) — three guards that asserted completeness over a narrowed population:
- NEW tools/macro_draft.py: a deduped fn has no definition in any .c (body lives in a DEFINE_
  macro), so conform_decls had been refusing the largest class it was built for.
- conform_decls skipped engine_core.h wholesale as "a defining TU": 10 stale externs survived
  while 1,514 fleet sites moved, and it still printed "axis complete". Skip now scoped to the
  defining macro's span.
- Return-axis compare was literal: typedef int/s32 and a missing `extern` faked a return change.
  Now compares normalized types.
- §85 consumer scan under-reported (the dangerous direction): a cast between `=` and the call
  hid `s0 = (s32 *)func_80144A04(...)`. Now classified by position, validated both ways.

Corrections to my own predictions (R14): the documented scalar-narrowing hazard was benign
across 2,052 sites; the breaks were arity (6 call sites, fixed with §17a-1 fn-ptr casts) and
the consumer-guard gap. A header-only first probe broke ov_SC01_000 — §85 is literal.

Not done, named: memcpy (builtin codegen), ApplyMatrixSV (no DEF), gte_SetRotMatrix (link bug),
func_80147364 (unparseable macro), D_800AE620/D_80126CC4 (data axis). Cookbook §159.
2026-08-10 16:01:49 -06:00
Drew T b005312127 feat(phase-30 S46-3): propagation banked — 29 fns / +2,815 member-instances; R22 213/213
The S45p9 blocker is closed, and the recovery loop that kept it from finishing is rewritten.

- BANKED: dedup_propagate --auto-from ov_SC02_037 --recover -> 29 functions propagated,
  141 overlays byte-identical, dedup 1920 -> 1949 groups, member instances 246,284 ->
  249,099 (+2,815). make clean && extract-all && check-all -> 213 passed / 0 failed (R22).
- WHY IT FINISHED THIS TIME: gate_all -> gate_failures returns EVERY failure from the sweep
  that already computed them, and the recovery loop resolves them all per round. Converged in
  3 rounds; the old one-overlay-per-sweep design needed ~138. That reframes the S45 run — it
  was not nearly done when it died, it had barely started.
- Batching did NOT cost capability: per-overlay necessity probes excluded four of the nine
  culprits from only the 9 overlays that needed it (not all 138), and ov_SC07_006 was
  RECOVERED by the Part-B caller-extern reconcile instead of excluded.
- Plan phase parallelised: 5 min -> 26 s, plan + skip classification byte-identical. Its
  compiles_standalone temp file is per-call now — the fixed `t.c` was the same fake-isolation
  class as match_one's shared --work dir (P28 T5), latent until something ran it in parallel.
- docs/accelerators.md (NEW, Drew 2026-08-07): the reusable-workflow ledger — what we learned
  late that a future decomp should know on day one, each entry with when we found it, when it
  WAS findable, what it cost, and the honest prerequisite where one exists.
2026-08-07 22:24:35 -06:00
Drew T fe946595fd fix(phase-30 S45p7): dedup_propagate leaves no orphaned reconcile on failure + func_8015C030 propagated x7
ROOT CAUSE of the 141/213 breakage earlier this session (correctly derived this time;
my first attribution to F1 was WRONG -- no arity journal ever touched func_80146A6C and
the arity undo reported success):

  dedup_propagate --recover's Part B reconciles a conflicting caller extern and
  DELIBERATELY leaves the edit on disk when it buys the byte-match ("keep the reconcile
  on disk"). Correct while the fn survives -- but a fn can still be dropped by a LATER
  iteration against a different overlay, and when the plan finally emptied, the
  "all candidates dropped" sys.exit fired with NO restore. Reconciles kept for
  ov_SC07_001..009 were orphaned: no-proto'd caller externs for functions that were
  never propagated -> ov_SC07_010 "passing arg 2 of func_80146A6C makes pointer from
  integer" -> 141 of 213 binaries failed check-all.

  The byte-gate never mis-banked (it fails closed). The real cost was VERDICT VOIDING:
  every subsequent gate reported "near" against the broken tree, so two whole batches
  (4/4 and 20/20) were mis-read as draft failures when they measured the tree (R35).

FIX: a reconcile LEDGER. Every kept reconcile is recorded against its fn, undone the
moment that fn leaves the plan, and ALL outstanding reconciles are restored before the
failure exit -- so a failed propagation leaves the tree exactly as it found it.

HONESTY: the fix is IMPLEMENTED AND REVIEWED BUT NOT YET PROVEN. The negative control
aimed at the exact failing propagation SUCCEEDED instead (different tree state), so the
guarded path never executed. A targeted test of the ledger is still owed.

Also lands the propagation that control performed: func_8015C030 x7 overlays
(func_80168B70 excluded from 4 SC07 overlays, survived elsewhere). check-all 213/213.
2026-08-07 18:49:56 -06:00
Drew T 9f61cd33c5 feat(phase-30 S6): BOTH GIANT WALLS CRACKED ×138 (+50,094 ins) — the verdicts were stale, not wrong
The two functions the roadmap has carried as PERMANENT WALLS since Phase 24 are matched in all 138
overlays. Neither needed a siege. Both matched from drafts ALREADY ON DISK.

  func_80178004  165 ins x 138 = 22,770   Phase 26: Fable5, ~477k tokens, "intrinsic 3-integer
                                          regalloc wall". THREE stored drafts report match_one
                                          MATCH today; one banked first try, no new work.
  func_801412A8  198 ins x 138 = 27,324   close=29/110 since Phase 24. Matched from 1 of 31 stored
                                          drafts + the §37/§124 alias.

WHY func_801412A8 LOOKED INTRINSIC (worth understanding — match_one is structurally blind to it):
the TU declares `extern int func_801412A8(int,int,int,int,int,int)` and its callers USE the return
(`param_1 = func_801412A8(...)`), while the byte-true definition is
`Prim_1412A8 *(Prim_1412A8 *, int, int, int, u16, u16)`. Narrow params cannot agree with an `int`
prototype and the no-prototype escape is illegal once a param promotes, so NEITHER side can move --
and the resulting byte difference is in the CALLERS, which match_one never compiles. The §37/§124
def-side asm-label alias decouples them: the TU decl keeps governing the call sites (codegen
untouched), the definition keeps its byte-true signature.

THEN PROPAGATION RETURNED 0/137 TWICE, both times a missing TYPE, not codegen:
  family_remap's `_carry_macros` carries file-scope #defines but (a) NOT typedefs, and (b) is NOT
  TRANSITIVE -- it brought addPrim_1412A8 and stopped, though that macro calls setaddr/getaddr and
  getaddr casts to PTag_1412A8. Lifted Env_1412A8 / PTag_1412A8 / Prim_1412A8 + OT/getaddr/setaddr
  into src/shared/engine_types.h (inside the include guard) -> 137/137, 0 failed.

MY ERROR, CAUGHT BY THE GATE: I lifted the typedefs but did not STRIP them from ov_SC01_077.c, so
they were declared twice and gcc-2.7.2 rejects a repeated typedef even when identical -- the lesson
already recorded at the foot of engine_types.h. R22 came back 139/140 with [FAIL] ov_SC01_077 (the
exemplar's own overlay). Stripped, re-verified, 140/140. A proper lift strips the source;
build_engine_types --strip does both and I did it by hand.

Also a measurement error worth recording: I checked whether the draft defined Prim_1412A8 with a
plain `grep -c` -- which matches inside `addPrim_1412A8` -- and briefly concluded the carry worked.
Substring false positive; the same shape as reading a `return` as a declaration.

VERIFIED: make clean && make extract-all && make check-all -> 140 passed, 0 failed of 140.
Fleet 12432941 -> 12483035 instr (+50,094 -- EXACTLY the two giants x138); fn-count +276;
instr-weighted 94.5% -> 94.8%. audit-digest OK. 0 NON_MATCHING (G4).

THE RULE THIS BUYS: re-measure a wall before respecting it, and SCAN every stored draft rather than
sampling (my first pass checked 8 of 31 and reported "closeness 40" for a function whose MATCH was
in the 9th). Four minutes of re-measurement was worth 50,094 instructions.
2026-08-05 12:51:06 -06:00
Drew T 85519f1e32 feat(phase-30 S39): propagate free h_exact class 0x8017d174 (8 ins x 1) - R22 140/140 2026-08-05 00:32:32 -06:00
Drew T 49a3efa14d feat(phase-30 S39): propagate free h_exact class 0x801880f8 (8 ins x 1) - R22 140/140 2026-08-05 00:28:41 -06:00
Drew T 7604e294f2 feat(phase-30 S39): propagate free h_exact class 0x80188f90 (8 ins x 1) - R22 140/140 2026-08-05 00:25:22 -06:00
Drew T c07ee02282 feat(phase-30 S39): propagate free h_exact class 0x80182bb0 (9 ins x 1) - R22 140/140 2026-08-05 00:21:32 -06:00
Drew T 8059ac8a53 feat(phase-30 S39): propagate free h_exact class 0x80182bd4 (10 ins x 1) - R22 140/140 2026-08-05 00:17:59 -06:00
Drew T e88eccac60 feat(phase-30 S39): propagate free h_exact class 0x8018625c (19 ins x 1) - R22 140/140 2026-08-05 00:13:15 -06:00
Drew T 638f97dbbb feat(phase-30 S39): propagate free h_exact class 0x80176144 (53 ins x 1) - R22 140/140 2026-08-05 00:09:28 -06:00
Drew T ff4bc60e09 feat(phase-30 S39): propagate free h_exact class 0x8017bee0 (10 ins x 6) - R22 140/140 2026-08-05 00:00:20 -06:00
Drew T c3bf1c988d feat(phase-30 S39): func_801758FC propagated x137 (+7,535 ins) — the largest free h_exact class
Measured the h_exact free pool from the bytes rather than trusting the frontier report's
numbers (R14 — its whale claim was 3/4 wrong: it said the whale was open in all four SC07
overlays; three were already banked and I closed the fourth earlier this session).

MEASURED: 215 open function-instances / 8,763 instructions are byte-identical (h_exact,
including reloc payloads) to an already-matched function. ONE class is 86% of that pool:

  func_801758FC — 55 ins, same address in all 138 overlays, matched in ov_SC01_000 only,
  OPEN in the other 137  =>  7,535 instructions.

h_exact means identical INCLUDING jal/lui/%lo reloc immediates, so the matched body compiles
byte-identically at every member with NO remap (dedup_extend's correctness argument, §14).
dedup_propagate --addr authored it once as DEFINE_func_801758FC() in engine_core.h and
instantiated it at all 137 open sites in address order.

  [ OK ] 138 overlays byte-identical after propagation; 1 new group in config/dedup.us.yaml

VERIFIED: make clean && make extract-all && make check-all -> 140 passed, 0 failed of 140.
Fleet instr 12411467 -> 12419002 = +7,535 EXACTLY; fn-count +137; instr-weighted crosses to
94.5%. distinct-code unchanged BY DESIGN -- the class was already matched in ov_SC01_000, so
the 137 add fleet instructions but no new DISTINCT function. audit-digest OK. 0 NON_MATCHING.

Note this function had been sitting in the stored-draft backlog for ov_SC06_030 and
ov_SC07_010 and re-gated "no" earlier tonight -- because gating a DRAFT is the wrong move for
an h_exact class. The right move is propagating the already-MATCHED body. Same function, two
routes, and only one of them is free.

Remaining free pool after this: 78 instances / 1,228 ins across 32 classes.
2026-08-04 23:56:15 -06:00
Drew T 7b5eda0424 feat(phase-30 S39/S4): re-gate probe — A10 broadly stands; 4 banked from the reverted overlays (+146 ins)
Tested whether decision-log A10 ("stored drafts re-gate at 0/958", measured in T1) survives
S38's tool repairs. Three populations, plain re-gate, no draft edits:

  fresh wave-6 drafts (diagnosed "blocked on a class")   4/6
  stored pool, unbiased sample (every 96th of 1,155)     1/12   <- hit was in a REVERTED overlay
  the two REVERTED overlays, targeted                    3/17

A10 BROADLY STANDS. ~8% on the general stored pool is not a harvest, and a 1,155-wide sweep
(= 1,155 whole-binary builds) is not justified by it. Do NOT generalise the fresh-draft rate
(4/6) onto the stored pool -- different populations. The honest rule is narrower and cheaper:

  after a tool repair, re-gate the drafts THAT DEFECT plausibly touched, targeted by its
  blast radius -- not the whole ledger. (R35 applied to the backlog, not just to metrics.)

BANKED (+146 ins): ov_SC06_030 func_80161208 + func_80162CCC; ov_SC07_010 func_801506A4 +
func_8016F0AC. R22 clean-fleet 140 passed, 0 failed of 140 -- which also proves byte-neutral a
fleet-shared engine_core.h edit the bank required (extern s32 func_801506A4(s32,s32) -> the
no-prototype form), reaching all 138 overlays (T2 blast radius).

Fleet 12410129 -> 12410275 instr; distinct +95 / +1 uniq; fn-count +4. audit-digest OK.

Also documents the LEDGER MECHANICS in calibration.md (Drew asked): .run/backlog.jsonl is
append-only and nothing is deleted on bank -- open-ness is DERIVED from corpus.stubs at every
read (load_best drops now-banked rows per-binary, P9) and `make report` runs `backlog.py prune`.
Membership is therefore self-maintaining and currently clean: 863 rows, 0 already-banked, 14
duplicate-addr (was 6,867 rows / 98% banked before Phase-29 compaction). What pruning does NOT
re-validate is the VERDICT on surviving rows -- closeness + residual class are as old as the
tooling that wrote them (Phase 28 found a corrupt one: func_80178004 close=0 -> 91). That is
the staleness that matters, and it is exactly what this probe measured.
2026-08-04 22:42:54 -06:00
Drew T c57860db4e feat(phase-30 S38/S1a): lift 895 local types to engine_types.h — kills the type-scope sweep class
The free-sweep "wall" was a C parse error: a remapped member body names the EXEMPLAR's TU-local
types, which are undeclared in the sibling's TU, so gcc-2.7.2 parses the declarator as an expression
and dies before ever reaching codegen. extract_unit does carry typedefs, but only ones immediately
preceding the function in the preamble — types declared elsewhere in the exemplar's TU are missed.

Rather than patch the scanner per-family, remove the class: lift every liftable local type into the
shared header once. 895 types lifted, 6,196 local definitions stripped across 1,259 files.
R22 clean-fleet 140/140.

EXCLUDED s8/s16/s32/u8/u16/u32/f32/s64/u64/f64 — lift_types classified those common.h scalars as
liftable and lifting them would have been actively harmful. The tool's own visibility guard kept 8
local defs in src/ov_SC01_077/ov_SC01_077_o0.c, which does not include engine_types.h (stripping a
type out of a TU that cannot see the replacement DELETES it, and the link error that follows names
an unrelated data symbol).

Mechanism proven before scaling: lifting just 3 types took 0x801833f0's family from 0/6 to 6/6.
2026-08-04 18:46:30 -06:00
Drew T 91bb3ac76b feat(phase-30 S38): the free-sweep "wall" was a TYPE-SCOPE parse error — 0/6 becomes 6/6
family_sweep --hseq returned 0/6 on 0x801833f0 (328 ins, PURE, matched exemplar) and I recorded it
as evidence that h_seq families do not template. It was a C PARSE ERROR: the remapped member body
carries the EXEMPLAR's TU-local type names (PTag_801833F0 / Ft4_801833F0 / Drm_801833F0), which are
declared only in ov_SC02_028's TUs. Undeclared type -> gcc-2.7.2 parses the declarator as an
expression -> "parse error before `vtx'" two lines later. Never reached codegen.

Lifting the three types to src/shared/engine_types.h (lift_types --apply; each had ONE canonical
definition, no variants) turns the same sweep into 6/6 banked. R22 clean-fleet 140/140.

This is the §20 propagation cap resurfacing on the h_seq sweep path, where nobody had checked for it.

MY ERROR, RECORDED (R37/R14): I claimed in the S38 checkpoint and in commit commit:1410 that
"family_sweep reports banked/failed WITHOUT the per-member build error". That is FALSE. There are
23,211 .run/hseq_failed.*.classified.txt files on disk; the diagnosis for BOTH of today's zeros was
written by the sweep itself at probe time (0x80128c98's says "PLUMBING: conflicting types for
`cdFileLocTable'"). I asserted a tool limitation without checking for it, and then spent two probes
plus a manual --stage-only round rediscovering what was already in a file. Probe before costing.
2026-08-04 18:36:04 -06:00
Drew T b497ee1649 feat(phase-30 S33c): PROPAGATE head COMPLETE — func_801466F0 x137 took three fixes + a type-lift
Fleet 96.17 -> 96.21% fn-count / 93.8% instr / 88.0% distinct; dedup 1909 -> 1910
groups, 0 failed, C1 241216/241216. R22 clean-fleet: 140 passed, 0 failed of 140.

The head is now 5/5 classes, 18,545 templatable ins, all banked this session from
a standing start of 0.

func_801466F0 had sat since S6b behind THREE separate blockers, each of which
looked sufficient on its own to explain the failure:
 1. Its definition is under a §37/§73 ASM-LABEL ALIAS (`aF801466F0` in C, bound to
    the real symbol by `__asm__`), and dedup_propagate.find_site anchored its head
    regex on the literal `func_<ADDR>` — structurally blind to the form, returning
    None, which every caller reads as "not matched". Now reuses
    family_remap._alias_decl_for rather than growing a second matcher (R33).
 2. That matcher was itself blind to the WRAPPED (multi-line) declaration — the
    §134 shape, third tool. Fixed by matching over the joined text and mapping the
    offset back to the decl's FIRST line (extract_unit carries from there).
    Regression control: the single-line form still resolves. Fleet census after:
    2,768 of 2,768 alias sites resolve, 0 missed.
 3. Its record type was a draft-local typedef, so the body failed
    compiles_standalone. Lifted Rec801466F0 to src/shared/engine_types.h INSIDE
    the include guard (the SESSION-19 double-include note) and switched both the
    macro and the exemplar to it — byte-neutral, gate-proven.

Probed on ONE member before the fleet run: byte-identical 9052dc0e first try.

MEASURED, NOT INHERITED (R37): the S6b note frames the alias-regex gap as a CLASS
of missed work. It is ONE function — 91 distinct alias decls fleet-wide, the
per-line matcher resolved 90. Recording it so a future session does not scope a
phase against a class that does not exist.

cookbook §138 extended with the alias-form tool boundary and the three-blocker
story; index regenerated.
2026-08-04 00:44:33 -06:00
Drew T 4f6b0e8de1 feat(phase-30 S33b): PROPAGATE head 82% banked — 15,257 of 18,545 ins, four levers
Fleet 96.10 -> 96.17% fn-count / 93.7 -> 93.8% instr / 88.0% distinct.
dedup 1908 -> 1909 groups, 0 failed, C1 241078/241078.
R22 clean-fleet: 140 passed, 0 failed of 140.

  func_80147364  4,110  x137  definition-side asm-label alias
  func_8016BA68  3,886  x134  dedup_extend + the MIRROR decl relax
  func_8012F274  3,973  x136  hand-authored macro, source overlay excluded
  func_8012A598  3,288  x138  cdecl._mask backscan fix + shared-type switch
  func_801466F0  3,288  OPEN  the wrapped-alias regex — measured as ONE function

THREE DISTINCT CARRY VARIANTS were hiding in one "CARRY-FIXABLE" bucket, and
only one is a tool bug (-> cookbook §138):
  - a MULTI-LINE comment halts the preamble backscan -> fix the tool (cdecl._mask)
  - a draft-local `struct Tag {…}` -> switch the exemplar to the SHARED type
  - a file-scope `static inline` helper -> hand-author, EXCLUDE the source overlay
The third is the sneakiest: gcc-2.7.2 accepts implicit function declarations, so
the extracted body PASSED compiles_standalone with the helper undeclared and the
miss surfaced only as a whole-binary byte DIFF 137 gates later. Instantiating
that macro in the SOURCE overlay is a duplicate definition (its file-scope helper
is still there), so the shape is `--source-overlay X --binaries <all-but-X>`;
`--binaries` alone removes the source from the scan pool and errors.

TOOL BOUNDARY: once a group's members are DEFINE_func_*() sites, dedup_propagate
cannot extend it (find_site never returns a `def`). dedup_extend is the tool for
an already-macro-ized group — and `dedup_extend --check-only` across ordinary
overlays is a cheap fleet-wide wiring census (measured: exactly 1 group per
overlay, so no hidden backlog).

MEASURED, NOT INHERITED (R37): the S6b note frames _alias_decl_for's single-line
regex as a CLASS of missed work. It is not — 91 asm-label alias decls exist
fleet-wide, the regex matches 90, and the single miss is func_801466F0. Worth
3,288 ins, but a one-function fix. Correcting the expectation so a future session
does not scope against it.
2026-08-04 00:30:56 -06:00
Drew T 356373efab fix(phase-30 S33b): the PAIR rule — my 42-decl relax did NOT unblock the lane; the mirror form did
HONEST CORRECTION to commit:1382. That commit's message implies the 42 `(void)`
relaxes unblocked the PROPAGATE remainder. They did NOT: the re-run banked 0/1
in all 134 overlays with the same error, because DEFINE_func_8016BA68 declares
func_80146C3C `(u8*)` — the MIRROR of the EXTEND-lane pair — and my relax only
touched the `(void)` direction.

Root cause is the R37 shape a third time: I bucketed by SYMBOL and stopped. The
lever is set by the (macro-shape, TU-shape) PAIR, and the same symbol conflicts
in BOTH directions across this fleet. One awk over the macro I was ACTUALLY
fixing — which I ran for the EXTEND macros and not for this one — shows the pair
before a 134-build run. §138 amended with the PAIR rule; correction logged in
CURRENT_PHASE.md rather than rewritten out of history.

The 42-decl relax still stands: byte-neutral, R22 140/140, removes a real
conflict class. It just did not do what I predicted.

THIS commit relaxes the 2 remaining `(u8*)` decls (uses are cast; `()` is
compatible with the (void)/()/(u8*) forms the fleet carries and no decl of this
symbol has a default-promotion param). R22 clean-fleet: 140 passed, 0 failed.

ALSO: tools/overlay_src_split.py `_split_macro_body` — the §134 sweep's one real
target, fixed. It carried the identical single-line-only comment test, and it
decides where a macro body's file-scope externs END, so a multi-line comment
truncated the extern set. SIZED FIRST: 38 live lines in engine_core.h macro
bodies hit it today. Now decides on cdecl._mask (one oracle, R33) with the
length-preservation invariant asserted (R32). Proven both directions by a
control: pre-fix it stopped at `/* multi` carrying 1 of 2 externs and treated the
comment as the definition head; post-fix both externs carry and the def head is
correct. Not in the gate path (only o0_subsplit + jr_isolate_all import it).
2026-08-04 00:16:23 -06:00
Drew T 7a6a09379f fix(phase-30 S33b): relax all 42 func_80146C3C decls — the PROPAGATE remainder is the SAME symbol
Diagnosed the 11,147-ins PROPAGATE remainder with one probe, in §138's order:
1. ONE COMMAND, NO BUILD: the originals of BOTH 0x8016BA68 and 0x8012F274 are
   sha1-identical across ov_SC07_006 / ov_SC06_025 / ov_SC01_000 / ov_SC01_077 /
   ov_SC03_001 -> the registry is sound; the cause is TU context.
2. ONE BUILD in an excluded overlay named it: `conflicting types for
   func_80146C3C` — the SAME symbol as the EXTEND lane, same (void)-vs-(u8*)
   shape, same one-token lever. The 137 [exclude] lines were one declaration.

Relaxed the remaining 42 `extern void func_80146C3C(void);` in engine_core.h to
`()`. Measured safe BEFORE editing (§138): every fleet decl of the symbol is
`(void)/()/(u8*)/(u8 *a0)` — no default-promotion param anywhere, so gcc-2.7.2's
`()` rule cannot bite — and every use in the header is a no-arg call or already
cast, so it is codegen-neutral. R22 clean-fleet: 140 passed, 0 failed of 140.

TOOL BOUNDARY worth recording: `dedup_propagate` CANNOT finish this one. The 4
SC07 members are now `macro` sites, so `find_site` never returns a `def` and the
auto-source scan errors with "no source overlay has it matched". Extending an
already-macro-ized group is `dedup_extend`'s job. Probe: exactly 1 extendable
group per ordinary overlay — so the fleet has no hidden wiring backlog beyond
this function (a useful negative, R32-shaped).

Also logged: the §134 scanner sweep is sized and has ONE real target —
tools/overlay_src_split.py:345 (_split_macro_body) carries the identical
single-line-only comment test, and it decides where a macro body's file-scope
externs END, so a multi-line comment there silently truncates the extern set.
The other scanners in that file track block-comment state; split_src_region.py
and family_remap.py already handle the multi-line form.
2026-08-04 00:11:42 -06:00
Drew T 62042f65ca fix(phase-30 S11): multi-line-comment blindness in dedup_propagate; func_8012A598 x138
Fleet 96.06 -> 96.10% fn-count / 93.7% instr / 88.0% distinct; dedup 1907 -> 1908
groups, 0 failed, C1 240807/240807. R22 clean-fleet: 140 passed, 0 failed of 140.

func_8012A598 (3,288 templatable ins) was being written off as CARRY-FIXABLE.
It took TWO fixes; either alone leaves it skipped.

1. TOOL (R33) — find_site's preamble backscan. The SESSION-18 fix handled blank,
   `//`, and SINGLE-LINE `/* … */` lines, but a MULTI-LINE block comment still
   halted the walk: its middle lines start with `*` and its last line ends `*/`
   without starting `/*`. So the three externs above the body were dropped and
   the body then failed compiles_standalone on now-undeclared data. This is the
   §134 multi-line-blindness class — S6b fixed the identical shape three times in
   family_remap (D1/D2/D5) and this copy was never reached.

   Fixed by deciding skippability on `cdecl._mask` — the project's ONE masking
   oracle — instead of on line syntax: it subsumes every comment form at once and
   cannot be fooled by a `/*` inside a string, with an R32 assertion on the
   length-preservation invariant it rests on. Strictly monotone (it can only
   carry MORE preamble), and dedup_propagate is a byte-gate feeder, so a bug here
   can fail to bank but never falsely bank.

2. EXEMPLAR — the body also declared a draft-local `struct BigCopy164` tag, which
   the tool refuses by design (two macros defining one tag would redefine it in a
   single TU). The shared `struct BigCopy` (engine_types.h L312) is the identical
   layout and is ALREADY used this exact way at engine_core.h:16158, so switching
   the exemplar to it is byte-neutral and drops the alias too.

Probed on ONE member before scaling (R37/S29): byte-identical 9052dc0e first try;
then 138 overlays byte-identical.

PROPAGATE head accounting after this: 7,398 of 18,545 ins banked (func_80147364
4,110 + func_8012A598 3,288). Still open, each with a NAMED cause and none yet
diagnosed against a build: func_8012f274 (3,973, dropped), func_8016ba68 (3,886,
4/138), func_801466f0 (3,288, the S6b D4 wrapped-alias gap).
2026-08-03 23:53:50 -06:00