Commit Graph

921 Commits

Author SHA1 Message Date
Drew T 672431e325 fix(r22+gater): R22 now REFUSES while drafters are live; §372 the copy-capture pair
tools/r22_verify.sh (NEW, promoted from .run so it survives the session):
'make clean' deletes asm/ AND build/, and THREE times this session that raced a
live lane -- a subagent authorised to splice src/800.c produced a FALSE
'212 passed, 1 failed' red, and two drafting agents reported their target's asm/
tree MISSING mid-draft (one survived only by finding an old snapshot). Drafting
agents never WRITE src/, which is exactly why 'check for a dirty tree' does not
catch them: they DEPEND on state this operation destroys. The guard refuses when
any wave scratch dir was touched in the last 6 minutes, names the live agents, and
offers R22_FORCE for a drained lane. R54 -- a guard that is not running is not a
guard, so this refuses instead of relying on me remembering.
Negative-controlled BOTH directions: refuses with 5 live agents named; passes on an
idle lane AND on a lane whose scratch is 30 minutes stale (no false positives).

fix(gater): the in-tree main commit message said '0 fn(s)' for a commit that
contained a real bank. corpus memoizes, so querying corpus.stubs immediately after
the bank returns the STALE pre-bank set. Derive the list from harvest_verify's own
verified-out file instead (R33: derive from the invariant the tool already wrote).

