Commit Graph

937 Commits

Author SHA1 Message Date
Drew T 2f916b269d docs(cookbook): §395 — five narrowing/placement levers from the reach-6 exemplar crack 2026-09-01 13:57:34 -06:00
Drew T f8e522ea0d docs(cookbook): §378b — the four decl-blocker variants, and the two places §378 does NOT apply
Correcting my own guidance from earlier today. §378 gave the self-caller chain;
three more variants appeared within hours and two of them BREAK the chain.

Variant 3 (NEW, byte-proven ov_SC04_018/func_8017F35C, banked): conflicting
RETURN type on a decl that is ALREADY no-proto, where the symbol is
ADDRESS-TAKEN rather than called. --any-proto has nothing to relax and
cast_self_callers has no call site to cast; --sync-decls ALONE fixes it, and is
safe precisely because an address-taken site has no arguments to convert.

Variant 4 (REFUTATION of what I wrote in the playbook this morning): "run the
same chain on the callee the diagnostic names" is wrong at scale. Applied to
func_8012AD44 in ov_SC07_000 it no-protoed 60 caller decls and the binary went
RED (265b24bb vs 9dbe4241); reverted via journal. The self case is safe because
step 2 casts the call sites so the decl change cannot alter argument conversion;
for a callee, cast_self_callers correctly refuses and the decl change runs
unprotected. It banked main/func_80021D38 only because that callee had ONE decl,
not sixty.

Rule added: never --any-proto a symbol whose call sites you are not also casting;
count the sites first. The chain is a DECISION TABLE, not a sequence to run
blindly.
2026-09-01 13:34:21 -06:00
Drew T 34249a4696 docs(cookbook): §392-§394 — harvest the 7 sonnet overlay waves (105 agents, 57 MATCHes)
The hard gate caught me: m1/m2 (§379-§383) and the fable escalation (§385-§388)
were harvested, but o1-o4 and p1-p3 were not — 57 MATCH notes sat unbanked while
I was about to draw new waves.

§392 — seven byte-proven spelling levers, each of which closed a match on its own:
  (a) a same-address dual-sign read is fixed by ORDER (emit the unsigned
      store-source read first); cse merges lh/lhu for every cast spelling tried
  (b) a narrow temp picks the narrow load — s16 vs s32 decides lh vs lhu, and a
      signed decrement temp yields "sll 16" where unsigned yields "andi 0xFFFF"
  (c) tbl[idx-2] folds -8 into the lw offset; hoisting the subtract forces addiu
  (d) identical switch arms must be SEPARATE case blocks — the target duplicates
      arg setup per case and cross-jump-merges only the shared tail
  (e) distinct pseudos per repeated inline copy — one shared pair biases sched1's
      tie-break for the first copy only
  (f) split the widen into two statements to move the sll off a pinned register
  (g) the RETURN TYPE alone closed a 7-ins schedule residual (s32 -> void)

§393 — the BIRTHING BOOST: a single-set local gets max scheduling priority and
sched2's backward pass pushes it LATE; a zero-byte re-tie gives it a second set
and kills the boost. The scheduler-side sibling of §380 — same trick, different
pass, opposite symptom.

