Commit Graph

162 Commits

Author SHA1 Message Date
Drew T 22af9ab2c5 feat(phase-29): 3 Vec8-freed cores ×138, R22 140/140 — and the honest ROI verdict on the cap
- Propagated 0x8012A464 / 0x8014FFDC / 0x801502EC -> 138/138 byte-identical, 0 stragglers, 3 new
  groups. R22 clean-fleet 140/140; dedup 1872/0; C1 237654/237654.
- FINDING (R14/R31): the §20 propagation cap was gating source-level DE-DUPLICATION, not coverage.
  The whole uniquify campaign (Buf+MATRIX+Vec8, 223 files renamed, ~1559 copies stripped, 5
  propagations, 4 R22 cycles) moved the fleet by +6 functions / +558 ins / -6 stubs and 0.00pp on
  all three headline metrics. The freed cores' members were ALREADY matched individually;
  propagation just consolidated them into shared macros. "Unblocked" != "unmatched".
- SESSION ATTRIBUTION: of -837 stubs / +0.3pp instr / +0.23pp fn-count, -831 stubs came from the
  FIRST batch (broad lift -> 13 cores). The uniquify campaign contributed -6.
- Roadmap B4 re-labelled: a maintainability item, not a coverage lever. Remaining camps
  (Handler/Blk8/V8/Prim/Prim_8016E7C8) are small and now known low-yield — opportunistic only.
- distinct-code sat at EXACTLY 3811442/5634875 = 67.6% at open and close. Fresh cracks are the sole
  mover of that number; point the next session there.
2026-07-23 21:25:39 -06:00
Drew T e393c320e6 feat(phase-29): VARIANT camps -> UNIQUIFY (not reconcile); validated on Buf, R22 140/140 (§64a)
MEASUREMENT CORRECTED THE PLAN. The checkpoint called for a "per-camp field-access reconcile";
measuring the camps refutes that: Vec8 = {s32 w[8]} (32B) in 180 files AND {s16 unk0..} (8B) in
139 files; MATRIX 48B/32B/32B; Buf 16B / 0x20+ / DrawEnv. These are DIFFERENT types sharing an
identifier across TUs of the same overlay — reconciling to a canonical layout MERGES them, the
same failure that broke 103 binaries on Prim. The right op is UNIQUIFY: rename the non-majority
camp (byte-neutral — a type name emits no code; TU-local by construction), which makes every camp
single-def and liftable by the existing lift_types rules.

- NEW tools/uniquify_type.py: deterministic camp ordering (file-count desc, then normalized text,
  so re-runs assign the same suffixes); majority keeps the name, camp n -> <T>_c<n>; rewrites ONLY
  files that DEFINE that camp (a file that merely USES the name gets it elsewhere and is untouched);
  \bT\b word boundaries so `Buf` never matches `Buf80153978`.
- VALIDATED on Buf (578/6/1 files): 11 identifiers across 7 files -> 3 camps LIFTABLE -> lifted
  (585 local copies stripped) -> R22 140/140 -> blocked core queue 13 -> 11 (0x8012ea90, 0x801749c8
  freed). Propagated 0x8012EA90 ×138; 0x801749C8 dropped (straggler in ov_SC07_006).
- YIELD, HONESTLY (P9): ZERO new matched functions. fn-count 88.61% / instr 79.3% / stubs 40281 all
  UNCHANGED; dedup 1867->1868, C1 +138. 0x8012EA90's members were ALREADY matched in all 138
  overlays — the propagation consolidated duplication into one shared macro (DRY), not coverage.
  The value is the PROVEN RECIPE + the queue moving 13->11, not the numbers.
- dedup_propagate (R32): the skip line printed a COUNT and no names, and aggregated three unrelated
  causes into n_local — a body skipped merely for a `//` comment (macro-unsafe, 1-line fix) read
  identically to one genuinely using an overlay-local type. Now named and split by cause.
- cookbook §64a (uniquify-vs-reconcile + the validated recipe + remaining camps by cost).
2026-07-23 20:51:42 -06:00
Drew T 3642b5458a feat(phase-29): the type-lift's payoff — 13 cores propagated ×138, −831 stubs, R22 140/140
With the §20 local-type cap lifted (commit:0863), dedup_propagate --auto-from planned 17
self-contained cores that were previously skipped "not self-contained (local types)".

- BANKED: 12 cores via --auto-from + func_80175308 (propagated separately, 138/138) = 13 ×138.
  func_80175308 is the PROVABLE unblock — the core the SESSION-13 checkpoint named as
  local-type-blocked. No claim is made that all 17 were unblocked by the lift; measuring that
  needs a pre-lift re-scan I did not run (P9).
- 5 correctly DROPPED as cross-overlay stragglers (0x8012A018, 0x80172C50, 0x80173A60,
  0x80144090 in ov_SC01_000; 0x801495C4 in ov_SC07_006): h_exact sharing is all-or-nothing and
  those overlays' bytes diverge. --recover NOT used (the documented quadratic thrash hazard).
- GATES: R22 clean-fleet 140/140 BYTE-IDENTICAL (2nd full cycle this session); make report green;
  dedup-check 1854 -> 1867 validated / 0 failed, C1 236964/236964; 0 NON_MATCHING (G4).
- FLEET: instr 79.0 -> 79.3% | fn-count 88.38 -> 88.61% | INCLUDE_ASM stubs 41112 -> 40281 (-831).
  distinct-code stays 67.6% — correct: propagation replicates already-distinct-matched code;
  only a fresh crack moves that number.
- STILL BLOCKED: 13 cores "not self-contained (local types)", blocked by exactly the 8 deferred
  VARIANT entities (MATRIX 3-def, Buf 3-def, Vec8, Prim, Handler, Blk8, V8, Prim_8016E7C8).
  Next lever = a per-camp FIELD-ACCESS RECONCILE, not a lift (lifting them blindly is what broke
  103 overlays earlier this session).
2026-07-23 20:18:50 -06:00
Drew T 0eb22e10ae docs(phase-29): SESSION-13 type-lift addendum — §20 cap partially cracked (+276), lift_types.py doctrine; fleet 79.0% instr 2026-07-23 18:19:41 -06:00
Drew T 09bc2c7b72 docs(phase-29): SESSION-13 CHECKPOINT — 15 reach-138 cores banked + 2×138; integration-wall finding + build_engine_types as next lever; fleet 78.9% instr 2026-07-23 17:17:18 -06:00
Drew T 3c8fd8a0b0 feat(phase-29): ov_SC07_006 fresh-138 wave — 7 x1 core banks (gate_stage reconcile)
Crack wave w9lidyi5b (24 fresh LIVE=138 families): 20 self-assessed MATCH, 3 near.
Banked x1 (R22 clean-fleet 140/140):
- 2 self-contained via plain harvest_verify: func_8012B4B8 (§52b-wall crack),
  func_80169228.
- 5 via gate_stage's reconcile ladder (cast_call_sites in the draft's own TU):
  func_80175308, func_8012E138, func_80130C08, func_8012A1BC, func_80137178.

Correction (decision-log follow-up): fix_header_decl v1/v2 is FRAGILE for shared
multi-caller decls — rewriting an engine_core.h decl breaks callers that use the
return differently (CC1-FAIL). func_8014CD80 was a lucky single-caller/ignored-return
case. gate_stage's call-site-cast is the right tool for multi-caller plumbing (banked
5 where fix_header_decl broke the build). Remaining ~13 near/deeper-plumbing drafts
staged in .run/drafts-sc07006-fresh/. Propagation x138 next.
2026-07-23 13:55:29 -06:00
Drew T 7f18dbad2f feat(phase-29): func_8014CD80 x138 — the fresh-138 def-side blocker is RECOVERABLE (R35 reversal)
Bounded probe (SESSION-13, token-free) that REVERSED the same-session "fresh
reach-138 well is spent" verdict. Target func_8014CD80: 138 live, 0 matched, NO
DEFINE macro, a universal body (only universal callees + param offsets, zero
overlay-local D_* refs), clean MATCH draft from batch-1.

- Blocker was a def-side header decl: engine_core.h DEFINE_func_8014CD0C()
  forward-declares it `void func_8014CD80(s32,void*,void*)` while the byte-true
  def is `int func_8014CD80(s32,u16*,u16*)`. gate_stage's arity pre-pass is
  param-COUNT-only (misses return/ptr-type); §54 reconcile_def_sig fixes the
  wrong direction.
- One byte-neutral header edit (void->int, void*->u16*; call site passes u16[3]
  arrays + ignores the return -> codegen unchanged) -> harvest_verify banked x1
  BYTE-IDENTICAL -> dedup_propagate --addr propagated 138/138 overlays
  byte-identical (live 138->0) -> R22 clean-fleet 140/140.
- Fleet 78.7->78.8% instr, 88.22->88.26% fn-count from this one family;
  tools-health green (dedup 1851/0).

Quantified market (decision-log 2026-07-23): of the 75 fresh (>=100-live)
families, 46 carry an engine_core.h caller forward-decl, 38 SIMPLIFIED = the
func_8014CD80 pattern -> each a candidate x138 (~+1.5-2.8pp instr). NEXT: build
tools/fix_header_decl.py + a fresh-family wave. func_80165CA0's 0/135 was a
non-universal BODY (different failure mode), not this blocker.
2026-07-23 12:06:26 -06:00
Drew T 57ef4ebcb5 feat(phase-29): ov_SC07_006 reach-138 batch-1 propagation + live-count re-scope (SESSION-13)
Propagation of the 6 batch-1 x1 banks (§55b: banks committed first in commit:0848,
then targeted propagate as a standalone step):

