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).
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.
The permuter-autopsy prerequisite (Drew-directed). Captures the WHAT/WHERE of every
non-match so the classifier/autopsy (Task-13) can mine it, not just a scalar closeness:
- masked_diff.structured_diff(): the per-instruction masked residual [(idx,mine,tgt),...]
- match_one --json: emits {status,closeness,nins,residual} (refactored to share the primitive)
- backlog FIELDS += residual, passes_tried
- gate_stage.match_one_closeness returns + logs the residual on every near/fail (verified
end-to-end: a near-miss's structured residual now lands in backlog.jsonl)
- grinder: durably save the winning C to .run/permuter-winners/ BEFORE gate_stage banks
(this session's lesson — 3 permuter wins were lost to a mid-flight revert)
A study substrate (UNIVERSAL/COMPILER-CLASS/BFM-SPECIFIC tagged) for a future Fable
pass to refine into a general roadmap for any-platform/any-compiler decomps. §7 adds
the permuter-failure-autopsy loop (mine failures -> extend the ILS wrapper -> shrink
LLM to genuine humps) per Drew's 2026-07-20 direction. Companion to Tasks 12-14.
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).
Previously only auto-isolated on NON-CONTIGUOUS carve collisions; the span-fit
wall ('table starts do not fit the span', when --like's merged span doesn't match
a sibling's jtbl layout) fell through to carve-fail. jr_isolate unblocks it too
(byte-proven: func_8017AE2C ov_SC01_000 member BANKED). The distinct table-count-
drift error ('more rodata .align than pad specs') stays excluded (not isolate-fixable).
The --hseq path templated from pick_exemplar's choice (hard-prefers ov_SC01_077),
silently ignoring --source (wave-2 finding). Now when --source names a different
overlay carrying a MATCHED member of a family, template from IT (self-correcting:
only a non-stub source member is used; whole-binary gate stays the arbiter). The
ov077-default path is unchanged (override skipped).
Propagated the func_8015C32C jump-table exemplar to 110 more overlays via
jtbl_family_bank (carve + ld_interleave + remap, per-sibling whole-binary gated).
Run halted by an uncaught exception at member 111 (ov_SC06_018); 110/119 attempted
banked clean. Remaining ~19 members to follow.
First jtbl core of crack-wave3: gcc emits the switch jump table into .rodata, so
each overlay needs jtbl_carve + ld_interleave. Path validated 9/9 BANKED.
- func_8016B234: §58b self-def — engine_core.h func_8016B234 (void)->() no-proto
(byte-neutral: only 0-arg callers fleet-wide); typedef preamble stripped.
- func_8016C998: §59(1) local struct rename Slot/Blk32->Slot_998/Blk32_998
(collide with TU's Slot) + D_801D9CA0 extern moved to block scope (TU's other
decls of it are all block-scope; a file-scope one collided).
R22 clean-fleet pending (engine_core.h touched).
Exemplar cast (§56b) unblocked propagation: the bare func_80161208(p) call
relied on ov_SC01_077's no-proto decl, but member TUs carry a (void) prototype.
Casting the call member-proofs the templated body. All banks whole-binary byte-gated.