Commit Graph

25 Commits

Author SHA1 Message Date
Drew T 4a503fce1e phase-36: S105 harvest f5 — generators R45 derived_pointer_store (known-true 0 alone on two f5 bodies) and R46 set_once_chain (ALL 0 on func_8018FA34); selftest OK; SETUP rows 2026-09-11 13:25:01 -06:00
Drew T ae522dbc49 phase-36: S105 harvest f2 — generator R44 counter_derived_pointer (known-true 0 on e21's start text, 18 on f2's loop 2), R22 extended to same-base offsets, the && read-as-&p refusal in R22/R44 fixed; selftest OK 2026-09-11 11:56:31 -06:00
Drew T 2b1393dd9a phase-36: lever_free_body refuses a strip that unbalances block comments (R43) — e24 found a start text left as invalid C; 7 residue classes had been silently UNSCORED, now named 2026-09-11 03:17:48 -06:00
Drew T aada3bdc2b phase-36: the first minimum-lever bank (func_80177B5C: 1 marked launder instead of 23 levers, 133 bodies); c43/c44/c45/c37 closes with their cross-address copies (delever --port-scan); generator R26 alias_repeated_addresses (known-true: c45's close from its start text) (R22 218/218) 2026-09-10 18:32:46 -06:00
Drew T 01f066923d phase-36: re-draw c21 — func_801397B0 closed (a do-while reference-weight wrapper, on the a4/c15 precedent), 125 bodies; c22's and c28's readings (func_8012E364 at 4, func_8013F350's head irreducible); --try parallel-safe per call with --keep (R22 218/218) 2026-09-10 17:14:30 -06:00
Drew T 96820256ce phase-36: re-draws c24 (func_8012956C: a phantom 4th argument + a switch) and c23 (func_80133784: the exit block inside a real loop, overturning b4's de-loop reading) closed, 252 bodies; R25 trim_arguments; argcheck reads K&R definitions (95 callees were invisible); the selftest asserts every dispatched family is registered (R22 218/218) 2026-09-10 16:45:14 -06:00
Drew T a620e1880f phase-36: generator R24 (the addPrim copy read as a whole word, c20's move) + its regen pass (2 classes, the func_80140D68 header on 140 objects); c13's reading of func_80140958 (43 -> 4, not closed) (R22 218/218) 2026-09-10 15:57:16 -06:00
Drew T 164825b5d8 phase-36: delever_regen — R22+R23 re-run over the whole residue closes 17 classes / 22 bodies with no agent; --try learns header TUs (24 classes had never been scorable) (17,715 → 17,692 sites, R22 218/218)
- tools/delever_regen.py: read-only pass (both starting texts, only the named families, delever_search --try --body,
  one worker per class) + --bank (re-score on the current tree, apply_body_core, propagate); dictionary + SETUP rows
- pass 1: 1169 classes in 127 s, 14 MATCH; the 25 UNSCORED read before banking: 24 were header-TU classes whose
  includer's ../shared include never resolved in --try (fixed; controlled: unchanged body 0, lever-free 32, mutated 1),
  1 a body-local #define (R22/R23 now refuse preprocessor lines); pass 2 over header TUs: 104 judged, 3 MATCH
- banked: 14/14 + 3/3 (two shared headers IDENTICAL on 141 objects each); R23 12 classes, R22 5
- check-all 218 passed 0 failed; lever_census 17,692 marked 0 UNMARKED
2026-09-10 15:36:01 -06:00
Drew T 2e61220bde phase-36: T7 wave c — seven agent closes (c4 c6 c1 c7 c3 c5 c8) + func_8017EEC0's parameter, ~1,000 bodies; generator R23; CI's verbatim_check fixed and wired into tools-health (23,988 → 20,206 sites, R22 218/218)
- closes, each --try 0 then apply-body IDENTICAL + propagate N/N 0 refused: func_80133AB0 (u16 width moves), func_80130D48
  (one call per goto-tail site), func_80135168 (reused temps split + H16 member store), func_80134A74 (widths + join
  statement in both arms), func_80148AFC (implicit handler argument + later operand), func_8015D738 (jump threading:
  re-read + a do-while on precedent, the class raised with Drew), func_80135004 (temp split + argument from its global)
- func_8017EEC0: the uninitialised a0v T4 tus10 left is the parameter (8/8, IDENTICAL)
- CI red since cb2fb5e6d: verbatim_check --strict saw the DECOMPILE-NOW row func_8017EEC0 converted; row removed (one
  row), --update keeps order + UTF-8 (proven equal to the hand fix), verbatim_check --strict now in make tools-health
- delever.split_reused_locals = family R23 (selftest + two refusals; known-true: joint split = the agents' measured 12/26)
- check-all 218 passed 0 failed (twice); lever_census 20,206 marked 0 UNMARKED; Drew: at most five concurrent agents
2026-09-10 14:56:17 -06:00
Drew T 205331765f phase-36: T7 agent c2 — func_8013D8FC closed (the walked-pointer merge), 131 bodies; harvested as generator R22 (24,119 → 23,988 sites, R22 218/218)
- agent c2 (Opus): a second pointer q = p + 5 stepped in lockstep with p kept a second biv alive (loop.c strength
  reduction, -dL 'Cannot eliminate biv'); one pointer lets combine_givs fold every field read onto one base
- bank: apply-body IDENTICAL, propagate 130/130, check-all 218 passed 0 failed, lever_census 23,988 marked 0 UNMARKED
- delever.merge_walked_pointers = family R22 (selftest + two refusal controls; known-true: the agent's start text's
  candidate is its closing body, --try score 0); leads the COUNT class after R19 in delever_search; SETUP row
- S103 opening: the method addendum .run/P36/agents/METHOD_S103.md; wave c launched (six agents); Fable out of credits,
  c5/c6 relaunched on Opus
2026-09-10 14:30:30 -06:00
Drew T d30ccc9a72 phase-36: T7 agent b8 — func_80135888, the largest class left, closed with all five levers gone (134 bodies; 24,789 → 24,119 sites, R22 218/218)
check-all: 218 passed, 0 failed of 218
  lever_census --check: 24,119 pin/asm sites, 24,119 marked !FAKE, 0 UNMARKED — OK

Three moves, each predicted from a dump before it was compiled:
- while -> a guarded do-while (29 to 22). Cross-jump (jump.c:1969 -> find_cross_jump :2371, from toplev.c:3142) had
  matched the load in front of the jump against the one in front of the bottom test and deleted three instructions; the
  guarded form makes the two tails differ.
- the duplicated pre-loop call block -> goto (22 to 6). This is an allocno_compare rank move (global.c:585-611): the
  priority is floor_log2(refs)*refs/live, reg_n_refs is loop-weighted (flow.c:2067), the in-loop copy of that call is
  worth two references, and deleting the out-of-loop copy takes exactly one off — 8 to 7 crosses a floor_log2 step and
  drops the pointer's priority from 3157.9 to 1891.9. The predicted allocation order matched the dump exactly. The
  rewrite is byte-neutral on its own: reorg steals the target's first insn into the delay slot and retargets.
- the two-arm mask temp inlined (6 to 0): set in two arms it has two deaths, fails local-alloc.c:472, and combine_regs
  bails at :1774, so it went to global allocation and took its copy preference.

Harvested as R21 second_consumer, from agents b2 and b6 together: give a computed value a second consumer before its
copy, either by chaining (v = slot = E) or by hoisting the store above it. cse deletes such a copy only when the
producer sits immediately before it (cse.c:7440-7501, guard :7454-7460), and flow links only the FIRST following use
(flow.c:2076-2091), so a store in between defeats both. R9 can never produce it — the two statements share the
identifier, so its independence guard refuses the swap. Known-true: the joint form scores 0 on b6's pre-bank text, and
the single-site forms do not, which is the third measured case this session of a joint edit no hill-climb can reach.

Also recorded from b8, worth a pre-check later: declaration-order moves are PROVABLY DEAD on a register residual whose
allocnos have distinct priorities, because global.c:604-610 compares priority first and only ties by allocno number —
4,811 compiles of those candidates sat flat because of it.
2026-09-10 13:31:47 -06:00
Drew T 9d78fc4085 phase-36: T7 agent b3 — func_8016CBC0 closed from a residual of 55 (128 bodies), and its move toolified as R20
- the move: narrow every local in the counter's def-use chain together — the counter, its +/-1 temp and the copy-back —
  and do it for BOTH chains at once. Four instructions were MISSING, not miscoloured, three of them the moves the $0 pin
  was faking. insert_regs (cse.c:1029-1032, early bail :1018-1020) puts two pseudos in one equivalence class only when
  their MODES match, so an all-int copy-back is collapsed and swept, while the narrowed one is a truncation: no
  equivalence, the wide temp stays live and reaches reload as the move the target has. The fourth instruction is
  strength_reduce minting a shift giv from a wide counter whose every use is a cast; a HImode pseudo cannot be that giv.
  delever --propagate: 127 of 127 sibling(s) banked, 0 refused. 26,202 -> the census below.

- R20 narrow_chains: the agent PROVED the joint form is necessary, and the generator reproduces it. Single declarations
  scored 45/72/51/24, each chain alone 43, both chains together 0 — every intermediate worse than the search's own best
  of 11, so a beam over R12's one-declaration width moves cannot reach the answer from either side. Seven runs and 4,811
  compiles stalled at 11; R20 offers six candidates and the right one is a single compile.
- known-true check: run on b3's pre-bank text, R20's joint signed candidate scores 0 (MATCH) and its single-chain
  candidates score 43 and 51 — the agent's own hand-measured numbers, reproduced by the tool.
- chains are built conservatively from the body's text (two locals linked when one is assigned from the other, through a
  cast or a +/- constant), and only whole components are offered, so the partial narrowings the measurement showed are
  always worse are never generated. Selftest: the chain is found whole, an unlinked local is not pulled in, and a body
  with no linked pair offers nothing.
2026-09-10 12:57:06 -06:00
Drew T f3de70fce5 phase-36: R19 — the argument-restore generator: call signatures become engine work, not agent work
Six T7 agents independently reached score 0 by restoring an argument the decompiled source had dropped, and no generator
could reach the class because every other family rewrites statements that exist while this changes a call's ARITY. R19
closes that gap without cracking anything: it finds every call whose in-scope declaration is narrower than the callee's
real definition, then offers one candidate per value already in scope (each parameter, each local declared before the
call) and lets the byte oracle pick. The missing argument is never inferred.

- known-true check: run on the pre-bank text of func_8017A3D8, which agent a12 solved by hand, R19 emits that agent's
  exact fix and --try scores it 0 (OTHER; mine 53 ins, target 53) — MATCH.
- two spellings were wrong before that passed. It took the return type from the DEFINITION and produced
  ((void (*)(s32))f)(a) != 0, which cannot compile because the defining TU says void where this one says int — it now
  repairs the arity only and keeps the TU's declared return type. And it required a simple statement, so it found
  nothing on the very body it was written from: these calls live in  and  far more often
  than in a plain statement.
- it also sees the cast-wrapped form ((s32 (*)(void))f)(), which is how m2c usually spells a dropped argument, and
  replaces the whole wrapper rather than nesting a second cast.
- ranked FIRST in every residual class: it emits candidates only for calls whose declaration provably disagrees with the
  definition, so it costs nothing when it does not apply. The engine selftest's ordering invariant is updated to say so
  rather than being widened again.
- argcheck now carries each definition's return type, which the cast route needs.
- selftest: two positive assertions and two controls (the declared return type is kept; the definition's is refused; a
  call inside a return statement is seen; a matching declaration offers nothing).
2026-09-10 11:13:34 -06:00
Drew T c6b380fcd0 phase-36: T7 burst — 503 more bodies banked, and the per-file scratch-object collision fixed at its cause
The scorer named its scratch object after the FILE (compile_obj tag="score"), so the nine burst agents sharing one
translation unit wrote and read one object. Two reported it independently without seeing the code: spurious
COMPILE-ERRORs naming an unrelated header, and one agent scoring four candidates against another agent's function. The
tag is now per function. Every landed body was re-verified after the fix and all still score 0; the banks were never at
risk, the agents' intermediate readings were.

- banked: func_801627E8 (132), func_8017A3D8 (118), func_80141874 (119 of 125), func_801345F8 (134). 28,887 -> 27,984.
  lever_census --check: 27,984 pin/asm sites, 27,984 marked !FAKE, 0 UNMARKED — OK
- THE FINDING: the biggest lever class in this phase is a WRONG DECLARATION, not codegen. Four agents independently
  reached score 0 by restoring a call's real arity, each in a different spelling — a function-pointer cast, a widened
  block-scope prototype, a call given its argument, and a definition given its two parameters. The mechanisms differ
  (combine.c:1458's added_sets_2 gate; set_preference global.c:1589 ahead of first-fit at :1001-1015, the argument copy
  becoming a self-move deleted at toplev.c:3142 so it costs zero instructions; assign_parms' parameter home copies) but
  the class is one: a truncated (void) declaration removes an instruction the pin was then hired to fake. No generator
  can reach it — every generator rewrites statements that exist, and this changes a call's arity.
- func_80157D20 does not bank body-only (gcc rejects a block-scope redeclaration), so its Path A joins func_80136824 and
  func_80168828 as the third measured case for the types phase.
- two more new classes, byte-proven: a store sinking past a load because true_dependence's exception (sched.c:837-839)
  discards the edge, fixed by declaring the global an array and storing through [0] to set MEM_IN_STRUCT_P; and a
  post-decrement queued by expand_increment until the next sequence point, fixed by splitting the statement plus a u16
  destination cse refuses to join (cse.c:1017-1019).
- correction to record: an uninitialised register __asm__("$0") is an opaque operand, not a constant holder — R16 must
  refuse it.
- snapshot row 20.
2026-09-10 10:38:24 -06:00
Drew T fb6c857f7c phase-36: the build/ coupling fixed (a baseline snapshot the fleet gate cannot wipe) + T7 agent a4 — func_8016C49C closed by one do-while on the last statement (126 bodies)
Drew: fix the build issue so agents' effort doesn't get wiped, this needs to be parallelizable.

- every score compares a candidate with the fleet run's object under build/, and the R22 gate starts with make clean,
  which deletes exactly that. With agents scoring in parallel, a fleet gate would make every live --try compare against a
  missing or half-written baseline and report nonsense in the agent's own voice.
- fixed at the single accessor: delever_oracle.baseline_path(obj) returns the snapshot under .run/P36/delever/baseline/
  when it holds the object and falls back to build/ when it does not, so nothing silently scores against half a snapshot.
  baseline_bytes and both direct readers in delever_search.py go through it. --snapshot-baseline refreshes it:
  7,428 objects, 188 MB, taken at 9f5b22176. Valid until the fleet stops being green: the baseline is the original game's
  bytes and a bank is byte-identical by construction.
- known-true test both ways: func_800123F0 in src/800.c scores 0 MATCH with build/src/800.o present; the object was moved
  away and it scores 0 MATCH unchanged; restored.
- a4: func_8016C49C from a seed of 34 to score 0 by one move — do { param_1[1] = sVar1; } while (0); on the function's
  LAST statement. The residual was a single qsort comparison in global_alloc lost by 142 units out of 6666 (global.c:546
  sort, :587 priority, :904 first-fit). reg_n_refs is loop-weighted and computed before combine and sched, so the
  reference inside the do-while is counted twice (flow.c:434, :440-443, :2067/:2501/:2711): refs 23->24, priority
  6524->6808 > 6666, the order flips and all 34 words fall into place. A plain block at the same site still scores 34,
  which proves it is the loop notes and not the scope.
  delever --propagate: 125 of 125 sibling(s) banked, 0 refused
  lever_census --check: 28,887 pin/asm sites, 28,887 marked !FAKE, 0 UNMARKED — OK
- two instrument findings to act on: the candidate ranking buried the winning move at 438 of 439 so --cap 48 discarded it
  in six runs (~4,300 compiles), and history.txt's 'R15 sink @2777 -> 1' is not reproducible (the generator's own text
  scores 40) — to be checked against the bytes before either is trusted.
- snapshot row 19.
2026-09-10 10:30:38 -06:00
Drew T 449acd8cb3 phase-36: T7 sweep s4 and the OUT-OF-BODY defect fixed at its cause (R14 refuses what the body-only bank cannot take)
search: 0 of 139 exemplars matched lever-free in 0.54 h (0 of 7,077 bodies behind them; 52,566 compiles) — NO-MATCH 136 · BANK-REFUSED 3

- the three refusals are the three fleet copies of func_80136824, each a real score 0 (R15 sink + R12 width + R14
  param-width) blocked by a contract rather than by a bad body: the engine verifies the whole candidate text but hands
  apply_body_core only the definition, and --propagate remaps that body to siblings, so a generator that edits lines
  outside the definition can never bank. R14 is the only such generator.
- my first diagnosis was wrong and was discarded rather than shipped: I guessed the conflicting declaration was in a
  shared header and built a 2,431-name index to refuse on, and the index said the function is not in it. Reading cmd_run
  gave the real answer.
- two fixes: param_widths refuses outright when the TU declares the function anywhere but at its definition
  (protos_outside_definition; the earlier R14 banks had no such prototype, so nothing that worked is lost), and the engine
  names the condition itself with a new OUT-OF-BODY verdict instead of letting the bank die on a compiler error that reads
  like a bad body. Controls both ways in the selftest.
- the steering measurement (R41): across s1-s4 the head's 57 classes have absorbed ~128,000 compiles for 6 closes, all of
  them R15's and all in the first sweep. The head is resistant to every mechanical generator at this width; sweeps pay on
  the tail and on targeted families, and the head is what agents are for.
- open by name for the types phase: func_80136824 (133 copies) has a real crack that needs its prototype widened with its
  definition — the second measured case where a declaration, not codegen, stands between us and the bytes.
2026-09-10 05:00:01 -06:00
Drew T d71836107c phase-36: T7 agent a3 — func_801397B0 not closed (best 2), its reading toolified as R18 the bystander move
The third agent produced no bank and a precise refutation plus a generator, which is the deliverable the brief asks for.

- it refuted the a2 hypothesis on its own body: git grep returns 1,770 declarations in two forms, both (s32 a0), no (void)
  anywhere, and the pin is on a local rather than the parameter. Three lever-free spellings reach the target's complete
  register assignment, so the class is reachable from plain C.
- its best is score 2, class ORDER, 89/89 instructions, every register correct, one displaced bystander store. The target's
  sw sits inside the lbu->addiu window and that position is forced: anti_dependence and true_dependence (sched.c:817/845)
  both hold, so the store can neither hoist nor sink. Post-sched1 stream and reg_live_length then match ours, leaving
  reg_n_refs — computed by flow on the pre-combine RTL — as the only remaining input.
- R18 moves one simple statement to each other position in its own block, up to six away. R9's adjacent swap is the special
  case; the distance is the point. It costs no instruction where R7's LOOP notes are a full sched1 barrier and always cost
  one displaced insn, so R18 is ranked ahead of R7 in every class.
- two wrong spellings before the known-true check passed: identifier-disjointness as a requirement offered three candidates
  and none of them the agent's (it is only an ordering preference now — byte-identical output is the same program, so the
  oracle is the whole correctness proof, which is R9's own footing), and a blank line counted as an obstacle, so the
  generator never offered the very move it was written from. It now reproduces that body exactly: bystander @21->17.
- delever_pack.py now writes each trace candidate's residual class beside its score, from the agent's method note: a bare
  number hid that a move had already turned this body's residual from REG into ORDER.
- delever --selftest OK (3 new controls incl. the nested-block refusal); delever_search --selftest OK; tool_census OK.
2026-09-10 04:26:00 -06:00
Drew T 975850ff84 phase-36: T7 toolify a2 — generators R16 (constant holder inlined) and R17 (constant-run split), the directed form of a move R9 reached only by luck
- R16 writes a local whose only assignment is one integer literal at every use and deletes it. R6 stops at a temp read
  exactly once, so a holder read four times was invisible to the search and its whole family with it. Deleting it is
  byte-neutral alone but removes a quantity from the block, which is what lets the next move reach the allocator.
- R17 splits a run of consecutive same-literal assignments by moving the nearest differently-valued one into it, at each
  interior split point. find_free_reg's live-range scan (local-alloc.c:2109-2110): while the two constants' ranges are
  disjoint they share a caller-saved register; splitting makes the first live across the second and it takes another colour.
- known-true check: on the seed that keeps func_80168828's semantically-forced $4 pin, R16 then R17 reaches
  score 0 (OTHER; mine 108 ins, target 108) — MATCH at three of the six offered split points, in ten compiles where the
  blind search needed 2,271.
- the engine selftest's caller-saved assertion is now the ordering invariant (every targeted lever before every blind
  family) rather than a fixed window widened once per new generator.
- delever --selftest OK (4 new controls); delever_search --selftest OK; tool_census --check OK; SETUP row (R21).
2026-09-10 01:27:20 -06:00
Drew T 861dd0651c phase-36: T7 toolify a1 — generator R15, the sink (agent a1's crack made mechanical; reproduces it from the pre-bank text at score 0)
The harvest half of the one-at-a-time loop (R16): agent a1's reading of func_80156044 is now a move the engine can make
on any body, so the remaining head classes get it for free.

- R15 sinks the statement AFTER an if/else chain into every arm and deletes the variables it consumed:
  `if (c) { v = e1; } else { v = e2; } w = f(v);` -> `if (c) { w = f(e1); } else { w = f(e2); }`.
- it is a REGISTER move, not a scheduling one. A value set in every arm and read after the merge is a cross-block pseudo
  local-alloc never gives a quantity (local-alloc.c:472, next_qty reset at :517), so the arm holds two quantities and
  takes block_alloc's unrolled case 2 (:1499-1502, qty_compare :1578-1596). Sinking makes it a third block-local
  quantity, and case 3 (:1491-1496) falls through into case 2 and applies that comparison a second time, undoing its own
  exchange — the two caller-saved colours swap. It also takes the value out of global.c, where set_preference
  (global.c:1535+) had given it a copy preference through the merge result's argument copy.
- applicability is checked, never assumed: each consumed variable must be assigned exactly once in every arm by a simple
  statement, appear in the merge statement, and occur nowhere else in the function.
- if_chains() counts a line's CLOSING braces before its opening ones. On a `} else if (...) {` line the two net to zero
  and the first version's depth counter never closed the arm — the generator found 0 candidates on the very body it was
  written from. Caught by running it on that known-true case before believing it.
- ranked third in REG-caller / REG-mixed / COUNT; the engine selftest's "R5 in the first three" assertion widened to
  "R5 and R15 in the first four" rather than de-ranking the new move.
- verified: delever --selftest OK (3 new controls: a variable read after the merge, a variable one arm does not set, the
  brace walk's three arms); delever_search --selftest OK; and the known-true check — R15 run on func_80156044's
  pre-bank text emits the agent's crack and `--try` scores it
  `score 0 (OTHER; mine 74 ins, target 74) — MATCH`.
- SETUP row rewritten (R21), kit corpus regenerated, tool_census --check OK (371 copies + 30 pointers, 0 gaps).
- no src/ change in this commit; the sweep of the other 56 head classes follows.
2026-09-10 00:45:15 -06:00
Drew T 7b2200edad phase-36: the tail pass g6 + g6b (47 + 63 of 400 small classes; 186/191 siblings propagated), R22 218/218; 30,806 → 30,358 sites; --try (a candidate scored without a tree write), delever_pack.py (the 57 T7 packs + PROMPT.md), --restore refuses an empty snapshot; the checkpoint: T7 as one agent at a time, approved, starts in the fresh session 2026-09-09 23:32:57 -06:00
Drew T 2f3ce92a15 phase-36: rung G run g5 — the head re-drawn wide: 5 of 70 (small classes, 62 bodies), R22 218/218; 30,892 → 30,806 sites; the wide-search lever is spent on the big classes (112,216 compiles); R14 rewrites prototypes, R8 names repeated operands/groups, R12 splits multi-declarator lines; C/D-only bodies are done and not drawn, the seed keeps class C/D sites 2026-09-09 22:07:17 -06:00
Drew T 1ec67f6677 phase-36: rung G run g4s — func_8016E9EC's shape closed in three classes (133 bodies, R22 218/218; 31,025 → 30,892 sites); generators R12 widths (u8/short/int), R14 parameter width, R8 shared base, R10 cast alias; the bank and propagation in process (apply_body_core); the per-tag scratch-object race fixed; propagate's empty-list return 2026-09-09 20:18:43 -06:00
Drew T 584031c717 phase-36: rung G generators R10 (parameter copy), R12 (width), R13 (reassociation), R8 common-subexpression; --explain reads a residual as mnemonic blocks; four declaration-run/statement defects fixed; the 6-distance class read: one surviving copy the width move does not reach 2026-09-09 18:28:59 -06:00
Drew T a4cbe0d5a3 phase-36: rung G run g1 — 1 of 16 exemplars (func_801424E4, the count-changing body rung D left at 2) closed by three composed moves, 132 bodies banked + propagated 131/131, R22 218/218; 33,427 → 33,295 sites; R5 skips constant operands (lane B's fold claim verified on bytes); bottom-up order within a file 2026-09-09 18:22:01 -06:00
Drew T 623e553408 phase-36: rung G — tools/delever_search.py, the guided search (the score is the oracle's own object read as an edit distance, the residual classified to pick the move families, a beam composing 2–3 moves; positive controls 1–2 PASS, 3 FAIL on a missing inverse); R8/R9 + the unwrap in delever's generator registry; the 301-row ledger hash defect fixed at its cause and repaired; lane B's residual→move map banked 2026-09-09 18:11:16 -06:00