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.
4.1 KiB
Autopsy — the permuter's failures, classified
Generated by
tools/autopsy.py reportfrom.run/autopsy/residuals.jsonl(built bycollect, which recompiles every open backlog draft throughtools/match_one.pyand classifies the FULL residual withtools/residual_class.py).
A verdict here is a candidate, never a bank: the whole-binary byte-gate remains the sole arbiter (G3/P9).
Corpus: 1752 record(s) · 1659 classified · status {'near': 1354, 'nobuild': 93, 'match': 305}
Buckets — what tool each failure actually wants
| bucket | fns | reach-weighted | meaning |
|---|---|---|---|
| redraft | 699 | 2162 | the stored draft is NOT this function — un-attempted work misfiled as a near-miss; route to a fresh crack, not to a wall |
| structural | 578 | 7761 | local mutation CANNOT introduce it — wants a C-level idiom, not CPU |
| integration | 305 | 2303 | byte-correct standalone; blocked on plumbing (§58/§59 reconcile ladder) |
| permuter | 75 | 740 | local mutation CAN reach it — permuter fuel (a plateau here is a missing-transform candidate) |
| unknown | 2 | 2 | the residue the LLM tier is for |
Classes
| class | fns | reach-weighted | bucket | permuter profile |
|---|---|---|---|---|
| SIZE-MISMATCH | 699 | 2162 | redraft | — |
| LENGTH-DRIFT | 394 | 6380 | structural | — |
| MATCH | 305 | 2303 | integration | — |
| OPCODE-MIXED | 80 | 878 | structural | — |
| WIDTH | 44 | 310 | structural | — |
| IMM-OFFSET | 38 | 38 | structural | — |
| DELAY-SLOT | 23 | 289 | permuter | schedule |
| BRANCH-POLARITY | 22 | 155 | structural | — |
| REGALLOC-PERM | 18 | 151 | permuter | regalloc |
| ADDRESSING | 17 | 150 | permuter | cse |
| IMM-VALUE | 10 | 143 | permuter | cse |
| SCHEDULE-REORDER | 7 | 7 | permuter | schedule |
| MIXED | 2 | 2 | unknown | — |
Top clusters (the batch-autopsy work items)
One representative per signature diagnoses the whole cluster — that is what makes the LLM pass a batch autopsy rather than N per-function reads.
| # | signature | fns | reach-weighted | example |
|---|---|---|---|---|
| 1 | SIZE-MISMATCH/short |
604 | 1801 | func_8017E918 (close=4, 2 ins) |
| 2 | MATCH |
305 | 2303 | func_80168B70 (close=0, 27 ins) |
| 3 | LENGTH-DRIFT/-1? |
116 | 1712 | func_8018312C (close=5, 7 ins) |
| 4 | SIZE-MISMATCH/long |
95 | 361 | func_8017E06C (close=6, 9 ins) |
| 5 | LENGTH-DRIFT/-2? |
70 | 1268 | func_80190480 (close=3, 4 ins) |
| 6 | OPCODE-MIXED |
67 | 599 | func_80161D20 (close=1, 14 ins) |
| 7 | LENGTH-DRIFT/1? |
63 | 595 | func_80187074 (close=4, 7 ins) |
| 8 | LENGTH-DRIFT/2? |
51 | 450 | func_80181B8C (close=5, 11 ins) |
| 9 | LENGTH-DRIFT/-7 |
32 | 32 | func_80184590 (close=9, 2 ins) |
| 10 | LENGTH-DRIFT/+1 |
21 | 21 | func_8017DCE4 (close=3, 8 ins) |
| 11 | IMM-OFFSET/1 |
17 | 17 | func_801827C4 (close=1, 13 ins) |
| 12 | DELAY-SLOT/1 |
13 | 146 | func_8016BA68 (close=1, 29 ins) |
| 13 | BRANCH-POLARITY/bnez!=beqz |
11 | 144 | func_80185E38 (close=1, 12 ins) |
| 14 | IMM-VALUE |
10 | 143 | func_8018A640 (close=2, 4 ins) |
| 15 | WIDTH/lhu!=lh |
9 | 9 | func_80142A10 (close=1, 28 ins) |
| 16 | LENGTH-DRIFT/-3? |
8 | 1072 | func_8012CC88 (close=13, 102 ins) |
| 17 | OPCODE-MIXED/addressing,width |
8 | 274 | func_8017F114 (close=5, 75 ins) |
| 18 | DELAY-SLOT/2 |
8 | 141 | func_80158638 (close=2, 87 ins) |
Second oracle — deterministic verdict vs the recorded label
The recorded klass is what a wave agent typed months ago; the verdict is derived from today's bytes. Neither is authoritative — the disagreement is the finding, and it is exactly the mis-classified bucket (a wrongly-labelled residual sends the directed search at the wrong levers, so it plateaus and then reads as a wall).
- labelled records comparable: 4 · agree 3 · disagree 1
| fn | recorded label | label routes to | measured class | measured routes to |
|---|---|---|---|---|
| func_801549F8 | schedule |
schedule | ADDRESSING | cse |