§372 ★★★ THE COPY-CAPTURE PAIR. Tell: a REGALLOC-PERM residual whose wrong-register
rows READ the destination of a nearby MATCHING copy insn. Two passes re-base uses
onto a copy's destination -- cse.c make_regs_eqv (canonical-reg rewrite of later
same-EBB uses) and local-alloc.c optimize_reg_copy_1 (forward-substitution when the
copy's src does not die in it) -- and BOTH die to one zero-byte edit: spell the copy
'P = X + zr' so SET_SRC is a PLUS, which is not a reg-reg copy and records no reg
equivalence, while emitting the byte-identical 'addu $rd,$rs,$zero'.
Notably the escalation was told to CHECK whether §368's tell applied rather than
assume it; it reported that it did NOT (pure shift/slti rows, no commutative
operands) and found the real cause from RTL dumps. That is §361's procedure working.
2026-08-31 18:51:21 -06:00
Drew T 54c0624e49 docs: §371 the module-binary -O0 carve route + the spimdisasm rodata trap; SETUP.md S68 tooling rows (R21)
§371 ★★ carving a SINGLE-OBJECT module binary. One 'unaddressable content'
message was THREE stacked causes (interior-YAML-comment symbol-list truncation, a
trailing verbatim-asm chunk with no region, bare tag forward decls) -- fix one and
the message does not change, which is why it read as an impassable wall.

Then the reusable part: spimdisasm migrates single-referenced rodata into a
function's .s ONLY within the same subseg, so a carve that moves the function
silently DROPS it, and INCLUDE_RODATA cannot bring it back (splat marks it migrated
segment-wide and emits nothing). Rename the .rodata subseg to the object its
emitters moved to; the regenerated .s coming back byte-identical is the proof.

Also recorded: the Makefile -O0 glob hunk is PART of the carve, not a follow-up;
interleave_check's DRIFT on md_MAIN_003 is PRE-EXISTING and must not be 'fixed';
the still-open second-carve refusal (UNOWNED rodata 0x800cedf8); and the §126 plan
for the remaining 8 -O0 stubs (three are ADJACENT so one region covers them).

SETUP.md (R21): three tooling-inventory rows covering gater_lane/escalate_fable/
o0_boundary, the six overlay-layout fixes, and the module-binary carve route.
2026-08-31 18:34:38 -06:00
Drew T 2a0808e3dc docs(cookbook): §370 — a HARD BOUND from sched.c, plus the reorg slot-steal diagnostic
The third fable escalation did NOT close its function (main/func_8001BC6C,
33 -> 28 over ~45 measured compiles), so the checkpoint's '2 for 2' is corrected
to 2 closed of 3. The failure is banked because a negative result that tells
future agents when to STOP is worth its tokens.

THE BOUND: sched.c schedule_select ALWAYS fronts a ready load over an
equal-priority ALU leaf (potential_hazard), so no C spelling can emit an ALU chain
before loads that are simultaneously-ready same-priority leaves. If a target shows
that order, look for reorg slot-steals, hard-reg dependency walls, or late in-block
consumers BEFORE burning compiles on statement permutations.

Also banked: the reorg fill_simple_delay_slots slot-steal diagnostic and its
split-tree precondition (the accumulator must live outside the $v0-heavy tail to
be eligible), three supporting levers, and three REFUTED ones with measurements --
a dead-init boost-kill is a no-op because cse delete_dead_from_cse removes it
before the final reg_scan, dense-block re-ties cost +4 to +9 because each re-tie
re-anchors its own load, and the -fno-schedule-insns oracle does not discriminate
when the residual is a multi-pass composition.

This run applied §361 CORRECTLY -- it removed the prior agent's pin first and
exonerated it for the head -- which is why its four-pass diagnosis can be trusted
where the previous single-tie claim could not.
2026-08-31 17:29:45 -06:00
Drew T 0816ea0576 chore: refresh the backlog + fleet digests after the S68 banks 2026-08-31 17:27:15 -06:00
Drew T 92e3ff9272 docs(cookbook): S68 harvest round 2 — §363-§369, including the reload-remat constant
§363 ★★ the OVERLAY-LAYOUT assumption is a systemic bug class and main is the
     exception that finds it — SIX measured instances, four in one session, each
     of which presented as 'the model wrote bad drafts'. Pass the fact you have
     (corpus.Stub.path/.asm_dir, the Makefile's <b>_OUT/<b>_CHECK_SHA/...); never
     reconstruct it. Two of the six were the SAME tool one call deeper with an
     IDENTICAL symptom, which is what makes a one-layer fix feel complete.
§364 ★ the libgpu P_TAG bitfield spelling is OPT-LEVEL DEPENDENT: required at -O0
     (store_fixed_bit_field fixes the or's operand order), byte-WRONG at -O2
     (MEM_IN_STRUCT_P lets the alias oracle CSE a load across the tag store,
     -4 ins/block). First case where the right answer flips with opt level.
§365 pin BOTH masks or neither (one pin measured 36/34, both -> MATCH)
§366 ★★ group_case_nodes merges STACKED consecutive case labels — give every case
     its own duplicated body and let cross_jump fold them back. The three stacked
     runs were EXACTLY the -25 length drift. First-try MATCH on 360 ins.
§367 reconciling a decl conflict between two drafts for the same TU: match the
     already-banked spelling and adapt the USE SITE; a block-scope shadow works
     for a typedef but NOT for an object.
§368 ★★★ the RELOAD-REMAT CONSTANT — a function-scope single-set local that
     global-alloc cannot color makes reload rematerialize the constant per use and
     choose the register by order_regs_for_reload, reaching registers no
     'register __asm__' pin can (pins measured WORSE). The tell is a
     wrong-register row whose COMMUTATIVE OPERANDS are also swapped.
§369 reuse the compare constant's own variable for a coalescing mask; and
     aggregates take their frame slot at BLOCK ENTRY while scalars take one only at
     &x, so an inner-block pad is a frame ORDERING dial (sharpens §333/§358).

Index: 1020 sections, 14 symptom buckets. Cookbook 383 -> 399.
2026-08-31 17:25:47 -06:00
Drew T c55cebea9b docs(cookbook): S68 harvest — §354-§362, nine sections from the wave and the whale carve
§354 the giv worth-while test as a dial (re-associate the addend into the index
     term; strength_reduce declines and $fp is freed) - ov_SC03_105/func_801824CC
§355 a remapped sibling's SOURCE bias is not its EMITTED bias; gcc re-anchors
     reduced givs, so do NOT hand-shift offsets to match the asm
§356 measure a draft in the TU it will live in: 39 of 43 'undeclared' cc1-fails
     were the standalone probe's environment, not the draft (R35)
§357 one struct pointer, not two - a second source variable builds a THIRD iv
§358 sharpens §333: an UNREFERENCED fixed-size aggregate local is load-bearing;
     expand_decl slots every aggregate, so an unused decl is a frame-layout knob
§359 spell a sign-widen as an explicit two-step function-scoped temp; a single
     (s16) cast and a register pin both measured FAILED
§360 the 'compiler found a shorter equivalent' pair - with its third lever marked
     REFUTED rather than deleted, so nobody re-derives it
§361 ★ a loop-tail byte signature that names its source shape, and the law that a
     'scheduling tie' may be an artifact of your own earlier lever. The prior
     agent's sched1 diagnosis was WRONG and its own hack was the cause.
     Escalation economics: sonnet 229k tokens no bank, fable 74k tokens MATCH.
§362 two traps when a carve moves a stub into the -O0 TU (rollout_o0 goes blind;
     the §8b decl layer conflicts with the shared header on 7 symbols)

Index regenerated: 1013 sections, 14 symptom buckets.
2026-08-31 16:37:35 -06:00
Drew T ed53a68f18 feat(p31 s68): deferred propagation done honestly (2 banked) + seed_ref was offering DEAD TEXT
The S67 FINAL-3 OPEN item, plus the two defects found while doing it.

* fix(dedup_propagate): the tool could not run AT ALL. S67's -j patch wrote
  `os.environ` at module level in the one module that imports `os as _os`, so
  every invocation died with NameError before doing any work. Propagation was
  not deferred, it was impossible. Import-checked the other 7 -j-patched tools.

* propagation, honestly scoped: the real closable set is 11, not 32, derived two
  independent ways that agree (seed_ref exact+same_addr, and a direct corpus
  derivation). The 3,161-entry --auto-from plan over 53 overlays is dedup
  hygiene over already-matched code and closes almost no open stub.
  Applied: 2 banked byte-green (ov_SC04_018 func_80181270, func_80182AF8);
  3 gate-refused and cleanly reverted; 6 blocked with named blockers
  (3 CARRY-FIXABLE, 3 func_80144B9C not-inline-def -> needs the o0 whale carve).
  R22 clean fleet: extract 212/212, check 213 passed 0 failed of 213, rc 0/0/0.
  Frontier 453 -> 451.

* fix(seed_ref): REFUSE targets in LINKED subsegs. The playbook calls this tool
  "the fleet-wide answer" and it reported 82 open stubs with a banked twin --
  43 of them main stubs whose TUs the linker script never references. Any C
  written there compiles, links and leaves the SHA1 green WHETHER OR NOT IT IS
  CORRECT, so a mechanical twin lane fed from that list could have minted up to
  43 gate-green FALSE matches the byte gate cannot see. draw_waves has refused
  these since S66; this oracle did not. The refusal is counted and printed, not
  silent. NC: guarded 39 subset of raw 82, all 43 dropped are main, the non-main
  population is identical.

* wave drawn: .run/S68o1 (24 opus 187-770 ins) + .run/S68m1 (30 main), cards +
  packs + wave_args asserted, queue of 53. Drafting opened at concurrency 5.
2026-08-31 15:59:01 -06:00
Drew T 93ea53217e docs(playbook): a carve writes THREE outputs — merge all three, splice overlays.mk per block, gate jtbl with --r22 2026-08-31 15:17:27 -06:00
Drew T 5bcb322283 docs: gating is fully parallel — no serial lane; jtbl unlocked via isolate_asm; launch detached with setsid 2026-08-31 14:55:39 -06:00
Drew T 3a4eac272e docs(cookbook): §353 -fno-thread-jumps as a pass-identification oracle; launder the value to keep a dead re-test 2026-08-31 14:37:16 -06:00
Drew T 91a622b4c5 docs(cookbook): §352 CRITICAL — two identical zero-byte barriers merge with EACH OTHER, defeating their purpose 2026-08-31 14:34:16 -06:00
Drew T b39db34b56 docs(cookbook): §351 /s is a per-access dial; the base-split spelling; a pin-induced sched1 residual with the remaining door named 2026-08-31 14:33:55 -06:00
Drew T bbddb26e68 docs(cookbook): §350 the zero-byte re-tie also kills sched1's birthing_insn_p boost — attribute WHICH pass it moved 2026-08-31 14:32:30 -06:00
Drew T fcada63ada docs(cookbook): §349 n_times_set>1 on a base pointer defeats both the invariant hoist and the address giv 2026-08-31 14:27:27 -06:00
Drew T 932977cc5a docs(cookbook): §348 base spelling picks the addressing mode (3-insn lui/%lo vs 2-insn addu/lw); §137 refuted on constants 2026-08-31 14:27:10 -06:00
Drew T 6ad89305b8 docs(cookbook): §347/§343 addenda — one variable per purpose (3rd instance); sltiu proves an unsigned return 2026-08-31 14:21:45 -06:00
Drew T 096da8e4ff docs(cookbook): §347 loop regalloc is a declaration-order/live-range dial (no live-range splitting in gcc-2.7.2) 2026-08-31 14:21:25 -06:00
Drew T bd9b9f827d docs(cookbook): §346 COND_EXPR singleton path — c?X:-X negates in place, if/else does not 2026-08-31 14:14:53 -06:00
Drew T 34da91b45e docs(p31 s67): harvest §339-§345 from the 30-workflow streaming burst
Seven sections from 30 single-function opus workflows on 187-297 instruction targets (30/30 MATCH):
 §339 a 2-case switch OMITS gcc's low-bound range test (stmt.c emit_case_nodes) — so slti/bnez
      between two beqs is a COUNT TELL that a case node is missing from your draft
 §340 §194-K corollary: a 'scheduler' residual can be sched.c's ALIAS ORACLE inventing a false
      true-dependence; source order picks the edge's DIRECTION, so reverse it into an anti-dep
      rather than fighting it (10->0, zero bytes; 3 alternatives refuted with reasons)
 §341 an HImode store temp reweights a sched2 tie no statement order can reach
 §342 NEW LAW: a twin's  param cast in a local is NOT byte-neutral when a later param also
      needs a callee-saved reg — and the §333 converse does NOT hold (gcc may already pad the gap)
 §343 decl_prior's fleet MAJORITY can be wrong about the true signature — read the RIVALS.
      Measured: void(s32) x1374 vs the truth s32(s32) x163. The tool is honest, the corpus is wrong.
 §344 raise a biv's global_alloc priority with a zero-byte REFERENCE; a register pin kills LSR
 §345 volatile STORE evicts the MEM from cse and keeps sh; volatile LOAD blocks combine and
      degrades lh into lhu+sll+sra — the qualifier is not symmetric

Also: seed_ref validated on a live A/B. The same 187-ins body cost 102,193 tokens / 476 s in
ov_SC03_107 when the card said 'no banked twin', and 72,077 tokens / 135 s in ov_SC07_006 once the
card carried the twin — 30% fewer tokens, 3.5x faster. A second instance (func_8017F62C) went
63,595 vs 118,485 tokens. others_open=137 on that one exemplar, so it compounds.
2026-08-31 14:14:26 -06:00
Drew T 022d50325a docs(playbook): the pgrep bracket is NOT enough when launch and wait share a shell
Measured a SECOND time in S67, and the first fix was incomplete. A waiter using the bracketed
pattern still matched itself and spun 1h35m, because the same shell command had LAUNCHED the job —
so its own command line carried the unbracketed 'gate_stage.py --binary ov_SC07_007' from the nohup
half. The regex gate_[s]tage.py does not match the literal bracketed text, but it happily matches
the plain text sitting earlier on the same line.

Rule is now: launch and wait in SEPARATE shell invocations, or better, wait on a completion MARKER
the job writes to its own log rather than on process liveness.
2026-08-31 13:51:48 -06:00
Drew T 00812fc62f docs(p31 s67): wave-playbook (the CURRENT pipeline) + seed_ref fix + harvest §333-§338
THE DOC GAP, and it cost tokens this session. `docs/automation-runbook.md` was titled "the
autonomous campaign, as it actually runs" while documenting the RETIRED OpenRouter/ox-alpha system
whose lanes are all deliberately DEAD. The current Claude-wave pipeline existed only as two dense
tooling-inventory rows in SETUP.md — reference, not procedure. Three of this session's costliest
mistakes were procedural and a playbook prevents each:
  * hand-typed a refill target -> invented func_80184F60 (2nd instruction of a matched function), 58k
  * hand-rolled a serial gate loop when parallel_gate existed -> ~1h for what took 103s
  * re-derived a function banked verbatim in ~20 overlays -> 102k

NEW docs/wave-playbook.md — start to finish, each guard paired with the MEASUREMENT that produced it
(that pairing is the part a generic decomp guide cannot have, and the seed of the future template).
automation-runbook.md retitled HISTORICAL with a pointer; SETUP.md §6.9 links the playbook.

NEW tools/seed_ref.py — the cross-TU banked twin, joined on corpus signature hashes (no atlas knn,
~2s fleet-wide), wired into t5_cards.py. FLEET: 87 open stubs have a banked twin; 41 of them sit in
twin_sweep's refusal ledger, invisible to BOTH tools at once. Documents twin_sweep's two holes:
load_sigs covers 141/213 binaries (main, resident, all md_MAIN_* absent), and one curated symbol
name silently disables an entire binary via a bare `except Exception: pass`.
Schema note: seed_ref's binary/fn are the EXEMPLAR's, because api_agent greps src/{binary} for {fn};
naming them after the target would send every agent grepping for itself — caught pre-ship.

HARVEST §333-§338 from the s67o2_1/pool_1 waves:
 §333 frame size is set by DECLARED aggregates, not used ones — an unreferenced trailing local is a
      dial (3 instances; one worth 30 of 32 residual rows)
 §334 a reload spill slot rounds to BIGGEST_ALIGNMENT for align AND size: one 4-byte pseudo grew a
      frame by 16 (82->53)
 §335 `extern u16 A[]` at a variable subscript allocates ~8B/access of dead stack temps that inflate
      the frame with ZERO extra instructions — invisible in a body diff (141->20)
 §336 the §5a barrier goes at the BOTTOM of the twin; find_cross_jump walks BACKWARD
 §337 the CC1-ONLY blocker class: blocker_probe's static oracle says "none" and cc1 still fails
 §338 _sltiu_bounds misreads a non-switch sltiu as a bounds check, over-spanning the table

gate_wave.py now STREAMS both lanes (R55) — it captured output and printed at the end, leaving a
zero-byte log indistinguishable from a hang.
2026-08-31 13:48:56 -06:00
Drew T 21a2212ae3 feat(decomp): S67 main r2 — 1 banked (main 89 -> 88) + §332/§332a toolchain-wall findings
Wave s67m2_1: 7 sonnet agents, 1 MATCH banked, 6 NEAR — but 4 of the 7 are NOT drafting failures:
* func_8005FA94 / func_8005D244 — oracle_reorder.py bypass gives 0/55 and 0/62 diffs: the C is
  byte-correct, the pinned as -O1 cannot emit the §188 epilogue. func_8005D244 is additionally
  libpad pdent3.o, an SDK object owned by psyq_integrate.py — it should never have been drawn.
* func_80062144 / func_8005DBD8 — §332, traced to the compiler sources: gcc-2.7.2 emits a symbolic
  la as ONE atomic length-2 insn (no HIGH/LO_SUM split in this backend), eligible_for_delay requires
  length==1, so it can never fill a jump delay slot; the retail split is ASPSX macro-hopping that
  maspsx does not replicate. Byte-verified by running maspsx over cc1's raw -dS output.
  6 such functions fleet-wide, NONE banked.

§332a records the draw-policy consequence: main's cheap population is spent and the residual is
ENRICHED in toolchain walls, so main's apparent match rate is contamination, not a model signal.
Wall ledger at .run/S67_walls.txt for the --exclude mechanism.
2026-08-31 13:21:01 -06:00
Drew T 6bb3d240fa feat(p31 s67): harvest §325-§331 + gate_wave.py (split jtbl/parallel, both lanes concurrent)
HARVEST — the s67o1/s67m1 wave banked 7 cookbook sections:
* §325 a shared small constant stored twice in the pre-loop block is a LOCAL-ALLOC $s-occupant that
  steals the argument allocno's register — pin the ARGUMENT-derived local, not the constant
  (pinning the constant reached only closeness 15). byte-proven func_80184F18.
* §326 spelling two reads of the same halfword differently (sym[i] vs *(s16*)(base+i*4+2)) yields
  different address rtx and DEFEATS address-CSE, restoring separate %hi/%lo groups. func_8017FAAC.
* §327 a range test must be HImode: with s32 + a (u16) cast gcc PROVES the mask redundant and drops
  the andi — a real -1 length drift that reads as a schedule. +3 levers. func_8017EC34.
* §328 NEW LAW: the volatile alias must be an aliased OBJECT; `*(volatile s32*)&sym` unfolds %lo
  into a separate addiu (+1 ins). func_80181B8C.
* §329 fold-const narrows `(int)s16 & 0xFFF` onto the RAW HImode pseudo, breaking the
  sign-extend/mask register tie; a zero-byte `s32 e = t;` widening temp restores it (30 rows -> 0).
* §330 the NEIGHBOUR-SHAPE lever, four independent instances in one wave — copy an already-banked
  in-TU function's SPELLING before any codegen reasoning (one dissolved 18 REGALLOC-PERM rows in a
  single compile). Corollary: a warm start from another binary is often worth LESS than the
  neighbour 20 lines away.
* §331 OPEN GAP, recorded as unsolved: no lever eliminates an UNWANTED DUPLICATE copy at a
  branch-target block head (main/func_80013154, closeness 12, ~16 iterations, 5 approaches refuted).

TOOLIFY — tools/gate_wave.py: split the batch on the per-draft jtbl predicate, run parallel_gate
and the serial jtbl lane CONCURRENTLY. Measured this session: 4 binaries in 103s wall through
parallel_gate (87/87/88/102s each) vs ~6 min serially; I had gated all 16 serially to protect ONE
jtbl draft, ~1 hour. The split precedes the run because a jtbl worker does NOT fail cleanly — it
re-extracts through the worktree's asm/ symlink and writes the MAIN tree while other workers read it.

Its own negative control found two defects in it before first use:
  * listdir counted gate_stage's _xform output dirs (-cn/-cast/-rc/-sd, written as SIBLINGS inside
    the drafts root) as binaries: 20 "binaries" for a 16-binary wave. Now validated against
    progress.BINARIES and refused loudly (R32/R43).
  * a post-hoc control over BANKED functions cannot reproduce a split (has_jtbl has no stub to read);
    re-controlled against a live draft set, where it correctly routes the two functions the gate had
    independently reported CARVE-REFUSED.
2026-08-31 12:44:13 -06:00
Drew T bac7537564 fix(p31 s67): repair ov_SC04_018 — dedup_propagate deleted a decl layer the surviving bodies needed
R22 caught it: 212/213 after the S67-cc1 gate run. `ov_SC04_018` was RED.

ROOT CAUSE (from the diff, not inferred). Commit commit:3354's propagation replaced three bodies in
`ov_SC04_018_jr_80135D20.c` with DEFINE_func_*() instantiations and deleted the 981 lines they
occupied — INCLUDING the TU's file-scope declaration layer, which the two surviving non-deduped
bodies still referenced. A duplicate copy of those decls survived at line 225, BELOW the function
that uses them at line 42, so C89 ordering made it fatal (`D_8018D7A4' undeclared).

THE STRUCTURAL GAP: gate_stage byte-gates the SOURCE binary, then propagation writes to N OTHER
binaries and nothing re-verifies them. "fleet 99.2%" in the commit subject is a metric, not a gate.
This is the blind spot R50 exists for, and only the periodic whole-fleet R22 could see it.

REPAIR: restored src/ov_SC04_018 to commit:3354^, re-extracted (banking had pruned the .s stubs the
restored INCLUDE_ASM lines need), rebuilt rc=0 at the locked SHA fe9b413f. dedup-check clean
(2193 validated, 0 failed, C1 255302/255302). Cost: the 2 banks in that binary.

NEW tools/restore_dropped_decls.py — compiler-driven recovery for this failure mode: build, read
which identifiers cc1 calls undeclared, look each one up in the pre-deletion git ref, insert it
above the leading #include block, repeat. Two defects found and fixed in it while using it:
  * anchoring after "the last extern in the first 400 lines" inserts BELOW the point of use, so the
    build fails identically and the loop re-inserts forever (measured: 25 rounds, 100 dead decls).
    The only safe anchor is the top of the file.
  * a no-progress guard now REFUSES when a round asks for what the last round already inserted.
It also correctly refused when the failure changed class (link-level undefined references), which
is how the wider damage was found rather than papered over.

NOT a defect of the S67 §8d rung: scope_demote_drafts only ever writes draft dirs under .run/.

FLEET: make clean + extract-all + check-all = 213 passed, 0 failed of 213.
FRONTIER: 530 -> 526 (4 functions closed this session, measured from corpus.stubs).
2026-08-31 09:44:50 -06:00
Drew T c4380c19e4 feat(p31 s67): stranded-draft census + honest jtbl probe — the frontier's biggest class is carve plumbing
MEASURED (denominators in .run/S67_findings.md):
* 193 of the 530 open functions ALREADY have a draft on disk (1,885 wave targets seen,
  1,521 banked, 171 open-no-draft, 166 never drawn). Classified in their real TUs:
  37 MATCH / 67 NEAR / 89 CC1-FAIL.
* 159 open functions (30% of the frontier) reference a jump table; 96 are PLAN-REFUSED
  by build_carve (non-contiguous same-subseg .rodata), 75 non-main across 38 subsegs.
  Not a codegen wall and not a decl wall — carve plumbing.

NEW
* tools/strand_census.py — coverage-asserted census + rtu_match classifier + draft staging.
  Keys binary:fn (R48); classifies each pair once after merging every manifest's view.
* tools/o0_detect.py — the -O0 prologue tell extracted from match_one (which parses argv at
  import and therefore cannot be imported). match_one re-exports it; ONE definition (R33).
  Wiring it into the classifier turned md_MAIN_003 from 8 NEAR (7 of them >20) into 6 MATCH.
  Negative-controlled both directions.
* tools/scope_demote_drafts.py — §8d as an _xform-contract gate rung. NOT yet exercised.

FIXED
* jtbl_carve --probe now runs build_carve (a pure planner) and reports plan-refused. It
  previously called only island_probe, which answers a necessary-not-sufficient question —
  every blocked function probed "carveable", and S66 priced 32 of them as free on that.
* blocker_probe.macro_scope selects the LAST #define per macro name, matching cpp.
  engine_core.h has 1,037 duplicate DEFINE_func_ names and 4 with DIFFERENT bodies.

NOT VALIDATED — DO NOT SCALE
* jr_isolate_all: two real defects fixed (carried types deduped by name; header-provided
  types no longer re-emitted) but ov_SC02_000 STILL fails the byte gate after them.
  Open lead: file_scope_types carries a block without its enclosing #if guard. 20 of 35
  blocked overlays dry-run clean and that number means nothing until one round-trips.

0 functions banked this session. tools-health has ONE pre-existing cdecl defect
(1 of 74,749 declarations, func_8017EE08_p55352/struct ZnRec) — cdecl.py and its inputs
are byte-identical to HEAD, so it is not from this change.

Knowledge banked: cookbook §322/§323/§323a/§323b, decision-log pivot, accelerators #13/#14.
2026-08-31 01:46:16 -06:00
Drew T d343892b4c chore: --only-main draw mode + progress/backlog refresh after the S66 gates
draw_waves.py gains --only-main (the main lane draws main and nothing else; implies --main so the
LINKED refusal still applies). Progress/backlog regenerated: fleet 99.2% instruction-weighted,
98.1% distinct.
2026-08-31 00:00:37 -06:00
Drew T 7f75442b67 docs(cookbook): S66 round 6 — §320 breaks the §43/§183 'return-type flip' wall, §321 typedef identity
From the two cast-at-use reconcile lanes (27 agents on drafts the gate DROPPED for in-TU decl
conflicts, not codegen). 24 reconciled to MATCH, 19 banked.

§320 — §43 and §183 item 4 both record the return-type flip pair (TU says void, body materializes
$v0 on every exit) as TU-EDIT-REQUIRED IMMOVABLE. It is not: three agents broke it three ways in a
single lane, each byte-proven.
  1. §202 asm-label alias — s32 aF800CCBC0(void) __asm__("func_800CCBC0") — TU untouched
     (func_800CCBC0 138/138 first try; func_800D30D0 76/76).
  2. register $2 + input-only asm barrier before a bare return, with the early exit routed through
     a goto to a SHARED label — measured bound: inline in the if body is NEAR closeness 10, shared
     exit is MATCH (func_800D2A24).
  3. Adopt the TU's own old-style K&R decl rather than writing a prototype (func_800CB1CC 47/47).
Plus: when every caller discards the result a TU void->s32 widening IS byte-neutral, but MEASURE it
(null-draft rebuild must still give 143dbb89…) — done twice here. And the process trap that cost a
pass: gate_main snapshots and RESTORES the TU between passes, so an uncommitted TU edit is reverted
before the gate sees it.

§321 — two anonymous struct typedefs are distinct types to gcc-2.7.2 even when spelled identically,
so a file-scope duplicate is fatal while the SAME TEXT at block scope is only a warning and is
codegen-neutral. Three dials, all byte-proven: demote to block scope; or hoist and delete the local
copy; or name a local typedef for its OWN address (SVEC_8017E07C, not a neighbour's SVEC_8017E158).
Not a cast-at-use case — the conflict is type IDENTITY, not width.
2026-08-31 00:00:08 -06:00
Drew T f5d2cd017e docs(cookbook): S66 harvest round 4 — 1 NEW, 5 addenda from the O31 lane
9 mechanism-advertising transcripts of 19, from the session's hardest draw (23 of 25 over 120 ins)
and the first wave whose packs auto-carried the residual class's cookbook bucket. 16/16 agents.

§319 (NEW) — duplicate 'return v;' tails let combine fold the OR into $v0.

The sharpest addendum extends §164-26 (func_8017D89C). That section closes 'It is the only spelling
that reaches it' about the 2-D extern retype, and §185b hardens the failure into a recorded blocker
— so a function whose TU forbids the retype was written off. A THIRD spelling reaches the same
no-movable state with no retype at all: do the address arithmetic in INTEGER space and cast,
*(s32*)((s32)SYM + (j<<2)). The array never decays, expand_expr's ARRAY_REF case is never entered,
no ADDR_EXPR base pseudo is emitted, and scan_loop has nothing to record. §164-26's own byte-refuted
control stays valid and is the discriminator: *(char**)(SYM + b*8) still hoists, because
pointer_int_sum rebuilds it as a pointer add — a cast to s32 BEFORE the add is not the same edit as
a cast to char** AFTER it.

That addendum also records a second, cheaper tell: instead of counting the frame for an extra
callee-saved register, look for a DISTANT straight-line read of the same array's element 0 coming
out as 3 instructions (lui/addiu/lw 0()) where the clean 2-instruction lui %hi / lw %lo fold belongs
— the loop's subscript form corrupts an unrelated access blocks earlier. Closeness 37 -> 4 from that
one respelling, with a different-symbol control proving the loop is the cause.
2026-08-30 18:49:56 -06:00
Drew T cd3a87ceba docs(cookbook): S66 harvest round 3 — 5 addenda, 1 refutation, 2 retrieval failures
11 mechanism-advertising transcripts of 30 from the M2 (main) + O21 (overlay) lanes. 19/19 agents.

The addenda sharpen four residual classes with byte evidence: the static local_type blocker is
TEXTUAL and survives typedef removal (func_801588CC); an orphan sh triplet to $sp is a write-only
local array (func_8017F274); a REGALLOC-PERM store reading the narrow copy's register splits with a
second temp (func_801838CC); and a REGALLOC-PERM store inside a CROSS-JUMP SHARED TAIL defeats
§137's barrier method entirely, because the barrier reschedules the whole shared block instead of
the one pair (func_8017EDE8) — that last one is a real scope limit on an existing technique.

TWO RETRIEVAL FAILURES recorded as such, not as news: func_800CDBA8 and func_800CB00C re-derived
banked laws (§165-19/§162d1/§30#3 birthing-boost; the §135-1/§165-28 unsigned-switch-selector rule)
by grinding match_one, with an empty cookbook_refs_used — i.e. they never grepped the index. The
book's own guidance says a high COVERED rate is a signal to fix RETRIEVAL rather than write more
prose, so these are logged where the next reader will see them.
2026-08-30 17:20:01 -06:00
Drew T ae34a46dba docs(cookbook): S66 harvest round 2 — the M1/O1 resume transcripts
7 mechanism-advertising transcripts of 32, extracted then adversarially novelty-verified.
11/11 agents, 0 errors. Verdicts: 2 ADDENDUM, 1 COVERED, 1 REFUTED.

The valuable one is a POLARITY SCOPE on §167-05 (func_80182538). §167-05 sits on the mirror-image
site — same address class (one base pseudo, two disjoint u16 offsets, memrefs_conflict_p = 0),
literally the same 0x6/0xA offsets — and its headline says no statement order, no register pin and
no scope edit can create the scheduling edge. That is true only in ITS direction: you need the edge
to keep a load BELOW a store. When the target wants the load ABOVE an unrelated sibling store, both
orders are legal, rank_for_schedule falls through to INSN_LUID (§49), and plain statement order is
the whole dial, for free. Without this scoping a future agent reads §167-05's 20-variant plateau and
wrongly concludes statement order is inert on this cell. closeness 3 -> 0 by hoisting the sibling
load to its own statement above the store.

Also §211/§17 applied-existing on func_80180FF4: once nins is right, a whole-function $sN swap means
two values live across the same jal became global allocnos, and global.c's allocno_compare density
sort is not obliged to match the target — only an explicit register pin on the crossing value
overrides it. Reconfirmed on a PARAMETER rather than a plain local.

Index regenerated: 946 sections.
2026-08-30 16:09:02 -06:00
Drew T a1024ab76d docs(cookbook): S66 harvest — 4 NEW sections, 15 addenda, 1 refutation
Distilled from 35 wave transcripts (12 byte-proven, 23 drafted-but-ungated and marked UNPROVEN),
each extracted then adversarially novelty-verified against the book. 57/57 agents, 0 errors.
Verdicts: 4 NEW, 15 ADDENDUM, 6 COVERED (rediscoveries — the signal to fix RETRIEVAL, not to write
more prose), 1 REFUTED.

The NEW laws:
  §315  all-constant aggregate fill emits in SHARED-LITERAL GROUPS x destination order
  §316  IMM-OFFSET-only residual: early "return 0" guards skip the flag test
  §317  a narrow struct-field store distributes the truncation (convert.c convert_to_integer
        trunc1), minting a HImode copy whose source cse rewrites to the equivalent constant --
        so a LIVE variable becomes an immediate load. Fix: route the arithmetic through a FRESH
        s32 temp. Byte-proven func_8017EF94 (293->292 ins, closeness 73 -> MATCH); the control
        that reused an EXISTING scratch var regressed to 63, so freshness is the lever.
  §318  a unary minus stored back into the same halfword is computed in HImode (lhu)

Notable addendum: §167-12's own scope note asked for a byte-proven instance of the single-operand
volatile keepalive; func_8017F498 supplies it (closeness 2 -> MATCH, 99 ins), and extends the tell
from unary ops to a three-operand non-commutative subu whose dest ties its PINNED source.

This is the step I skipped for eight waves. Drew: harvesting is the project thesis, not hygiene --
new idioms make the next exemplars cheaper and mint free banks.
2026-08-30 14:41:50 -06:00
Drew T 45cf37ee02 docs: refresh progress/backlog after the S66 gates (260 fns closed, fleet 213/213) 2026-08-30 14:28:10 -06:00
Drew T 5ef1c0e615 docs(cookbook): S65 full-session harvest — 14 transcripts from 12 waves, 7 banked, 7 refuted as rediscoveries
Step 6 of the wave-closing sequence had not run since t5t. This is that backlog: every wave from t5u
to t8b, 139 transcripts, 14 carrying a novelty signal, each distilled and then adversarially verified
against this book before anything was written.

Verdicts: 7 COVERED, 6 ADDENDUM, 1 NEW (section 314).

The COVERED half is the point, not a loss. The verifiers did real work: the "3 new levers" claimed on
func_80183DA4 were traced to 164-71 + 30 stating the identical composite law (scalar decl places the
frame slot at &-time, COMPONENT_REF keeps MEM_IN_STRUCT_P) with a byte-evidenced worked example, and
the claimed-new delay-slot polarity on func_800CAEC0 turned out to REFINE the 220 S64 addendum rather
than contradict it — that addendum's "polarity means aliasing, never arity" holds only when the draft
has a pin or named alias, which this one did not. That bound is now stated.

Four entries are marked UNPROVEN: they come from drafts the whole-binary gate REFUSED, so the lever
moved match_one's closeness but no byte-equality is claimed (R14/G3). Section 314 is one of them — the
abs-range if/else-if wall, with four structurally different C rewrites measured byte-identical.

Index 921 -> 922 sections, green.
2026-08-29 20:43:08 -06:00
Drew T 3ca7e00d81 docs: recovery queue — the step-2 lane I skipped for 12 waves, classified and QUEUED
wave-harvest-is-a-pipeline-step step 2 (RECOVER the failure set: near-misses, gate-drops, errored
cards) ran for NO wave this session, nor for the earlier t5b-t5r waves. This is that backlog, built
and classified but deliberately NOT run (Drew, S65: queue it for next session).

69 unbanked wave targets: 47 with a draft on disk, 22 errored with none.
  Lane A  14 GATE-DROPS  — match_one MATCH, gate refused: integration/JTBL_PADS, probe first ($0).
                           Includes ov_MAIN_012:func_80144B9C at 770 ins, the largest recoverable item.
  Lane B  33 NEAR-MISSES — closest are closeness 1, 2, 2, 2, 2, 2, 3, 4, 4, 5. The S65 pack builder
                           now embeds the measured residual, so a redraft starts from the diff.
  Lane C  22 ERRORED     — no draft was ever written (rate limits); these are not failures at all.
2026-08-29 20:29:34 -06:00
Drew T d804449be5 fix(distill): carry banked=False through to the distiller and the verifier
The distill prompt asserted 'the whole-binary byte-gate ACCEPTED the final draft, so the final body is
ground truth' for EVERY target. With --with-unbanked now feeding it drafts the gate REFUSED, that
sentence would have laundered an unproven body into a byte-proven cookbook entry (R14/G3). A target
with banked=False now gets an explicit PROVENANCE WARNING telling the distiller to extract the lever
anyway (cookbook 52: a model that FAILS still distils the idiom that cracks its siblings) but to mark
every claim UNPROVEN and never assert byte-equality; the verifier is told the same so its
entry_markdown carries the label. Exercised this session: the one surviving ADDENDUM came from an
unbanked draft and is filed UNPROVEN.

Also regenerates the scoreboard after the day's banks.
2026-08-29 19:03:28 -06:00
Drew T 1725d19ecb docs(cookbook): §165-03 addendum (asm-free EQ-channel dial, UNPROVEN) + a §5a FINDABILITY addendum
The t5s/t5t distill returned three 'new lever' claims and the verifier REFUTED two as rediscoveries:
  * func_8017E044's zero-byte __asm__ against reorg's delay-slot steal IS §5a/§34 (+§164-33/§164-36),
    already indexed at cookbook-index.md:22;
  * func_8017C014's ternary-vs-if-chain LICM effect is the loop.c movable gate (REG_N_SETS==1)
    already documented for a recomputed CONSTANT — here firing on a computed loop-invariant EXPR.
Only func_8017EB30's survived, as an ADDENDUM to §165-03 — and the verifier proved it by reading the
target .s itself: the same 279-ins template, same //, as §165-03's byte-proven sibling
func_8017F2D4 in the adjacent overlay. Filed with its UNPROVEN label intact (that draft did not pass
the whole-binary gate — R14/G3).

THE REAL FINDING is the rediscovery rate, so §5a gains a FINDABILITY addendum: the law was there and
the agent could not find it, because the index states the symptom as 'gcc stole an instruction into a
branch delay slot that the target leaves as nop' and what the agent actually SAW was LENGTH-DRIFT/1
at closeness 45, an extra j absent from the target, and a DUPLICATED store — the nop never appeared
in its diff at all. The addendum indexes those three alternate tells. Same shape as S64's §41
addendum: the knowledge base's gap is retrieval, not content.

Index 921 sections, green.
2026-08-29 16:03:12 -06:00
Drew T 201c683325 docs(report): regenerate the scoreboard + backlog after t5s and the S65 recovery banks 2026-08-29 13:42:01 -06:00
Drew T 6ed0f77b6a fix(recover): gate the RAW draft first — macro-externs is a fallback, not the measurement (+ classify_fail drops orphan notes); cookbook §313
recover_integration's macro-externs stage rewrote a draft's callee extern to the FLEET macro's
signature and then gated only the rewrite. func_ADDR names are per-address, not per-function, so
another overlay's 'extern void func_8017C338(void)' replaced this overlay's correct 4-arg decl and
manufactured the CC1-FAIL it reported as the draft's failure. The untouched draft banks
byte-identical (ov_SC03_012:func_8017BEBC, 246 ins, banked in the previous commit).

reconcile_and_gate(draft_rewrite=) now gates raw (pass 1a) then rewrites only what raw refused
(pass 1b), records the winning variant per fn, and re-gates that variant in pass 2.

harvest_verify.classify_fail kept the 'note:' half of a benign warning pair and labelled a built
draft CC1-FAIL with it; notes now drop with their warnings. Negative-controlled over 5 diagnostic
shapes — only warning+note-only changed (to the honest no-diagnostic label). R39/R57/R32.

Cookbook 920 -> 921 sections, index green.
2026-08-29 12:26:02 -06:00
Drew T c5a60897bc docs(cookbook): §312 (a bare if(a<b) scatters the slt destination register — materialize the compare to force it) + a §41 FINDABILITY addendum. The 741-ins agent's headline 'new lever' was VERIFIED AS ALREADY-COVERED by §41 step 3 (cast a type-changed param at its uses, never via an intermediate local); the real gap was that §41's declaration-wall title hides its REGALLOC symptom, so the key is filed there with the n7/n9/n10 byte ladder incl. the inert decl-order control (§67). Index 919 -> 920 (P31 S64) 2026-08-29 11:50:44 -06:00
Drew T 1bdd62455e docs(report): regenerate the fleet scoreboard after t5o-t5r + the 741-ins bank 2026-08-29 11:44:42 -06:00
Drew T 1856524bec docs(report): regenerate the fleet scoreboard after t5m/t5n (1,968 -> 1,741 stubs; 98.7% instr / 97.3% distinct) 2026-08-27 14:05:55 -06:00
Drew T ba7afeed34 docs(cookbook): 2 NEW + 3 addenda from the t5j-t5m distill — §310 (a subu's dest ties only to the block-local operand), §311 (a same-lvalue if/else store must be DUPLICATED into both arms: sched1 runs before cross-jump, so a join-block store swallows the arm's load-delay nop; cross_jump refunds the duplicate so it is byte-free), + §220/§164-29/§164-39 addenda. NOTE: the §164-39 addendum REJECTS the drafting agent's 'integer width' claim — the byte-check shows comparison OPERAND ORDER is the lever. Index 917 -> 919 (P31 S64) 2026-08-27 13:47:39 -06:00
Drew T e5956d021f docs(report): progress.md regenerated with the S63 scoreboard 2026-08-27 11:33:02 -06:00
Drew T e268956de6 docs(report): regenerate the fleet scoreboard after t5g/t5i 2026-08-27 11:31:57 -06:00
Drew T 0edd7344c2 docs(cookbook): 3 NEW sections + 2 addenda from the t5e-t5i distill — §308/§308a (a target's lone j+nop over one self-terminating block survives ONLY behind a tautological re-test; a plain goto/polarity flip DELETES it — closeness EXPLODING after a polarity edit means an edge was removed; two overlays, independently derived), §309 (a frame-address equivalence rides through a -fcse-skip-blocks conditional; duplicating the call into both arms barriers it, cross-jump merges them back), §264 + §195-L addenda. Index 914 -> 917 2026-08-27 11:28:58 -06:00
Drew T 689bbc7c2f docs(report): regenerate the fleet scoreboard after t5b-t5h + the free lane (2,310 -> 2,068 stubs; 98.6% instr / 97.1% distinct) 2026-08-27 09:43:27 -06:00
Drew T 1180748502 docs(cookbook): 3 byte-proven addenda from the t5b-t5d distill — §211's guard-hoist INVERTS on a reg-reg copy (LENGTH-DRIFT -1; use the §164-36a fence instead, func_8017DD80); §194-M third instance + new residual shape (func_80182420); §176-B B1 sharpened (func_80180B44). 2 more verdicts COVERED. Index green at 914 (P31 S63 T5.5) 2026-08-26 21:42:47 -06:00
Drew T 926fc3f1c0 docs(cookbook): §307 — the brute-force-statement-orders lever has a BYTE-EVIDENCED BOUND (12/12 permutations byte-identical on func_8001BC6C, corroborated on func_80021284); a fan-out copy's priority is rank_for_schedule-internal, unreachable from source order — recognise the all-same-closeness tell and route to the permuter. Plus t5_distill_args --novel-only (P31 S63 T5.5) 2026-08-26 21:33:45 -06:00
Drew T 3ae63a9b2c docs(cookbook): §164-55 addendum from the t5a distill (byte-proven func_8017E2CC) — a single-constant arm written FIRST collapses into the branch delay slot; hoisting it instead pays §76's callee-saved pair; index rebuilt (P31 S63 T5.5) 2026-08-26 20:50:25 -06:00
Drew T 59bb3a23f8 docs(report): regenerate the fleet scoreboard after t5a + lane G (R32 digest describes the tree again) 2026-08-26 20:26:01 -06:00