§394 — two align-1 accesses in one function reserve a phantom 8-byte stack slot;
a frame 8 bytes too large with no spill to account for it is the tell.
2026-09-01 13:14:55 -06:00
Drew T f11bf13b4f feat(seed_ref): the CONTAINED tier + docs for the twin ladder (§390/§391, accelerator #18)
tools/seed_ref.py gains --contained/--contained-control: an open stub that is a
banked body plus or minus WHOLE BLOCKS — the class edit distance ranks badly.
Branch-offset masking was required (unmasked offsets veto exactly the target
pairs) and a min-side-25 floor (89% of raw hits were prologue/epilogue vacuity).
Ranks by (substitutions+regions, cover), not by d. Controls: planted-deletion
positive 60/60, random-pair base rate 0/397, R32 population 346/346, and a
post-refactor --near regression reproducing the stored slice exactly.

Banked on first use: ov_SC01_077/func_80184D50 = banked ov_SC03_007/func_8018283C
minus its trailing `&= 0x7FFFFFFF;` — MATCH, closeness 0, 98/98.

* cookbook §390: minimum distance is not minimum work (rank by effort; a deletion
  is free, a substitution is thought), the lookalike filter r = d/min(nins) ~ 0.3
  (17 of 30 "cousins" were boilerplate coincidence), and the three fleet-wide
  nulls that close the scanner question — 0 new / 9 / 2. Spend integration
  effort, not scanner effort.
* cookbook §391: a byte-aligned struct copies in FOUR instructions (lwl/lwr/swl/
  swr), a word-aligned one in TWO. Never invent an aggregate type to make a draft
  compile — an invented word-aligned Blk8 lost exactly 8 ins across two copies and
  read as a believable "near, closeness 70" codegen residual.
* accelerators #18: a claim derived from BYTES is not a claim verified by a
  COMPILER. Every similarity/correctness claim must name the tier it reached
  (stream containment / compiled standalone / whole-binary gate / clean fleet);
  a report that says "verified" without one invites the strongest reading.
  Non-reproduction is a finding — say so rather than assuming your own setup.
* playbook §2a-2: the twin ladder (exact -> RELOC-ONLY -> CONTAINED -> cousin ->
  cold), take the cheapest tier available, widen only when the tier above is empty.
* SETUP inventory row; generic-decomp-package: rank by work, and stop building
  scanners once the well is dry.
2026-09-01 13:06:27 -06:00
Drew T 881dd5a37c docs: the NEAR-TWIN BAND — §389, accelerator #17, SETUP, playbook §2a, generic-decomp-package
The exact-hash twin tier found 22 of 352 reachable open stubs (6%). The
edit-distance band added by `seed_ref --near` finds 75 of 352 (21%) — 3.4x — on a
corpus we believed fully mined. 31 of the new rows were PURE reloc-only twins of
already-banked bodies; 8 banked the same day at ~0 agent tokens, one 94-ins
exemplar serving five open copies.

* cookbook §389: the h_norm hole (norm_stream drops its pending lui-hi on an
  intervening R-type, so indexed-global reloc twins hash differently and vanish
  from seed_ref/twin_sweep/dedup/family-maps at once). Do NOT fix h_norm — every
  stored calibration keys on it; the near tier reads through it.
* accelerators #17: the generalisable law. A similarity hash built for DEDUP
  under-matches by design, which is correct for dedup and silently lossy as a
  FRONTIER join — the two questions want opposite error directions, and the
  frontier failure looks exactly like "this function is unique".
* generic-decomp-package §2b: build the near band at the same time as the exact
  tier, with the three verifications. It pays from the first bank for a new
  project, where we paid a session to recover the debt.
* SETUP inventory row + playbook §2a (run it before believing any "no twin"
  verdict; never send a RELOC-ONLY row to a drafting agent).
2026-09-01 12:20:59 -06:00
Drew T 9d7b26523c docs: cookbook §384 — a carve-config bank is red until you re-extract; correct the S69 checkpoint
The 'false bank' in the S69 checkpoint was not one. Both instances verify
byte-identical after 'make extract BINARY=<b>'. §384 states the law (verification
must regenerate whatever the gate changed the inputs to), the trap inside it (a
src-only revert of a carve commit produces 'table-count drift vs the carve', which
reads like progress), and the give-away I ignored — the commit diffstat showed
config/overlays.mk and a splat yaml sitting next to the .c.
2026-09-01 11:09:31 -06:00
Drew T 9fc27960e9 feat(integration): teach the rest of the toolkit about §378 (self-caller cast)
The lever existed but nothing downstream applied it. Proof it mattered: a wave
agent this session diagnosed its own blocker as "§378 THE SELF-CALLER CAST, a
TU-level fix (cast_self_callers.py) that requires editing src/, which I'm not
permitted to touch" — the knowledge propagated, the automation did not.

* recover_integration.py: NEW "self-cast" stage (tier=binary), so the driver can
  run the whole chain as --stages arity,self-cast. The docstring states WHY the
  order is not arbitrary: self-cast answers the error that "arity" CREATES.
* residual_rules_b.py: both decl-conflict tiers now prescribe the full chain
  instead of "route to integration / budget for banking", and
  NOCOMPILE-UNDECLARED-FIXED now says outright NOT to gate the autodecl arm (it
  is a second conflicting declaration in the real TU).
* wave-playbook §4b: replaced the stale two-step recipe with the three-step
  chain, the one-driver form, the callee variant, and the MANDATORY
  --undo-journal.
* SETUP.md: full inventory row (R21) — it had zero mentions.

Not wired, deliberately: gate_stage's ladder rewrites DRAFTS via _xform, while
this edits the TU; a src-side edit inside the automatic gate needs
revert-on-failure, which recover_integration already owns.

Still open: a draft_prechecks rule to catch the self-decl conflict statically,
before a build is spent. The new stage's plumbing is verified (CLI + candidate
selection); its functional end-to-end run is NOT — gate12 held the tree.
2026-09-01 11:03:06 -06:00
Drew T 05195783b9 docs: mark the triage-ladder spec BUILT with its three corrections; accelerator #16
next-session-triage-ladder.md was still written as a to-build spec. It now leads
with the shipped status, the acceptance numbers, and the three things the spec got
wrong (the '32 free banks' were 0/28; the autodecl arm is worse in-tree than the
raw draft; PRE and POST cannot be the same pass because residual_rules_b needs a
draft), plus the one found by building it — never classify on a moving tree.