- dedup_propagate --addr: func_801325B8 -> +3 onboarded-tail siblings
  (ov_SC07_007/010/011). func_8014A048/func_801678F0 byte-diverge in the SC07
  cluster (kept x1); func_8014FE60/func_80167540 local-type-blocked §20 (x1).
- func_80165CA0: consolidated its h_exact subgroup (dedup group registered, +0
  new), then family_sweep --hseq 0/135 — a PER-MEMBER WALL (cf func_80133AB0
  0/136). The x135 "fresh family" prize does not exist here.
- Net batch-1 yield ~9 newly-matched functions; fleet 78.6->78.7% instr, distinct
  flat; ov_SC07_006 84.6->84.8%. R22 clean-fleet 140/140; tools-health 1850/0.

The finding (R14/R35, decision-log 2026-07-23): nins*reach leverage over-counts —
rank by LIVE-siblings. build_wave_args.py --rank live now ranks by the true lever
and reports the fresh(76)/onboarded-tail(44) split. The reach-138 family well is
largely SPENT via wave+gate; the fresh families are the hard tail (def-side
plumbing/DIFF/per-member walls), not free x138 fuel.
2026-07-23 11:43:28 -06:00
Drew T b76ad85157 feat(phase-29): ov_SC07_006 reach-138 crack-wave batch-1 — 6 x1 banks
Option (b) from the SESSION-12 checkpoint: fresh-exemplar crack-wave on the
P27-onboarded ov_SC07_006 (84.6% -> 84.8%). New reusable builder
tools/build_wave_args.py emits wave_binary.js args from a fuel manifest.

- Drafting wave (wave_binary.js, 24 xHigh drafters over the top-24 reach-138
  WAVE families by leverage): 16 self-assessed MATCH, 8 hit the session usage
  limit (redraft later).
- Byte-gate: plain harvest_verify banked 2 (func_801325B8, func_80165CA0);
  gate_stage reconcile ladder (arity pre-pass + cast/sig_unify) banked +4
  (func_8014FE60, func_8014A048, func_801678F0, func_80167540). 7 near, 6
  reconcile-fail, 2 CC1-FAIL, 2 DIFF (the incomplete session-limit drafts).
- R14/R35 leverage reality-check: nins*reach over-counts. 5 of 6 are already
  matched in ~135 overlays (only the onboarded SC07 tail ov_SC07_007/010/011
  is live, +2-3 each). func_80165CA0 is a TRUE fresh family (135 live) — the
  x135 sweep prize, propagated next.
- R22 clean-fleet 140/140 (engine_core.h arity edit fleet-safe); tools-health
  green (dedup 1849/0). Propagation is the next commit (§55b: banks first).
2026-07-23 10:51:36 -06:00
Drew T e945933364 feat(phase-29): ov_SC06_018 non-jtbl wave batch-2 partial (5 x1 + 21 swept = 26 instances)
- batch-2 hit a usage limit mid-drafting (5 of 25 completed, all 5 MATCH); the 5 whole-
  binary banked via gate_stage --src-file, swept 5 families -> 21 members / 12 overlays.
- validates the gate_stage arity-undo fix (banks persist). R22 clean-fleet 140/140.
- non-jtbl wave running total (batch-1 + batch-2 partial): 13 x1 + 51 swept = 64 instances.
  fleet distinct 67.6% (+26 fns this batch), instr 78.6% steady, fn-count 88.22%.
- REMAINING (resume aids in CURRENT_PHASE): batch-2's 20 undrafted (.run/wave_b2_args.json)
  + batch-3's 30 (.run/wave_b3_args.json). Low-reach modal tail = low ROI (~0.1pp/batch).
2026-07-22 22:57:32 -06:00
Drew T 57af7ea889 feat(phase-29): ov_SC06_018 non-jtbl wave batch-1 (8 x1 + 30 swept = 38 instances) + fix gate_stage arity-undo revert bug
- batch-1 wave: 25 non-jtbl ov_SC06_018 targets (reach 3-14 modal), 13/25 match_one
  MATCH; whole-binary banked 8 (4 plain + 4 via gate_stage --src-file), swept 4 families
  -> 30 members across 13 overlays. 5 matches deferred (missing-sym/s58/deeper plumbing);
  12 nears are permuter fuel (several close=2/3/4).
- KEY: non-jtbl fns in a jr-split file need gate_stage --src-file <the jr TU> (the default-
  TU reconcile misses them -- same class as the jtbl --src-file fix).
- BUG FIX (R33): gate_stage's arity-undo snapshotted src/<bin>/*.c BEFORE _gate1 splices
  the banks there, so an unbanked draft in the batch triggered a snapshot-restore that
  SILENTLY REVERTED the banks (measured: a 9-draft run banked 4, the 5 unbanked reverted
  all 4 to INCLUDE_ASM). Fix: restore ONLY src/shared/ (the fleet hazard the snapshot
  exists for); the binary's own TU arity edits are local + byte-neutral. GATE_NO_ARITY=1
  was the interim workaround. s61's law from below (undo scope must not EXCEED write scope).
- incremental check-all 140/140 (concurrent with batch-2 drafting; full R22 after batch 2).
  fleet distinct 67.5->67.6% (+38 unique fns), instr 78.6% steady.
2026-07-22 21:48:17 -06:00
Drew T 215c5e2636 feat(phase-29): ov_SC06_018 func_8017D648 x71 (3rd thesis data point: modal family sweeps 85%)
- func_8017D648 (102, reach 82, MODAL/cross-address family): cracked fresh in ov_SC06_018
  (+ a byte-neutral s17a-1 callee-cast reconcile of func_8012F14C to the TU's 1-arg
  convention), banked x1, then swept 70/82 siblings (85%) via family_sweep --hseq
  --source ov_SC06_018 --allow-pins (+3 gate-fail, +8 remap-refused unresolved-immediates).
- 3rd data point for the family-specific finding: across 3 thesis families the fresh-
  exemplar sweep rate is 100% (func_801365B8) / 0% (func_80133AB0) / 85% (func_8017D648).
  Refined model (-> decision-log): the sweep works for the MAJORITY of families at high
  per-family rates, with a genuine per-member-wall minority; cracking is the generator.
- R22 clean-fleet 140/140 byte-identical; tools-health green; 0 NON_MATCHING.
  fleet 78.5->78.6% instr / 88.18->88.20% fn (session net 78.4->78.6 instr / 67.1->67.5 distinct).
2026-07-22 18:23:58 -06:00
Drew T f142a6858f feat(phase-29): ov_SC06_018 crack-wave — func_801365B8 x138 (fresh-exemplar sweep CONFIRMED), thesis is family-specific
- binary-aware crack wave (new tools/workflows/wave_binary.js): 8-target calibration
  over ov_SC06_018 substantial stubs, 7/8 match_one MATCH
- func_801365B8 (155, reach 133): cracked FRESH in ov_SC06_018, swept 132/132 siblings
  via family_sweep --hseq --source ov_SC06_018 --allow-pins -- SESSION-10 refused this
  family 0/133 from an ov077 exemplar. THESIS CONFIRMED (fresh exemplar unlocks it).
- func_80133AB0 (137, reach 137): cracked fresh + banked x1 (+ a byte-neutral s17a-1
  cast reconcile of banked caller func_801343C4), but the family sweep FAILED 0/136 even
  from the fresh exemplar (reverted clean) -- THESIS REFUTED for this family.
- FINDING (R14/R31 -> decision-log): the fresh-exemplar sweep is FAMILY-SPECIFIC, not a
  blanket mechanical x137. A fresh crack is necessary but not sufficient; the byte-gate
  arbitrates each family (~50% on this 2-family sample -> discount the ~1.5pp estimate).
- tooling (R33): family_sweep --source override now searches matched_members (a fresh
  member leaves 'members' after a sig-regen); cdecl._depth0_spans consumes backslash
  line-continuations so a raw-draft #define macro no longer trips audit-cdecl.
- R22 clean-fleet 140/140 byte-identical; tools-health green (dedup 1849/0, C1 234615);
  0 NON_MATCHING. fleet 78.4->78.5% instr / 67.1->67.5% distinct / 88.14->88.18% fn-count.
2026-07-22 18:12:09 -06:00
Drew T 80d570195c feat(phase-29): add main to the weighted denominators (roadmap §1 metrics contract)
The contract requires all three headline metrics to include the main EXE. Since
Phase-27 T10 main was reported as a SEPARATE provisional line, so the headline
silently measured 139 of 140 binaries — and flattered itself by omitting the
LEAST-decompiled one.

RESTATED CAVEAT (the old "stale, PROVISIONAL" wording was misleading): main's sig
is Ghidra's (2026-06-14), but function BOUNDARIES derive from the original bytes
and do not change, and matched-vs-stub comes from the LIVE corpus.stubs — so the
numbers do NOT drift. The real limitation is R34: sig_image cannot independently
validate a PS-X EXE's boundaries, so main has no SECOND, DISAGREEING oracle for the
PHANTOM/TRUNCATED class. The sig also excludes the LINKED PsyQ objects, which is
exactly right for a GAME-CODE contract.

EFFECT — the headline DROPS, which is the point:
  instr-weighted  78.7% -> 78.4%   (10,299,493 / 13,141,652)
  distinct-code   67.9% -> 67.1%   (3,782,990 / 5,634,875)
A continuity line reports the ex-main figure so pre-2026-07-22 readings stay
comparable, and the binary-count label is corrected to "main + resident + 138
overlays" (it read "resident+139 overlays").