accelerators #16: a 'verified, just bank it' claim must name the compilation it
survived. Day-one kit material for a new decomp: any per-function oracle compiles
in isolation, every real bank compiles in context.
2026-09-01 03:49:21 -06:00
Drew T 1dd15eda32 feat(triage): the triage ladder — built, wired, and acceptance-green
tools/triage_ladder.py — the zero-token pre-agent pass, split PRE (target-side:
BANKED/WALL-332/PARKED, no build) from POST (residual_rules_b, needs a draft).
--escalate refuses a walled or banked target; --acceptance is the R39/R32 harness.
Refuses on a non-quiescent tree: a merging gate makes the stub oracle wrong in
both directions (measured, ov_SC01_004:func_8017EB30).

Acceptance, on the whole corpus: false-skip 0/1367 open stubs, recall 426/426
matched, wall tier fires on exactly the 10 enumerated walls (0 extra, 0 missing).
The first wall control asked for evidence that CANNOT exist — it scanned banked
functions' .s, which splat never writes — and printed '0 scanned / 0 tripped',
indistinguishable from a pass. The R32 empty-denominator assertion caught it on
its first run; replaced with a two-sided sweep over all open stubs.

tools/cast_self_callers.py — the §378 lever + --sync-decls for the narrow-param
case C89 forbids no-proto from reaching (§378a).

Wiring: wave_args drops walled/parked targets at draw time via pre_classify (one
implementation, R33); escalate_fable.js refuses any target without triage:'DRAFT'.

Tool fixes found by measurement:
* fix_arity_callers was blind to main entirely (globbed src/main/main*.c; main is
  src/*.c) — reported success over an empty file set through three gates. Now
  refuses when --binary selects no files.
* parallel_gate records each worker's 'failed by class' line (was truncated out of
  the 200-char tail); gater_lane retries in-tree ONLY on the diagnostic-free
  blind-worktree signature — S69 ran 22 serial retries against real cc1 errors.

docs: cookbook §376/§377/§378 (index 1033), SETUP.md, wave-playbook §4b.
2026-08-31 23:53:50 -06:00
Drew T a22d5646f6 docs(cookbook): §374/§375 — two more bounds on the register-pin lever
§374 a register __asm__($30) reservation is NOT honoured by move_movables under
pressure, and the corruption is SILENT (the build succeeds) -- audit the raw
objdump register uses before trusting a pinned build that compiles.
§375 an $a0-$a3 pin used LATE relocates an EARLIER outgoing-call use of that same
register ~26 slots early, identically across three structural variants; argument
pins are not local the way $s pins are.

With §368 and §373 these now form a usable four-way rule for when a pin helps,
when it fights the allocator, when it is ignored entirely, and when it acts at a
distance.
2026-08-31 22:26:02 -06:00
Drew T 5c317dbe5f docs: wire the S68 tools into SETUP.md (R21) and the playbook (when to use them)
A tool nobody knows about is invisible work. Audit found neighbor_ref (built an
hour ago), residual_rules, lane_inflight and r22_verify in NEITHER doc, and
wall_sweep in the playbook but not the inventory.

SETUP.md gains a tooling-inventory row for all five with what each is FOR.

wave-playbook gains §2b: run neighbor_ref for EVERY card, placed right after the
seed_ref step because it answers the weaker and far more common question ('which
matched function should this agent READ?') that seed_ref structurally cannot. It
carries the measurement that justifies it -- a ~20x token swing on that single
variable -- and the failure it prevents: func_8017BEBC's card said 'no banked twin'
while a matched 755-instruction near-twin sat 3,700 lines up IN ITS OWN FILE.

Also states the two honest limits: an opt-level mismatch is PENALISED not merely
ranked low (§116 -- an -O2 example misleads an -O0 target), and a neighbour is a
worked example to READ, never a body to copy (§168 law 1, cousin-remap 0/26).
2026-08-31 22:25:43 -06:00
Drew T ba394da75a docs: spec the TRIAGE LADDER for next session, with its 32 free banks listed
The companion to neighbor_ref.py (built). Written so a session with none of S68's
context can finish it: what it is, where it sits in the pipeline, that
tools/residual_rules_b.py is already ~70% of it with its held-out scores, the
asymmetric failure mode that makes the R39 acceptance test mandatory (a false
'skip - already banked' silently drops a bankable function), and the falsifiable
predictions.

Includes the immediate payoff, verified by me rather than taken on trust: 10 drafts
are byte-MATCHES once an extern derived from the target's own .s is added (10 of 10
confirmed with match_one, closeness 0, patched drafts at .run/rules_b/*/autodecl.c),
plus 22 more that already match standalone and were misfiled as failures.

Also records the experiment's most important number: two INDEPENDENT
implementations converged at ~1-2% on pure cookbook-shape rules, so that tier's
ceiling is the POPULATION (surgical residuals live at the end of escalations, not
in first-pass wave output) and it belongs in escalation loops, not wave triage.
2026-08-31 22:09:11 -06:00
Drew T 7392fcf7c3 docs: accelerators #15 (the differential-oracle harness) + the generic decomp package thesis
#15 — the tool worth building FIRST in any decomp, because it works at 0% and
compounds: run every question down TWO independent paths on a schedule and fail on
disagreement. Ten-plus S68 blockers had one shape — a tool computing a TRUE number
about a NARROWER world than we believed it covered — and EVERY one was caught by
two measurements disagreeing, never by review. R32/R34/R40 already say this and
were not enough: they are rules applied by whoever writes the tool, and in S68 I
wrote R34's warning into one docstring and rebuilt the exact defect it warns about
an hour later in another file.

Includes Drew's scheduling half, which this project only ever did by accident: the
widening is PERIODIC. Tooling is not wrong when written, it goes STALE as new
idioms reveal populations it cannot see. At every phase close ask 'which scanner's
denominator just got wider?' — that question converts new knowledge into free
banks. The §332 sweep is the worked example: one review, 10 fns / 1,027 ins
reclassified, one in-flight escalation stopped mid-spend.