Metrics-only change; no build impact (ov_SC06_018 re-verified BYTE-IDENTICAL).
2026-07-22 15:43:48 -06:00
Drew T c6515a6cdc fix(phase-29): the FLOOR VERDICT was an artifact of snapshot frequency, not yield decay
burndown.py averaged the last 3 INTER-COMMIT deltas. The phase's ROI criterion is
"per-SESSION yield floors out", and historically one snapshot was taken per session
— but I seeded THREE inside this session (9, 9b, 9c). Averaging them drove the mean
to +0.23 and printed "AT THE FLOOR — consider closing P29" for a session that
actually yielded +0.7pp instr (78.0 -> 78.7), comparable to recent sessions.

I nearly closed the phase on it. Same error class as everything else this session:
an instrument answering a DIFFERENT QUESTION than the one asked, where the wrong
answer is indistinguishable from the right one.

- --session-close marks a snapshot as a session boundary; the floor verdict is now
  computed ONLY from those (older records predate the flag, so a label containing
  "close" counts too). Mid-session snapshots still record for tracking.
- honest output now: "0 SESSION-to-SESSION delta(s) logged — need >=3 for a floor
  verdict (1 session-close snapshot on record)".

=> P29 must NOT close on ROI grounds yet: the floor is UNDETERMINED and needs 3
session closes to become computable. The eyeballed "+2.5 -> +1.1 -> +0.6 -> +0.2"
trend is not the instrument's verdict either.
2026-07-22 15:24:59 -06:00
Drew T a609f43338 docs(phase-29): Task-7 burn-down live (floor NOT yet determinable), zero-crack track, jtbl_family_bank revert defect 2026-07-22 14:45:59 -06:00
Drew T 9c9ee6ea94 chore(phase-29): burn-down snapshot + regenerated digests 2026-07-22 14:20:28 -06:00
Drew T 8016c172f9 docs(phase-29): SESSION-9 CHECKPOINT — sweep 274 siblings, the PURE≠templatable finding, the tooling answer 2026-07-22 13:47:14 -06:00
Drew T 84fd6c785a docs(phase-29): the isolation-must-follow-the-splice finding, 5/11 cracks banked, and the retraction 2026-07-22 11:24:36 -06:00
Drew T 02b16fa7a7 refactor(phase-29): DELETE gate_stage's jtbl pre-pass (R33) + the honest ladder measurement
gate_stage._jtbl_prepare carried the SAME config-only undo as harvest_verify's did,
and ate the tree again on the first ladder run: 5 orphan region files, truncated
TUs, `undefined reference to func_80192F64`. That INVALIDATED the run's 0/10, so it
was re-measured rather than reported (R35 — a probe from a broken tool is not
evidence). Tree restored from HEAD and re-verified byte-identical first.

DELETED, not patched (R33 — the best outcome is a deleted stage). It was wrong on
two independent axes:
  1. §61b already byte-proved THE CARVE MUST FOLLOW THE SPLICE. A batch pre-pass
     carving unspliced functions reports "prepared" and yields a spec that fails
     once the body lands — which is why it banked nothing.
  2. Its undo snapshotted only config/, while jr_isolate_all rewrites region 0 back
     over the ORIGINAL src/<ov>/<nm>.c truncated.
harvest_verify's per-draft prep is the correct mechanism, snapshots the full source
set, and undoes per function. Two implementations of one capability, the outer one
ineffective AND destructive.

THE HONEST RE-MEASUREMENT (clean tree; tree verified clean after):
- 0/10 bank, but 9/10 now COMPILE and land as whole-binary byte-DIFF; 1/10 plumbing.
- match_one close=0 on several (the function's own bytes exact) and rtu_match says
  MATCH-in-real-TU for func_80135888 — while func_801299C8's transformed draft does
  not compile in its real TU at all. The residual is MIXED, not uniform; at least one
  is an IMAGE-level effect rather than the draft or its TU decl context (prime
  suspect: jtbl/rodata carve placement). NOT generalized from one data point.
- This PRICES Task 14 stages 2-3 by measurement: the existing ladder converts 0 of
  10, so they are not "wire in normalize_self_decls + the type-lift and collect ten
  banks" — the projection error §57a already caught once this phase.

- R22 clean-fleet 140/140 BYTE-IDENTICAL with the giant func_8018F694 banked and the
  func_80135A4C family swept 138/138
- cookbook §61d (the tree-eating undo in two tools; the constant-label defect; the
  re-probe + ladder measurements; the general rule: an undo whose scope is narrower
  than its write scope destroys work no byte-gate can see)
- decision-log + CURRENT_PHASE updated (R30/R31)
2026-07-22 01:55:47 -06:00
Drew T 12a14410f9 fix(phase-29): §61c REFUTED — the jtbl bank IS clean-reproducible; func_80135A4C banked ×1
The session-7 checkpoint gated the entire jtbl track behind one finding: the
carve+isolation path yields a bank that is incrementally valid and clean-invalid
(139/140, [FAIL] ov_SC06_018, "twice, identically"). The prescribed diagnosis
(diff the incremental vs clean object set) never ran, because the failure does
not reproduce.

MEASURED, with the bank applied through the single-function automated path
(harvest_verify --chunk 1 -> [jtbl] carved -> + chunk(1) -> BYTE-IDENTICAL):
  per-binary clean (rm asm+build; extract; build)  -> BYTE-IDENTICAL cbbc4f44
  make clean && extract-all && check-all  (run 1)  -> 140 passed, 0 failed of 140
  make clean && extract-all && check-all  (run 2)  -> 140 passed, 0 failed of 140

ATTRIBUTION (best-supported; the failing tree is gone): the 139/140 runs were
taken on the tree left by the BATCH _jtbl_prep (6 table-bearing -> 1 carved,
4 isolate-FAILED, 1 stale-asm carve fail) — five failed preps' residue of
stranded carves + half-applied isolations. The per-function snapshot-restore
that removes exactly that residue landed AFTER those runs, in commit:0803, the
same commit that named the blocker.

THE LESSON (R35 on ourselves, -> decision-log): "twice, identically" was not a
replication — two reads of the SAME contaminated state is one observation. A
replication must RE-CREATE the state, not re-run the check. Standing guard:
re-apply a fault from a known-clean tree before writing it down as a property
of the mechanism. Sixth "structural wall" to resolve to our own tree/tooling.

- BANKED: func_80135A4C (181 ins) x1 in ov_SC06_018 — isolated into its own
  code subseg + .rodata carve (single-table, no JTBL_PADS; tail3..tail18 renumber)
- §61c faults 1-2 STAND: a stranded carve poisons the overlay; per-function undo
  is unsound in a batch -> ONE jtbl draft per harvest_verify invocation.
  jr_inventory's 1:1 ownership assertion was right and is unchanged.
- UNFROZEN: this family = 138 members / PURE / 24,978 ins ~ +0.19pp (jtbl_family_bank,
  §53 carve law); the 9 preserved t5wave cracks (Task 14 stages 2-3, §57 plumbing)
- R22 clean-fleet 140/140 x2; tools-health OK (dedup 1848/0, C1 234481/234481,
  cdecl 53189/53189, audit-binaries 140); 0 NON_MATCHING (G4)
- fleet 78.0% instr / 66.5% distinct / 87.95% fn-count
- also: preserve the 4 untracked wave-4 .o0 drafts (R20); killed an orphaned cc1
  from the Jul-21 session burning a full core for 13h23m
2026-07-22 00:40:26 -06:00
Drew T 1074f2f202 feat(phase-29 Task-14 stage 1): the ARITY pre-pass — and the shared-state constraint it cost
DIAGNOSED, not assumed. The 12-draft integration probe banked 1/12 and reported the SAME
label for 10 of the 11 failures: `conflicting types for built-in function 'memcpy'` — the
§58 red-herring (a WARNING, from an unrelated TU position). Splicing three top-reach
failures individually and reading real cc1 stderr gave the actual causes:
  conflicting types for `func_XXXX'     3/3   <- loose-typing ARITY conflict
  redefinition of `struct V8'                 <- a SECOND class (type-lift), stage 2

A banked shared caller macro in engine_core.h declares the function with FEWER params than
its byte-true definition takes (the original calls K&R-style with fewer args than the callee
reads); a C89 prototype makes that a hard error. tools/fix_arity_callers.py --any-proto
already fixes it and was simply NEVER WIRED into gate_stage's ladder (only family_sweep
carried §57). Now wired as a TU-side pre-pass.

MEASURED: 2 of 7 top integration candidates banked (func_8016EFC8, func_80164418, both
reach-138) vs the 1/12 old-ladder baseline. R22 140/140; tools-health OK (dedup 1848/0).

INCIDENT — this stage BROKE 138/140 AND R22 CAUGHT IT (nothing was ever committed):
pairing `--apply --any-proto` with `--revert` for the unbanked drafts corrupted declarations
fleet-wide. `--revert` rewrites ()->(void), which inverts a PLAIN apply but NOT --any-proto,
so an unbanked fn whose real decl was `extern void func_801708B0(void *a0)` came back as
`(void)` — in engine_core.h (included by all 138 overlays) and 6 sites in ov_SC01_077's own
sources. harvest_verify --binary ov_SC01_077 reported BYTE-IDENTICAL and was RIGHT about that
binary; the other 137 were structurally invisible to it. Repaired to the exact lines.

ROOT CAUSE FIXED: the ladder now snapshots every file the pre-pass touches and undoes by
RESTORE + re-apply-for-the-banked-set-only — exact by construction, cannot invent a signature.