generic-decomp-package.md — what a NEW decomp inherits on day one and does BEFORE
cracking: mine the COMPILER SOURCE and sibling projects for idioms (this project's
best late idioms came from reading gcc-2.7.2's own passes and needed no matched
function at all — week-1 work done in month N), port the families/twins/dedup/carve
layer first, then the oracle harness, and only then crack. With the honest caveat
that tooling-first makes the cheap half free and does NOT shrink the hard tail.
2026-08-31 22:06:20 -06:00
Drew T d8b7fb4e49 docs(playbook): §1b — the §332 walls are now ENUMERATED, wire the sweep into the draw
tools/wall_sweep.py --emit-exclude feeds draw_waves --exclude directly. 10
functions / 1,027 instructions over 1,378 open-stub .s files, against §332's
'6 fleet-wide' with two named.

Recorded what it caught immediately: main/func_8005D734 was already escalated to
Fable at closeness 8 when the sweep listed it, and its site is exactly the residual
that agent described -- stopped. Filtering the live queue dropped two more before
they were drafted (func_8005D9C4 133 ins, func_8005F450 159 ins).

The §188 epilogue half is still NOT built and is now named as such rather than left
implied: its detector exists inside oracle_reorder.py and has never been run as a
sweep.
2026-08-31 20:02:56 -06:00
Drew T 0e50fbc84f docs(playbook): §1b — the walls ledger is always incomplete, and each gap costs an agent run
A wall nobody has met yet is invisible to the draw filter, so new ones are found by
PAYING an agent to hit one. Twice in S68 on main: func_8005E228 (a full run, then
banked the §265 verbatim-asm way) and func_8005F0C8 (289k tokens to reach closeness
36 with the residual confirmed as §188's epilogue by oracle_reorder.py).

Neither is a model failure. An agent handed a wall returns a NEAR with an
unexplainable tail, which looks exactly like a hard function -- and an escalation
cannot beat the toolchain, so escalating one is guaranteed waste.

The fix is named rather than left as folklore: run the §188 epilogue-shape detector
over every open stub AT DRAW TIME. It already exists inside oracle_reorder.py and
has never been run as a sweep. Until then, treat 'NEAR with an epilogue-shaped
tail' as a walls candidate and check it with the oracle BEFORE escalating.
2026-08-31 19:54:36 -06:00
Drew T c42b3dbc35 docs(cookbook): §373 — the dead-reset cse-breaker, the anti-dep pin, and pri(asm)=1
From the fable escalation that closed ov_SC06_010/func_8017E764 (8 -> 0, BOTH
clusters), and it is three findings not one:

1. DEAD-RESET CSE-BREAKER. To stop cse merging two computations of the same
   expression WITHOUT an asm's scheduling footprint: name it, use it, then
   'p = 0;' immediately after. cse invalidates at the second set and flow deletes
   the dead set BEFORE sched1 -- zero bytes, zero LUID disturbance. An empty-asm
   re-tie by contrast is a REAL pre-call insn whose def->asm->arg chain fronts that
   argument's addiu, and on this function that WAS the second residual cluster
   (§361 confirmed: the lever caused the bug it was later blamed on). Removing the
   dead-reset costs +2 ins / +8 frame bytes, so it is load-bearing.

2. A REGISTER PIN THAT DELETES A sched2 ANTI-DEP. sched1's birthing boost sinks a
   single-set 'la' to its consumer, local-alloc reuses the freed scratch, and
   sched2 is then walled by store-reads-$v0 -> la-writes-$v0. A pin on the address
   pointer deletes the anti-dep. Note this is where a pin is RIGHT, against §368
   where pins measured worse -- the discriminator is breaking a false
   anti-dependence (works) vs out-arguing local-alloc about an allocation (fails).

3. HARD FACT: gcc-2.7.2 insn_cost (sched.c:1363) sets LINK_COST_FREE on any dep
   whose consumer is unrecognizable (INSN_CODE<0 = every inline asm), so
   pri(asm)=1 ALWAYS. An asm can never inherit a load's latency into its priority.
   That closes off a whole family of plausible levers.

Also cross-referenced §370: this run was briefed to test that bound FIRST and
reported it did NOT explain the residual. §370's claim is unchanged and still
narrow; the transferable habit is checking whether a recorded bound covers your
case before declaring a residual unreachable.
2026-08-31 19:20:46 -06:00
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