NEW HARD CONSTRAINT (cookbook §61): any ladder stage mutating SHARED state must be undone by
snapshot restore, never an inverse transform, and validated FLEET-WIDE (R22) rather than by
the per-binary gate that authorised it. §55b's propagation law, one level down. The planned
type-lift stage edits engine_types.h and inherits it by default.

ALSO FIXED: the first wiring passed only --drafts (the narrow-param FILTER) without the
required --funcs, so the stage exited `no funcs given` as a SILENT NO-OP and the gate reported
0/6 as though diagnosed. sh() does not raise on non-zero exit -> explicit rc check added.
2026-07-21 18:19:04 -06:00
Drew T 835c45905d feat(phase-29 Task-13B close): plateau autopsy = ZERO missing-transforms; narrow the admission instead
The hindsight-study §7 taxonomy predicts plateaus decompose into missing-transform (the
"highest-value bucket and the whole point"), seed-structural, and genuine-wall. Run against
real plateaus this class produced NO missing-transforms, and the answer needed no LLM.

MEASURED: `length` probe, 20 targets, 1 win. tail 1/6; partial 0/12.
AUTOPSY (read directly from the bytes, 3 partial plateaus):
- func_8017F0C0 / func_801806C8: target has `sltiu $v0,$v0,1` = gcc's codegen for `!x`/`x==0`;
  the drafts wrote `(u32)(D_x ^ 1)` which emits `xori`. No local mutation crosses that.
- func_8017FF90: draft stores to arg0+8, target stores to a GLOBAL. Different function.
=> these are WRONG DRAFTS wearing a small closeness, i.e. seed-structural, not a mutation gap.

THE FIX IS THE OPPOSITE OF "ADD TRANSFORMS" — a tighter ADMISSION rule:
- _drift_route: permuter only when |d|<=2 AND explains=="tail" (the shape that measurably
  converts). length pool 339 -> 34; permuter bucket 389 -> 84.
- SIZE-MISMATCH: added a PROPORTIONAL test (|d| >= 0.5*nt). max(2,0.15*nt) is far too
  permissive on a tiny target — a 2-ins draft vs a 4-ins target read as a near-miss.
permuter_weights needs NO extension for this class.

Transferable (cookbook §60b): raising a search-closer's yield is at least as often about
refusing it unreachable work as widening its mutation set. Same knife as Task-13A's
targeting fix, one cut finer. Drafter idiom recorded: `sltiu rd,rs,1` => `!x`, never `x^1`.

17 unit tests green; corpus re-collected (1654 rows, closeness cross-check clean).
2026-07-21 17:45:49 -06:00
Drew T 5c894c1e62 feat(phase-29 Task-13B): func_80141B90 x138 + the reach repricing + the length profile
PROPAGATION (§55b, its own targeted batch): dedup_propagate --addr 0x80141B90 --recover
-> "138 overlays byte-identical after propagation"; 117 remaining stubs -> 0; 1 new
dedup group. This was the ONLY one of the 21 directed-run banks worth propagating.

THE REPRICING (R14 — measure a bucket's VALUE, not just its conversion rate):
the directed run converted 27% (21/77) but moved the fleet ~0.03pp, because h_exact
reach of the 21 is: func_80141B90=138, TEN at reach-1 (nothing to propagate), rest 2-10.
Instruction-weighted, the ENTIRE permuter bucket is worth ~0.36pp at 100% conversion.
The mechanism is validated; the fuel was small. Priced frontier (ins-weighted / 13.08M):
  LENGTH-DRIFT |d|<=2   472,178  ~3.6pp  (339 fns)   <- the real permuter-adjacent lever
  integration           419,162  ~3.2pp  (305 fns)   <- Task 14's ladder
  WIDTH                  71,593  ~0.55pp (45)
  permuter (current)     46,571  ~0.36pp (74)
  BRANCH-POLARITY         9,462  ~0.07pp (22)
So WIDTH/BRANCH-POLARITY are NOT worth prioritizing; my earlier "~200 candidates"
framing undersold LENGTH-DRIFT 10x and oversold WIDTH.

NEW: permuter_weights._LENGTH profile (perm_temp_for_expr/perm_expand_expr are the only
passes that change instruction COUNT; the reorder/decl-order levers that dominate the
regalloc+schedule profiles cannot, so they are down-weighted here) + residual_class
._drift_route (|d|<=2 -> permuter/`length`, larger stays structural — same class,
opposite tool) + classify() accepts a PROFILE NAME directly (the measured profile beats
re-parsing a free-text label). 17 unit tests green.

grinder: --profile filter (probe ONE residual class's conversion) + a PERSISTENT attempt
ledger. `tried` was in-process only, so every fresh --once run re-permuted the previous
run's losers — the permuter is deterministic given (base.c, target.o), so that CPU can
never produce a new win. Measured: a 20-target probe drew 19 already-tried targets.
Keyed by draft_sig so an improved draft legitimately re-opens the function.
2026-07-21 15:05:56 -06:00
Drew T b8ee9fa9d2 feat(phase-29 Task-13B): directed permuter wins first try; 3 latent gate defects fixed at root
First run of the Task-13A-targeted grinder (--once --batch 8 --permute-secs 90):
  targeting: ON — 1665 classified; only bucket=permuter is admitted
  targeting skipped 1601 non-permuter candidates
    {redraft 707, structural 583, integration 305, unclassified 4, unknown 2}
  permuter WON func_80181F78 @ ov_SC03_014 (close was 1)   [~6 min]

BANKED 2 (both whole-binary byte-gated, R22 clean-fleet 140/140):
- func_80181F78 (8 ins)  — classified DELAY-SLOT / schedule
- func_80141B90 (29 ins) — classified IMM-VALUE / cse
Both were classified bucket=permuter by residual_class BEFORE the run: the classifier
predicted a search-closer could reach them, and one did. First end-to-end validation of
the targeting thesis.

THREE latent defects, all pre-existing, all unreachable while the grinder banked nothing
since Phase 21 — the fix made it win and every one fired at once (cookbook §60a):

1. gate_stage commit path crashed on src=None. `src` is DELIBERATELY never defaulted
   (Phase 26-A: a default silently PINS the gate to the main .c), but the commit did
   `git add src …` unconditionally -> every caller that omits it (grinder, orchestrator,
   idiom_hunt) crashes THE MOMENT IT BANKS. Now `git add -u src/`, which also retires the
   `src/ov_*/*.c` filename glob that once omitted 4 R22-verified banks from a commit.
2. _xform ladder dirs (-cn/-cast/-rc/-uni) ACCUMULATE across runs: they held 34 stale
   drafts, so the gate processed 34 when the grinder submitted 1, and banked one function
   it was never asked to try — which would have been committed under a message naming a
   different one. Nothing wrong entered the tree (G3/P9 held; the gate banks only
   byte-identical output) but report and work had diverged. Now cleared per run.
3. grinder called gate_stage with the default propagate=True = `dedup_propagate
   --auto-from`, the §55b fleet-wide path that timed out at 3600s and left 90/140 overlays
   broken — and being INSIDE the gate it takes the banks down with it. Now propagate=False;
   banks commit cheap, propagation is its own targeted --addr batch (§55b law).

R22: make clean && extract-all && check-all -> 140 passed, 0 failed of 140.
tools-health OK (dedup 1847/0, C1 234343/234343); 0 NON_MATCHING (G4).
2026-07-21 11:24:48 -06:00
Drew T b3ab5c2253 feat(phase-29 Task-13A): deterministic residual classifier — the permuter's problem is TARGETING
The autopsy (hindsight-study §7) assumed the permuter loses for want of a mutation.
Measured over the whole open backlog, it loses because it is aimed at work a
search-closer provably cannot close.

- NEW tools/residual_class.py: decide a near-miss's class FROM THE BYTES. Decodes each
  mismatching MIPS word -> (op-skeleton, register-fields, immediate); drift FIRST (one
  inserted insn inflates `closeness` by the tail length), then consistent-injective
  register map -> REGALLOC-PERM (§31 S11/RC-3), same-multiset-reorder -> SCHEDULE-REORDER,
  DELAY-SLOT, WIDTH/BRANCH-POLARITY/STRENGTH/ADDRESSING/IMM-OFFSET/IMM-VALUE. Every class
  routes to a BUCKET = which tool the failure wants. Uncovered opcode -> UNKNOWN, COUNTED
  (R32). 16 synthetic unit tests (test_residual_class.py).
- NEW tools/autopsy.py: `collect` materialises the corpus Task-12's telemetry never filled
  (1 of 6,169 records had a residual) by recompiling every open draft through the EXISTING
  match_one path (R33) — 1,752 drafts in 21s at -j12. `report` -> docs/autopsy.md.
- NEW corpus.o0_sources()/is_o0(): the opt-level oracle DERIVED from the Makefile's own -O0
  rules, coverage-asserted. Scoring an -O0 target at -O2 makes the residual 100% artefact
  (the trap this phase hit four times).
- R34 cross-check baked in: residual_class's closeness vs masked_diff.structured_diff's,
  asserted per row; 1,673/1,673 agree, 0 classifier errors.

FINDING: of the 972 records the grinder's own filter admits, only 75 (7.7%) are
permuter-shaped; 547 are structural and 348 are drafts that are not the function at all.
~92% of the daemon's CPU went where it could not win — the byte-grounded explanation of
"7 banks all-time, all Phase 21, 0 since" (Phase-22 audit). grinder.candidates() now
filters on the measured bucket (1,303 -> 78) and takes its directed profile from the
measured class, not the logged label (91% carry none -> it ran on gcc defaults).
Degrades to undirected if uncollected and says so; --no-targeting A/Bs it.

Two measured corollaries (R14, not projections):
- 699 records rank as near-misses at closeness up to 278 purely from a length artefact:
  un-attempted work misfiled as a backlog of hard functions -> new `redraft` bucket.
- a 12-draft gate probe of the `integration` bucket banked 1/12 (11 PLUMBING), so the 306
  prices Task 14's reconcile ladder rather than promising free banks. func_80167714
  (104 ins, reach-134) banked x1, un-propagated by design (§55b).

Two defects fixed forward:
- masked_diff._common_typedefs() used ONE shared probe path, so parallel match_one
  processes clobbered each other: 14 of 1,752 drafts lost in a single 12-way run (0.8%),
  silently, in every parallel wave ever run. Now per-PID.
- gate_stage.match_one_closeness never passed --o0 -> phantom residuals for every -O0
  function, written straight into the backlog this autopsy reads.

R22 clean-fleet: check-all 140 passed, 0 failed of 140; tools-health OK (dedup 1847/0,
C1 234343/234343); 0 NON_MATCHING (G4). Flywheel captured in-session (R30/R31):
cookbook §60, decision-log entry, SETUP.md inventory.
2026-07-21 11:03:59 -06:00
Drew T e4e8ec5ca9 docs(phase-29): SESSION-5 CHECKPOINT — full session-checkpoint block for a fresh session
Session-5 (crack-waves 1-4 + 2 tooling fixes + burndown + hindsight-study + Task-12
telemetry). 140/140 byte-identical, fleet 78.0% instr. NEXT: Task 13 (classifier +
autopsy) then Task 14 (gate_stage ladder + auto-R22). Written BEFORE the pause per
the new checkpoint-before-pause rule.
2026-07-20 23:52:06 -06:00
Drew T a5bad7f48d feat(phase-29 Task-11): burn-down + velocity tracker (the ROI-close instrument)
tools/burndown.py snapshots the 3 fleet metrics + remaining substantial frontier
each run (docs/burndown.jsonl, git-HEAD-keyed), computes velocity vs the previous
commit-snapshot, and flags the yield floor (mean instr-pp over last 3 snapshots <
threshold => 'consider closing P29'). Seeded with the session-4-close baseline.
Reads progress.fleet.md + family-hseq.md (regen those first for a true reading).
2026-07-20 14:55:49 -06:00
Drew T 1ad5cc359a docs(phase-29 crack-wave2): session-4 checkpoint — +819 members (76.3% instr), frontier honest
Crack-wave 2 (absent-from-ov077 pool) + propagation: 6 families banked ~815
members fleet-wide (R22 140/140). Session-4 total: 75.2->76.3% instr /
60.6->62.8% distinct / 87.04->87.47% fn-count across 2 crack-waves (~1500 banks).
Tooling finding: family_sweep --source is ignored (uses manifest exemplar).
2 preserved permuter seeds. Non-MCP substantial frontier worked out; next fresh
cracks need /mcp prefetch.
2026-07-19 02:48:11 -06:00
Drew T d7092de63a docs(phase-29 crack-wave): session-4 close — +412 residuals verified, cookbook §59
func_80165240 137/137 + func_8016D1D8/D688 274/274 + func_8013C0F8 x1 banked by
the residual agent; 2 jtbl cores blocked on §8c/§8e-2 tooling walls. R22 clean-fleet
140/140, tools-health OK, 0 NON_MATCHING. Session-4 fleet 75.2->75.7% instr /
60.6->61.3% distinct / 87.04->87.24% fn-count (~687 member-banks). Cookbook §58/§59.
2026-07-19 00:25:58 -06:00
Drew T c9e12a079b feat(phase-29 crack-wave): +6 cores banked ×1 in ov_SC01_077 (R22 140/140)
Ultracode 11-core crack-wave over the freshly-regenerated draftable structural
frontier (R35: the Jul-14 manifest still listed already-banked families). 9
match_one MATCH / 2 near; 6 of 9 banked whole-binary byte-identical.

Banked (ov_SC01_077, ×1 — ×138 sweep deferred, Drew paused after the bank):
- func_80150170 (95, hexR=138 dedup core) — engine_core void->s32 narrow
- func_8016D1D8 (148) — data-label + typedef-scope
- func_8016D688 (60)  — data-label (D_801D9C20)
- func_80165240 (63)  — normalize_self_decls (caller-decl -> void(void*x3))
- func_80164E40 (25)  — engine_core void->s32 narrow
- func_801457A4 (79)  — -O0 (relocated into _o0b object)

- engine_core.h: 3 decls narrowed void->s32 (byte-neutral fleet-wide; callers
  ignore the return) — R22 clean-fleet 140/140 confirms neutrality.
- config/symbols.ov_SC01_077.txt: D_801D9C20/60 u8 data-label mirror so a
  re-extract re-emits the labels the D1D8/D688 banks reference (R22 corollary;
  fixed a type:data->type:u8 splat-format bug that broke ov_SC01_077 extract).
- 3 NOT banked (801549F8, 8013BD74, 8013C0F8): all match standalone, blocked
  ONLY by the §8 jtbl-rodata carve (NOT codegen; C0F8 was NOT a real DIFF).
- .run/giants: 2 near (8014D820 close-11 intrinsic-sched, 8012E364 close-22)
  + the 3 jtbl-blocked drafts preserved (R20).

R22 clean-fleet: 140/140 byte-identical; tools-health OK (dedup 1846/0,
C1 234205/234205); 0 NON_MATCHING linked (G4). Fleet 75.2/60.6/87.04 (flat —
×1 banks; the ×138 sweep is the deferred fleet-mover).

cookbook §58 (R30): match_one MATCH != bank — it compiles standalone so it is
blind to (a) Ghidra symbol names, (b) def-sig conflicts vs the fleet, (c)
callee-decl conflicts, (d) -O0-vs-O2; crack-wave drafts need a reconcile pass.
2026-07-18 22:58:15 -06:00
Drew T 53433df1b3 feat(phase-29): func_8013D53C 14/137 + NSD hardened (rewrite-to-canonical, (void) fix) + Cmd lift
- func_8013D53C: NSD (self-decl caller-thread) + a byte-neutral Cmd_8013D53C type-lift clear the plumbing
  -> 14/137 h_seq members bank; 123 have genuine per-member codegen DIFFs (hard cse.c-wall crack -> permuter
  fuel). Reverted the 123 bankless byte-neutral NSD edits (churn on matched code, §57a NB).
- NSD hardened, 2 bug-fixes validated on D53C: REWRITE the divergent decl to canonical instead of DROPPING
  it (drop broke def-after-caller forward visibility -> 'func undeclared'); and '(void)' is a genuine 0-param
  conflict, not skippable like a true no-proto '()' (the bug that filed D53C's arity class as 'not this pass').
- earlier this session: broad --fix-def-sig sweep = HONEST +137 only (staging != banking, R14/R35); NSD is
  SURGICAL-ONLY (broad application poisons whole groups; --fix-def-sig is broad-safe). cookbook §57a.
- R22 clean-fleet 140/140 byte-identical; tools-health OK (dedup 1846/0, C1 234205/234205); 0 NON_MATCHING (G4).
  fleet 75.2% instr / 60.6% distinct / 87.04% fn-count. session-total from 74.6: +0.6pp instr, ~+421 members.
2026-07-18 20:30:43 -06:00
Drew T 65c93ea035 feat(phase-29 type-lift): func_8016CBC0 family 1->138/138 (+137) via the 6-typedef engine_types.h lift
- func_8016CBC0's 137 members were NOT self-decl-blocked (§57 survey: 0 divergent self-decls) but blocked
  on the exemplar's 6 LOCAL typedefs (Rec_/Blk_/SVEC_/CLR_/Poly_/Mtx8_8016CBC0). Lifted all 6 verbatim into
  src/shared/engine_types.h (fleet-visible via engine_core.h) + removed the locals from the exemplar TU.
  No fleet name-collision; exemplar rebuilds byte-identical d19c9580 (the type-lift is byte-neutral).
- family_sweep --hseq --only 0x8016CBC0 --no-preclassify --normalize-self-decls -> 137/137 banked, 0 failed
  (the decl-normalize stage a correct no-op here — 0 self-decls). 0 func_8016CBC0 stubs remain fleet-wide.
- R22 clean-fleet 140/140 byte-identical; tools-health OK (dedup 1846/0, C1 234205/234205); 0 NON_MATCHING
  linked (G4). fleet 74.9->75.1% instr / 60.1->60.6% distinct / 86.96->87.00% fn-count.
- R14 lesson: two families that both looked like a 'stuck 137-family' needed DIFFERENT levers
  (decl-normalize §57 vs type-lift) — route by the real cc1 error, not the shape. session-total +270 members.
2026-07-18 17:50:07 -06:00
Drew T 514383de6a chore(phase-29 crack-wave): log wave2+fable+type-lift outcome (fleet 74.6% instr) + preserve drafts
Session-total 72.1->74.6% instr (+2.5pp). 8 exemplars + ~815 members banked; 3 Fable source-read cracks
(cse.c address-CSE, post-reload sched, reorg j-slot). Follow-ups: 801670e4/8016cbc0 per-sibling decl-norm,
8013d53c caller-thread, 801412a8 §29 wall, 4 permuter near-misses. All drafts preserved (R20).
2026-07-18 12:33:39 -06:00
Drew T 8bd1b2b175 chore(phase-29 crack-wave): log wave outcome (3 MATCH/4 near, 8013CB84 x138) + preserve drafts + fleet 73.7%
Ultracode 7-agent fan-out. func_8013CB84 banked x138 (+34k ins). 2 jr MATCHes deferred on
def-side/-O0 walls (characterized+preserved R20). 4 near-misses + 8014D820 perm27 = permuter/Fable5
fuel. Crack-wave sweep recipe learned (map regen -> matched-ov077 -> standard sweep). R22 140/140.
2026-07-18 09:36:30 -06:00
Drew T 4310269bb8 feat(phase-29 §8e): campaign close — 3 families swept (410 banks), fleet 73.4% instr / 56.9% distinct (v-batch R22 140/140)
- func_80131340 138/138 · func_80159C84 134/138 (4 SC07 named) · func_8013F350 138/138 ·
  func_8013C414 x1 (family deferred on the -O0-cluster rollout wall, uniform + fail-loud).
- cookbook §8e-2: clean-draft law, zero-word spec rule + tables= persistence + --like transfer,
  named deferral classes. progress.fleet.md digest regenerated. Clean drafts preserved (R20).
2026-07-18 04:25:19 -06:00
Drew T 1dbf8310ef chore(phase-29 T4): regen progress.fleet.md digest (fleet 72.1% instr after session-2 banks) 2026-07-17 18:37:47 -06:00
Drew T fd564a2cf7 feat(phase-29 T3): propagate the 3 self-contained cores ×137 (+410 instances; fleet 71.0->71.4% instr)
- targeted dedup_propagate --addr per core (NOT --auto-from), --recover for stragglers:
    0x8014ADE0 -> 138 overlays byte-identical
    0x801325B8 -> 134 (ov_SC07_011 byte-diverges -> auto-excluded, kept x1 — what --recover is for)
    0x801387B8 -> 138 overlays byte-identical
  = ~410 member-instances; 3 new dedup groups (1840 -> 1843), C1 coverage 233795/233795.
- 2 of the 5 banked cores (func_8014E284, func_80137DD4) stay ×1: "not self-contained (local types)"
  -> blocked on the build_engine_types type-lift (the §19/§20 propagation cap). Carried.
- R22 clean-fleet 140/140 BYTE-IDENTICAL; audit-binaries OK; dedup 1843/0; 0 NON_MATCHING (G4).
  Fleet instr 71.0 -> 71.4% / fn-count 86.30 -> 86.42% / distinct-code 53.3%.

- SELF-CORRECTION (R14/R35), now fixed in cookbook §55c + CURRENT_PHASE: my earlier claim that this
  propagate "needs ~2h+" was WRONG. That timing was taken while the tree still carried the partial
  damage of a killed --auto-from (90/140 overlays broken), so every member-gate was failing/retrying.
  On a HEALTHY tree a targeted --addr propagate is ~233s/core (all 3 = ~27 min) — ~20x faster. Only
  --auto-from is genuinely fleet-slow. A timing taken on a broken tree measures the breakage, not the
  tool — recover the tree FIRST, then measure.
- cookbook §55: the wave's new byte-proven levers (§49-variant birthing-boost suppression via
  reg_n_sets 1->2; sched1 birthing/LUID + "cc1 -dL" movable introspection; switch-tree vs jtbl
  CASE_VALUES_THRESHOLD=5; block-scope-extern beats *(T*)&sym) + the GATE-ORCHESTRATION law
  (--no-propagate per group then ONE targeted --addr; commit banks BEFORE propagating; a reverted src
  needs a re-extract; gate_stage's default harvest_verified.txt accumulates -> phantom banks).
2026-07-17 02:04:38 -06:00
Drew T b5340f920b feat(phase-29 T3): core-crack wave — 5 cores banked x1 (13 agents: 7 match/6 near); propagate deferred + 3 tooling traps logged
- ULTRACODE worker_wave: 13 xHigh drafters over 6 cores (260-371 ins) + 7 B3 near-misses (100-141).
  Usage-limit hit at 2/13 -> RESUMED (cached replay) -> 13/13 done, 7 match / 6 near.
- BANKED x1 (whole-binary byte-gate; R22 clean-fleet 140/140): func_8014ADE0 (139), func_8014E284 (108),
  func_80137DD4 (129), func_801325B8 (113), func_801387B8 (100). NEAR: func_8013FAF8 (312 giant, def-sig
  s16/s16 vs canonical s32/s32), func_8014F4C0 (in-TU byte-verified; unresolved decl conflict).
- NEW levers for the flywheel: §49-variant birthing-boost suppression via reg_n_sets 1->2 (func_801325B8);
  sched1 birthing/LUID + "cc1 -dL" movable introspection (func_80177940); switch-tree vs jtbl
  CASE_VALUES_THRESHOLD (func_801387B8). 6 near-misses carry byte-proven residual analyses.
- THREE TOOLING TRAPS (mine; ~3.5h lost, 0 data lost — all recovered):
  (1) gate_stage's propagate is FLEET-WIDE (--auto-from): running gate_stage per-group ran it 4x
      redundantly; 3 timed out at 3600s -> partial damage (90/140 broken, 887 files). FIX: --no-propagate
      per group, then ONE targeted --addr propagate.
  (2) a reverted src needs a RE-EXTRACT (R22 corollary): asm/ kept the banked state -> corpus.CorpusError
      '5 stubs have NO .s on disk' (R34's second oracle caught it, working as designed).
  (3) gate_stage's default .run/harvest_verified.txt ACCUMULATES + no --verified-out CLI -> PHANTOM
      'banked:1' for a still-stubbed fn (R32/R35 class, still armed). Trust the SOURCE, not the report.
  LAW: commit cheap verified banks BEFORE the expensive propagate.
- PROPAGATE DEFERRED, properly sized: 3/5 self-contained x138 = ~414 instances; 2 blocked on local types
  (type-lift); straggler ov_SC03_093 needs --recover; measured ~2h+ (my 3000s guards killed it twice).
- fleet instr 71.0% / distinct 53.3% / fn-count 86.30%; dedup 1840/0; 0 NON_MATCHING (G4); main 143dbb89.
2026-07-17 01:33:16 -06:00
Drew T afd1aeea4f feat(phase-29 T6): broad --fix-def-sig harvest +19 (def-sig lever tapped beyond the mega-pools)
- fleet-wide --band substantial (17) + tiny (2) with --fix-def-sig (all families) = 19 more members;
  the def-sig conflict was concentrated in the 2 tiny-IMM mega-pools (already banked, now not-stub)
- R22 clean-fleet 140/140 byte-identical; pure-reduction; dedup 1840/0; 0 NON_MATCHING (G4)
- fleet instr 71.0% (steady) / distinct 53.2->53.3% / fn-count 86.30%. Task-6 mega-pool track complete;
  permuter backlog (grinder/permuter_ils close-1..4) remains as the other Task-6 half
2026-07-16 19:35:18 -06:00
Drew T 941cd37b19 feat(phase-29 T6): tiny-IMM mega-pools CRACKED +4,801 via family_sweep --fix-def-sig (fleet 70.4->71.0% instr)
- THE FIX (new): family_sweep --fix-def-sig (header_sig_map + reconcile_def_sig, 1005 mapped fns) —
  rewrites each member draft's DEF signature to the shared-header (engine_core.h) canonical decl.
  Root cause (byte-proven, R14/R35 after 3 masked-metric mis-reads): engine_core.h forward-declares
  the member (extern void func_8015FAAC(s32 *a0), a shared fn calls it) while family_remap copies the
  EXEMPLAR sig (void *a0) -> 'conflicting types' -> member TU never compiles. Invisible to standalone
  diff_regions/match_one (no header conflict) AND to --reconcile. Byte-neutral (ptr-type param, gate
  arbitrates G3/P9); one member hand-verified byte-identical first.
- 0x80131eec 2331/2470 (94%) + 0x80130d0c 2470/2496 (99%) = 4,801 members banked across 405 overlay
  files. R22 clean-fleet 140/140 byte-identical; pure-reduction (0 new/dup stubs); dedup 1840/0;
  0 NON_MATCHING (G4). Fleet instr 70.4->71.0% / distinct 52.3->53.2% / fn-count 84.94->86.30%.
- CORRECTS the commit:0665 'symbol-definition gap' scout (WRONG). The 4th 'reproduce the build step'
  instance (§53-carve, -O0-flag, now the member's canonical DECLARATION). cookbook §54, decision-log R31.
2026-07-16 18:56:40 -06:00
Drew T f6f89781ff feat(phase-29 T2 Arm A): swing verdict = BANKED FACT (9/9 -O0 members on ov_SC07_010); fleet -O0 rollout deferred at the splat wall
- tools/rollout_o0_cluster.py (new) + Makefile O0_CLUSTER_OBJS -O0 wildcard: the -O0-cluster
  carve (0x13410..0x14834), adapting rollout_whale_o0.py to a 3-way <ov>/<ov>_o0/<ov>_o2b split
- ov_SC07_010: carve byte-neutral -> family_sweep --hseq banked 9/9 -O0 exemplar-family members
  whole-binary (R22 clean-fleet 140/140). The Task-1 masked-MATCH swing verdict is now a BANKED
  FACT: -O0 cluster members DO bank at -O0 (§52b). Phase-20 'func_8013B7AC overlay-local' refuted.
- THE WALL (byte-proven, TOOLING not compiler): the same carve on 006/007/011 byte-shifts the whole
  image (+0x20 %lo data-symbol shift, 34% diff) from a CLEAN build; boundaries verified as real
  fn-starts. Root cause = splat re-disassembly of a 3-way-split subseg that still holds INCLUDE_ASM
  stubs (the whale's stub-free _o0b shape avoids it). The Phase-20 '-O0 split infra' wall, root-caused.
- DEFERRED (ROI): full -O0 fleet rollout (~1,233 / ~0.6pp) — 3/4 sampled walled + 134 jr-embedded +
  bigger levers (Task 3 core-cracks, Task 6 tiny-IMM ~5,566). decision-log R31 + cookbook §18-P29.
- 140/140 byte-identical; dedup 1840/0; 0 NON_MATCHING (G4); main 143dbb89. Task 2 substantively done.
2026-07-16 17:05:52 -06:00
Drew T 908dded511 feat(phase-29 T2a): Arm B tail — 748 members banked in the 4 SC07 tail overlays (fleet 70.2->70.4% instr)
- resumed the SIGTERM-interrupted comprehensive --band all sweep as 3 band-bounded
  family_sweep --hseq --allow-pins passes (substantial 53 + mid 372 + tiny 323 = 748),
  each exit 0 (the --band all SIGTERM lesson: band-bounded + committed-per-batch)
- all 748 in the 4 files=1 SC07 tail overlays (ov_SC07_010 897->516, ov_SC07_011
  797->436, 006 457->454, 007 595->592); verified pure-reduction (0 new/dup stubs, R14/H5)
- 006/007 residual = jr-families (§53 carve, Task 3) + plumbing; plain-sweep tail drained
- R22 clean-fleet 140/140 byte-identical; audit-binaries OK; dedup 1840/0; main 143dbb89;
  0 NON_MATCHING (G4). fleet instr 70.2->70.4% / distinct 51.9->52.3% / fn-count 84.73->84.94%
2026-07-16 16:33:40 -06:00
Drew T 5b6a8ae6cb feat(phase-29 T2a): Arm B type-lift sweep — 3,407 member-matches banked (fleet 68.9->70.2% instr)
Acting on Task-1's verdict (the legacy-PURE "~3%" is tooling, not a wall): the -O2
type-lift arm. family_sweep --hseq --no-preclassify --band all --allow-pins templates
each matched exemplar's C onto its unbanked same-family members and whole-binary
byte-gates every one (the sole arbiter, G3/P9). The pin-crash wall being dissolved
(Phase-27/28 _carry_macros) let --allow-pins retry the pinned exemplars.

- BANKED 3,407 member-matches across 136 overlays (INCLUDE_ASM stubs -> matched C).
- R22 clean-fleet verify: 136/137 modified overlays byte-identical from a clean rebuild;
  the 1 FAIL (ov_SC07_010) was the SIGTERM mid-gate partial -> reverted, byte-identical.
- make check-all: 140 passed / 140 BYTE-IDENTICAL; dedup-check 1840/0; audit-binaries OK;
  audit-cdecl green; 0 NON_MATCHING in any default build (G4).
- Fleet: instr-weighted 68.9 -> 70.2% (+1.3pp) . distinct-code 49.5 -> 51.9% (+2.4pp) .
  fn-count 83.94 -> 84.73% (+0.79pp).
- Process lesson (CURRENT_PHASE.md): --band all sweeps are too long for one background
  pass (got SIGTERM'd); future Arm B runs go band-bounded + committed-per-batch (resumable).
  Residual FAILED members (pin/drift/plumbing) + the -O0 Arm A carve remain.
2026-07-16 14:27:10 -06:00
Drew T 3827d01bfb feat(phase-28): the endgame engine -> the instrument-repair phase; B2 lives, SC07 wired, R36 (v1.27.0)
- RE-SCOPED at plan time (R35): the roadmap's swing number rested on a broken-tool probe. B2's
  "structural families bank ~0%" (0/8, which reshaped 2 phases of strategy) was a MISSING CARVE ->
  8/8, then 102/115 (88.7%). The ~0% doctrine has NO surviving post-fix evidence.
- T0 img_path derive-not-guess -> un-hid a 230,612-ins SC07 pool doubly hidden (P27 onboarded 4
  overlays, never regenerated the map; the hardcode would have called every member "LEN").
- T3-A: the SC07 pool is h_exact + UNWIRED, not h_seq. T4 dedup_extend (NEW) wired 6174/6457 (95.6%)
  -> groups 134->138 binaries, C1 coverage +6174. NOT member_adapt (the number said build nothing).
- T5: resident 21->14 (90.34%, 7 banked via an Ultracode wave) + honest dossier for the 14; fixed
  progress.py (#if 0 + len()-sum) and match_one's FAKE isolation (found by an agent mid-wave).
- T2 purged the poisoned grinder blacklist (8/22 matched anyway). T6 killed the --chunk 1 double-build.
- T7: make audit-binaries (the R36 citizenship gate, negative-control-proven) + fixed disc_code_sweep's
  BLINDNESS to compressed code (the type-4 row was vacuous for 138 known binaries) + the worklist key-bug.
- T3b: the legacy h_seq swing number = ~3% AS-TOOLED, CLASSIFIED (274 DIFF / 37 PLUMBING), ceiling
  UNKNOWN -- the 274 DIFF is byte-PURE members whose remapped bodies don't reproduce (the same
  tooling-vs-wall ambiguity that resolved to TOOLING twice this phase). P29 disambiguates before scaling.
- THREE SELF-INFLICTED DEFECTS fixed forward: the registry yaml.safe_dump (H5, destroyed 47 comments +
  1832 hex fields, invisible to every byte-gate), two DIFF mis-reports (R14), the match_one shared scratch.
- rule R36 (a newly-discovered binary is not real until every consumer knows it; enforced by
  audit-binaries). cookbook §53. R22 140/140 throughout; tools-health OK; dedup 1840/0.
2026-07-16 10:53:23 -06:00
Drew T 876dc7f053 feat(phase-28 T5): resident 21 -> 14 stubs (7 banked, 90.34%) + fix match_one's fake isolation
Ultracode wave: 16 isolated drafters over the resident's non-jtbl stubs (the 5 jtbl deferred —
they need the rodata-island carve, §53). Drafts only; the whole-binary byte-gate arbitrated after.

- BANKED 7/16, byte-gated: func_800CEFD0(77) func_800D0D7C(45) func_800D1B80(22) func_800D1E28(37)
  func_800D1FC8(62) func_800D29F8(172) func_800D2D10(39).
  Resident REAL 122 -> 129, stubs 21 -> 14, byte-ident 124/145 (85.52%) -> 131/145 (90.34%).
  FLEET instr 9017152 -> 9017606 (+454 ins). R22 make clean && extract-all && check-all ->
  140 passed, 0 failed of 140 (the first R22 was killed by a terminal crash and RE-RUN, not assumed).
  Ground truth on 14 agrees 3 ways: source grep, splat-emitted stub .s count, progress.py.

- §52b's LAW, MEASURED AGAIN INDEPENDENTLY: the agents self-reported 11 match_one MATCH; the
  whole-binary gate banked 7 (64%). All 4 blocked MATCHes died on `conflicting types`
  (D_8010EDEC / D_80115110 / func_800D1984 / cdFileLocTable) — the loose-typing def-side wall, NOT
  codegen. gate_stage's recovery banked 0/5 on them. A match_one MATCH is a CANDIDATE (G3/P9).

- FIX — match_one's isolation was FAKE, and its own docstring was the false spec. It promises
  "Fully isolated (own temp dir) so many run in PARALLEL with no shared build -- a real asm-differ
  loop for an agent to iterate against", while `--work` defaulted to the SHARED '.run/match': every
  concurrent caller compiled into the same t.c/t.o. FOUND BY AN AGENT MID-WAVE, the only way it can
  be found — it read another agent's function out of its own scratch ("found another agent's
  func_800D2650 in my t.c") and reported it. Every other agent steered by a loop that could hand it
  someone else's compile: a CONFIDENT WRONG verdict, worse than a crash. Default is now a private
  .run/match/<fn>.<pid>; the default IS the promise. (Some agents had already worked around it by
  passing --work themselves.) The byte-gate was never at risk — it is the sole arbiter — but the
  iteration loop the agents steer by absolutely was.

- The 14 remaining: 5 PLUMBING (loose-typing) + 4 DIFF (genuine codegen: func_800D2650 close=4,
  func_800CFAD0 close=5, func_800D0E30 close=12, func_800D27DC close=48) + 5 jtbl deferred.
  Dossier next (T5b) — the agents' per-function residual analyses are the durable asset (R30).
2026-07-16 01:41:57 -06:00
Drew T 2c4e2344da fix(phase-28 T5): progress.py — #if 0 blindness + the len()-sum; resident 123/146 -> 122/145
R35: fix the instrument before planting a flag on its denominator.

- #if 0 BLINDNESS: classify() knew `#ifdef NON_MATCHING` (:425) but not `#if 0`, so a dead
  analysis body was read as a live definition AND its real INCLUDE_ASM stub counted separately —
  the SAME function in BOTH `real` and `stubs`. Live case: resident.c:868-925 wraps a full
  void func_800D00E4(s32){...} in #if 0 (its jtbl dossier) and re-declares the stub at :926.
  Now the block is skipped entirely: dead code is neither matched nor stubbed.

- THE len()-SUM (the dual defect): `placed` was a set union, so it caught a function in NO bucket
  — but `matchable` SUMMED len()s, so a function in TWO buckets counted twice and nothing
  complained. matchable/byteident are now SET unions, plus a new OVER-coverage assertion that
  fails loudly if any fn lands in multiple buckets. R32 means both directions: nothing missing,
  nothing double-counted.

- NEGATIVE CONTROL (the fix must change an answer the old tool gave):
    resident REAL 123 -> 122 | matchable 146 -> 145 | 85.62% -> 85.52% | func_800D00E4 no longer
    double-counted. FLEET instr 68.9% UNCHANGED (no #if 0 in the overlays) — the fix is scoped.

- FINDING (logged for T7's audit-binaries, does NOT block the flag-plant): the two INDEPENDENT
  oracles now agree exactly at 144 — corpus (21 stubs + 123 matched, derived from the tree) and
  sig_image (the 2nd oracle) — with EMPTY set difference both ways. progress.py still reports 145
  because it counts func_800CEDFC and func_800D33E0, which are DEFINED in resident.c but absent
  from sig_image. 0x800CEDFC is the resident's vram base +4 (the first function, code starts at
  file offset 0x4 after the leading data word), yet make audit-corpus reports 0 PHANTOM +
  0 TRUNCATED. Either sig_image has a boundary blind spot or those defs are not image functions.
  progress.py's text-scanning classify() is exactly the re-parsing R33 says should be DERIVED from
  corpus instead — a real refactor, logged not rushed.
  The flag-plant claim is unaffected: it rests on corpus.stubs('resident') == 21 (tree-derived,
  verified 5 ways), not on the contested denominator.
2026-07-16 00:17:57 -06:00
Drew T fda9eebb42 fix(phase-28 T4): wire all 4 SC07 overlays (6174/6457, 95.6%) + REPAIR the registry I destroyed
Completes T4 and corrects two defects I introduced, both landed in commit:0649.

- WIRED: 006 1543/1614 · 007 1544/1615 · 010 1544/1614 · 011 1543/1614 = 6174/6457 = 95.6%,
  ~0 agent tokens. Stubs/overlay ~2400 -> 831/984/898/825. Fleet instr 67.0 -> 68.9%,
  fn-count 82.16 -> 83.94%. dedup-check 1840 validated / 0 failed; groups now read
  "138 members [138 binaries]" (was 134); C1 coverage 227211 -> 233385 = exactly +6174.
  R22 make clean && extract-all && check-all -> 140 passed, 0 failed of 140 at every stage.

- FIX #1 — I DESTROYED THE REGISTRY'S DOCUMENTATION, AND EVERY GATE CALLED IT GREEN (H5).
  The first cut wrote config/dedup.us.yaml with yaml.safe_dump, round-tripping the whole file:
  47 comment lines -> 0 (including the curated Phase-11 header explaining WHY the share is
  source-level) and 1832 `vram: 0x80162FF4` -> `vram: 2148937716` (PyYAML parses YAML-1.1 hex to
  int; dumps int as decimal). 25,948 lines rewritten. It passed dedup-check 1840/0 AND check-all
  140/140 because _addr() accepts both forms: THE DATA WAS CORRECT AND THE DOCUMENT WAS RUINED.
  Fixed forward (R6, no history rewrite): restored from commit:0649~1 and re-applied the 6174
  memberships via a surgical text edit (add_members_surgical). Verified: 1545 insertions / 1545
  deletions, 0 non-`binaries:` lines changed, 47 comments + 1908 hex fields intact, and the
  rebuilt fleet is byte-identical to the destructive version (140/140).
  THE LESSON: every oracle this project owns measures BYTES, so a formatting-destructive write is
  invisible to all of them by construction. R34 says the byte-gate is a null COVERAGE oracle; this
  is the same hole one layer out — it is a null DOCUMENT oracle too.

- FIX #2 — I MIS-REPORTED THE DIFFs, TWICE (R14).
  (a) commit:0649 claims ov_SC07_006's 71 non-banks were "ALL PLUMBING, ZERO DIFF". FALSE — I read
      head -6 of the classified file and generalized. It has the same 4 DIFFs as the others.
  (b) I then built the jr guard assuming those 4 were the §53 jr class BECAUSE ov_SC01_077 hosts
      them in _jr_8017A4AC.c / _jr_80182268.c. has_mid_jr is FALSE for all four (33-52 ins, no
      jump table): they merely live in a carved jr-REGION split, which sweeps in every function in
      its address range. HOSTING FILE != FUNCTION CLASS.
  The guard is KEPT (preventive, §53-correct, currently skips 0 — no jr fn is in the extendable
  set) with its docstring corrected to record what it is NOT. The 12 DIFFs (0.19%) are UNDIAGNOSED
  and logged, correctly left as stubs by the gate — not dressed in a story.

- The 283 non-banks: 271 PLUMBING (the loose-typing conflict class + the whale, whose body lives
  in src/shared/func_80144B9C.h so no DEFINE macro exists to expand) + 12 DIFF. Existing tools
  cover the plumbing (cast_call_sites / canon_sig_reconcile / reconcile_tu).
2026-07-16 00:10:12 -06:00
Drew T c0486fe5f8 feat(phase-28 T4): dedup_extend — wire newly-onboarded binaries in; ov_SC07_006 1543/1614 (95.6%)
The 4 SC07 overlays P27 onboarded were byte-clean but NOT citizens: their .c included only
common.h (never ../shared/engine_core.h), so no shared body could reach them, and they
appeared in ZERO dedup groups (1689 groups read "134 binaries", never 138). Each sat at ~80
matched / ~2400 stubs while its siblings were ~2150 matched.

- NEW tools/dedup_extend.py — the missing mode. dedup_propagate is built for CRACK -> AUTHOR
  MACRO -> INSTANTIATE: --auto-from scans INLINE DEFS (planned only 11 here; the ~1600 shared
  bodies are ALREADY DEFINE_func_* macros in engine_core.h) and --addr dies "no source overlay
  has it matched" because no overlay holds an inline def. Extending an existing MACRO-BACKED
  group to a newly-onboarded binary is a different operation and nothing implemented it.

- SAFETY (explicit — this feeds the byte-gate): h_exact is the SHA1 of RAW INSTRUCTION BYTES, so
  two instances sharing one are identical INCLUDING their jal/lui/%lo reloc immediates — same
  callees, same data addresses, same symbols. The body that compiles byte-identically at one
  member does so at the other with NO remap. (Exactly why dup_report calls h_exact "guaranteed
  byte-match" and h_norm "candidate-only".) A bug here can only FAIL TO BANK, never falsely bank.

- REUSE, DON'T REBUILD (R33): owns only the set computation + the registry edit. The splice and
  the gate are harvest_verify verbatim (it already derives each stub's home TU from the corpus
  oracle, chunks + bisects, reverts on failure). h_exact members are byte-identical by
  construction -> the happy path is ~1 build per binary, not one per function.

- RESULT ov_SC07_006: 1543 / 1614 banked = 95.6%, ~0 agent tokens. Stubs 2374 -> 831.
  The 71 non-banks are ALL PLUMBING, ZERO DIFF, in two named classes with existing tools:
    * func_80144B9C "undefined reference" — the whale's body lives in src/shared/func_80144B9C.h
      (the -O0 shared header), not engine_core.h, so no DEFINE macro exists to expand.
    * "conflicting types for D_800A5E60 / func_8012C750 / func_8012C0EC" — the loose-typing
      conflict class (cast_call_sites / canon_sig_reconcile / reconcile_tu already exist for it).

- GATES: R22 make clean && extract-all && check-all -> 140 passed, 0 failed of 140, 0 FAIL lines.
  dedup-check 1840 validated / 0 failed; groups now read "135 members [135 binaries]" (was 134);
  C1 coverage 227211 -> 228754 = exactly +1543. The second oracle accepts the extension.

- Mechanism had been proven by hand first (probe-before-investing): +include + ONE stub ->
  DEFINE_func_80128158() -> ov_SC07_006 built 7ca772be BYTE-IDENTICAL, then reverted.
2026-07-15 23:14:19 -06:00
Drew T 4db79a2060 feat(phase-28 T1b): the B2 family swept — 102/115 banked (88.7%), fleet 67.0 -> 67.7% instr
The family the roadmap recorded as 0/8 ("~0%, structural families do not template" — the
number that rewrote P29's arithmetic to "(cores cracked) x (reach)") banks at 88.7% when
swept with the carve its own exemplar required. ~0 agent tokens.

- SWEEP: jtbl_family_bank.py over the remaining 107 members ->
  {'BANKED': 94, 'gate-fail': 7, 'remap-refuse': 6}. Family total 8 (T1) + 94 = 102/115.
  R22: make clean && extract-all && check-all -> 140 passed, 0 failed of 140, 0 FAIL lines.

- FLEET (measured, make report): instr-weighted 67.0 -> 67.7% (+0.7pp, +97,104 ins);
  distinct-code 47.8 -> 49.4% (+1.6pp); fn-count 82.16 -> 82.19%. 102 x 952 = 97,104 =
  the exact measured instruction delta — the arithmetic reconciles to the byte.

- THE 13-MEMBER TAIL is the predicted shape, and both halves are data for T3:
  * 6 remap-refuse = EXACTLY the family's 6 IMM members (cls_counts PURE 109 / IMM 6).
    imm_map_tier1 REFUSED rather than guessed: "unresolved immediates: [(512,
    'asm-ambiguous')]" — 512 also occurs at a non-differing position, so a blind swap could
    corrupt it. This is the concrete shape of T3's IMM stratum.
  * 7 gate-fail = genuine byte-DIFFs, correctly rejected. Verified to leave NO residue
    (all 7: split_file=none, cfg_refs=0) — no false-bank risk.

- HYGIENE: the 7 "git checkout ... did not match any file" errors are benign (revert of a
  never-tracked path). Verified 0 untracked splits belong to a non-banked member; 91 new
  splits + 3 banked into existing splits = 94.

- SCOPE (P9, unchanged): still n=1 family, and jr is the rarest class (3/163 matched-exemplar
  families). This demonstrates the mechanism at family scale; it does NOT give a rate for the
  PURE/IMM mass (98% of the population). T3 measures the swing number.
2026-07-15 22:34:45 -06:00