Commit Graph

992 Commits

Author SHA1 Message Date
Drew T 94ca16e007 docs(accelerators): #20 — set TU boundaries at the rodata island's jtbl spans, at segmentation time
Found P31 S72; COULD have been found 2026-06-15 (Phase 7, commit:0025), which wrote the
island's contents by hand and named loadDestPtrTable as the divider. The signal needs no
matching progress — it is a property of the retail image.

The number that matters is the cost curve: at Phase 6 src/800.c had 13 externs and 0
typedefs and the split was a yaml edit; at S72 it had 2,378 externs and 175 typedefs and
cost 57 crossing declarations, a shared header and 4 stale consumers. Plus a session of
wrong conclusions (11 'PROVEN gate-rejects', 10 of which banked once the carve existed).

PREREQ recorded honestly: the binding constraint came from the OVERLAY work two phases
later, so this is knowledge that never got carried back to main — not carelessness.

General principle: segmentation is the exception to probe-before-investing. When a
decision is evidenced at t=0, cheap now, and strictly more expensive later, make it early
even though its payoff is unproven.
2026-09-02 13:49:37 -06:00
Drew T 8e8521da22 fix+docs: make every consumer aware of main's new TU layout (R36)
The split created two new TUs and a shared header; four consumers still described main's
game code as one file:

* tools/reconcile_slate.py — HARDCODED open('src/800.c'), so after the split it saw a
  THIRD of main's typedefs while reporting success (silently-narrowed scope, R32).
  Measured: 133 visible before the fix, 187 after, 0 lost. Now globs
  corpus.src_files('main') + src/800_shared.h, so a future split is already handled.
* docs/wave-playbook.md 1c — still said spans B/C/D were NOT drawable and that drawing
  one is an R45 violation. That is now false and would have STOPPED a future session
  from drawing the very targets this work unlocked.
* cookbook §426 — its 'the remaining spans need src/800.c split' paragraph now records
  that it was done the same session, and points at §431 for the method.
* config/dedup.us.yaml + src/shared/clearTbl40.h — both said dedup group I0 is
  instantiated 'at both sites in src/800.c'; both sites are above 0x80035270 and are now
  in src/800_c.c.

Byte-neutral: dedup.us.yaml parses, gate_main --assert-baseline BYTE-IDENTICAL.
SETUP.md gains a row describing the layout and the rule it implies: never hardcode
src/800.c, glob corpus.src_files('main').
2026-09-02 13:48:00 -06:00
Drew T 430f40576a docs(cookbook): §431 — widen the gate-reverts-src rule from declaration edits to BANKS
I wrote the rule for declaration edits and then lost two byte-proven banks to the same
mechanism an hour later. gate_main's opening 'git checkout -- src/*.c' destroys anything
uncommitted in src/, banks included. R42 is 'commit before the next command that can
touch src/', not 'commit at a good stopping point' — and count banks from the SOURCE,
which is the only oracle that caught it.
2026-09-02 13:43:11 -06:00
Drew T 468c3751c3 docs(decision-log): S72 addendum — the split decision, and the effort estimate I got wrong
Quoted '2,318 scattered externs' as measured-not-guessed. It was measured, and it
measured the wrong quantity: what a split costs is declarations used OUTSIDE their
region (57 of 1,247), not the total. R41's denominator discipline applied to an EFFORT
estimate. Also records the correction to the '1998' premise: the spans prove at least
three TU boundaries, not that the devs' files were exactly these three.
2026-09-02 13:37:38 -06:00
Drew T 3e8138819a docs(cookbook): §431 — splitting a 27k-line TU at its original boundaries
Where to split: the jtbl spans (tables pack tight within a TU, separated across TUs), and
that is also the MINIMUM — a TU with no switch emits no table and is invisible, so what
you recover is a lower bound on the original structure, not the structure.

What crosses: ask the compiler. 2,318 externs is the scary number and the wrong one; only
57 of 1,247 declared names cross a boundary, 19 of them typedefs with one definition each
and zero shape conflicts. Fix TYPES first — a missing typedef cascades into dozens of
parse errors that all evaporate at once.

Plus the general defect it exposed (a typedef stripper must read the destination's
includes) and the operational rule it cost twice (gate_main reverts src/*.c first, so
commit alignment edits before gating).
2026-09-02 13:37:11 -06:00
Drew T f0148e6822 docs(phase-31): S72 CLOSE — R22 green 213/213, 7 main banked, main past 51.8%, frontier 140
The 11 'PROVEN gate-rejects' were one missing rodata carve, not bad bodies. Next
session starts at the span B/C carve: 18 jtbl functions left in main's frontier holding
most of its remaining instruction mass, blocked on splitting src/800.c at 0x8002B0B4
and 0x80035270 — the original TU boundaries the jtbl spans reveal.
2026-09-02 12:58:44 -06:00
Drew T 174f7aaf7a docs(cookbook): §430 — a shared tail is a late cross-jump merge, not a source goto
Counterweight to §3-B, with a precise discriminator. When two arms converge on a shared
block, that block is usually a late cross_jump merge of per-arm DUPLICATED statements
(§298). Spelling it as a real goto is not equivalent when the label sits INSIDE a loop:
the goto becomes a jump into the loop body, jump.c's mark_loop_jump marks it
loop_invalid, cc1 -dL prints 'Loop at N ignored due to multiple entry points', and
loop.c silently drops invariant hoisting — measured: the 1/0x80 constant hoist into
$a0/$a1 vanished, 2 insns plus a spurious andi.

Discriminator: shared tail outside every loop -> fold it (§3-B, and you may free a hard
ABI register). Shared tail inside a loop body -> duplicate per arm and let cross_jump
merge. A -dL line is a free oracle for this.

Also records CdReadSectorReadyCB's three remaining residual clusters as pack fuel so the
next attempt starts from the draft, not from the .s.
2026-09-02 12:53:19 -06:00
Drew T c0724cb59e docs(cookbook): §428a REWRITTEN — my prediction was refuted; the real law is better
I predicted §428's UID barrier would resolve func_8001B0D4's fence<->over-merge
coupling, reasoning that it changes no liveness. The escalation that tested it did not
use §428 at all. §3-B did it: seven in-block 'return 0;' -> 'goto L_ret0;' to one shared
tail removed the priority-1 hard-$v0 sets, freeing $v0 for the D_800747E4 reload and
$v1 for CdQueueBusy's result, AND fired all three cross-jumps (92->86). One edit, both
residuals.

The real law is the opposite of my framing: two residuals moving in opposite directions
under every lever are usually not in tension — they are two symptoms of ONE starved
resource, and every lever so far was paying for one with the other. Ask what they are
both competing for, and inventory the hard register sets the source forces. A repeated
'return <const>;' in switch arms is the commonest way to pin $v0 many times over.

The wrong prediction is kept in the section as the refutation (R14).
2026-09-02 12:38:49 -06:00
Drew T 4001ff0c6f docs(cookbook): §429 — every held pointer needs its own local; negative-displacement byte stores need one too
From main/CdReadStateMachine (MATCH 385/385, opus). One root: gcc-2.7.2 canonicalises
(mem (reg)) back to a symbol when the pseudo has a single reachable set, so reusing a
pointer local changes the addressing mode downstream. p[-0x10] re-folds to
lui %hi(sym-0x10) unless the offset pointer gets its own single-set local; and a
multi-set pseudo defeats the canonicalisation for every use, costing a load-delay nop.
Same mechanism as §421 read from the source side.

Also confirms the §333 frame dial and the merged-tail label pin (gcc's cross_jump picks
the other end of a merge than you expect) as the cheap alternative to a §5a fence.
2026-09-02 12:33:10 -06:00
Drew T 92c001ea8c docs(cookbook): §428a — the fence<->over-merge coupling (agent-measured, flagged not-yet-byte-proven)
A volatile __asm__ barrier is a scheduling AND allocation event, so on a function whose
residual is allocation-shaped every fence that kills the double-hop re-enables a
cross-jump over-merge. Two residuals in tension, which is why ~20 variants across two
attempts never converged. §428's UID-based barrier is the predicted resolution because
it changes no liveness; the escalation now running is the test.

Flagged explicitly as one agent's report, not a byte-proof (R14).
2026-09-02 12:26:01 -06:00
Drew T c6ab5ff455 docs(cookbook): §428 — a zero-byte cross-jump barrier (advance the pointer inside each switch arm)
Sharpens §5a/§336, supplies the missing precondition to §162. Writing the cursor
advance inside each switch arm instead of a shared temp makes the converging addu a
label CREATED by cross_jump (get_label_before), so its INSN_UID >= max_uid and
jump.c:1988's guard stops the minimum=2 jump-to-jump search from ever running — only
minimum=1 survives, which is exactly the target's single merge. Killed a -23
LENGTH-DRIFT (5 spurious tail merges) in one edit, with no volatile asm.

Found by the S72 main wave on func_80026D64 (MATCH in 2 compiles). The agent also
verified the .rodata table against jtbl_80072BFC past match_one's .text-only blind
spot — because the pack carried the §426 carve note telling it to.
2026-09-02 12:17:05 -06:00
Drew T 7bfc543d76 docs(playbook): 5b — gate the directory, never the verdict list
A wave verdict is a claim about what the AGENTS returned, not what is on disk.
claude_wave_draft.js has no filesystem access, so its .catch() reports NO-DRAFT for
any agent that dies — including one that already wrote a finished body.

S72: a Fable agent on main/func_80024448 spent 133k tokens / 17 tool calls / 10 min,
wrote its draft, then died on 'You've reached your Fable limit'. The workflow returned
NO-DRAFT with an empty draft_path; match_one on that same file returns
{status: match, closeness: 0, nins: 362}. A complete byte-perfect body reported as no
work at all.
2026-09-02 12:13:56 -06:00
Drew T e94bb20833 docs: bank the S72 main carve finding — cookbook §426/§427, playbook 1c, SETUP, decision log
§426 — main's switch functions were never a codegen wall: one .rodata carve had been
missing since Phase 7, so a drafted switch double-emitted its jump table (+28/+52/+76/+84
image growth, 238 symbols shifted, first mover jtbl_80072A4C every time). Includes the
derived name-address overlay that names a layout shift with no reference build, the span
table, and why spans B-D need src/800.c split at the original TU boundaries the spans reveal.

§427 — a hash is a correctness oracle with zero diagnostic content; preserve the red
artifact before anything rebuilds over it, attribute per byte, and negative-control the
localizer in both directions.

playbook 1c — which main jtbl functions are drawable (R45), and the gate note: main is not
in the parallel lane, read the BODY/PLUMBING/MIXED verdict before recording a main reject.
2026-09-02 12:05:01 -06:00
Drew T 6c904ebd0c docs: close the S71 documentation gaps - SETUP tools table, playbook steps, decision log, gate ledger
Audit found real gaps rather than assumed coverage:
* SETUP.md (R21) had NONE of the five tools written this session. Added a table for
  journal_notes / launch_check / gate_triage / restage_matching / weave_sweep, each with
  when you need it, plus the two gating rules now enforced in code (parallel_gate refuses
  main; gate_main refuses a no-op draft and counts banks from the source).
* wave-playbook: launch_check as step 4c (payloads go stale while gates run - 3 of 27
  wave-2 targets were already banked) and gate_triage as step 6b with the measured
  blocker census.
* decision-log (R31) held only the §406 pivot. Added the two strategic entries this
  session actually turned on: gating main with a tool documented as unable to gate it
  (false PASS, caught only by R22), and the drafting pool running dry while the lever
  was an exclude list nobody re-probed after a tool fix.
* CURRENT_PHASE: the per-gate ledger for all 14 cycles plus the carve/rebase/main gates.
* Two memories: gate-main-only-with-gate-main, reprobe-exclude-lists-after-tool-fixes.
2026-09-02 11:19:49 -06:00
Drew T 9631949339 docs(phase-31): S71 CLOSE — R22 green 213/213, frontier 147, 63 banked, main past 50% 2026-09-02 11:15:21 -06:00
Drew T 853cab2a97 docs(cookbook): §425 - sb aliases scalar globals (true_dependence's QImode carve-out) + 3 more
Four byte-verified findings from md_MAIN_003/func_800CF3E8 (467/469 ins), read off
-dS/-dR/-dl/-dr:

1. sched.c true_dependence guards on GET_MODE(mem) != QImode, so a `sb` store aliases
   scalar global loads while sh/sw struct stores are exempt - that is what pins the
   colour lbu after `sb 0xb` and gives it a mandatory filler slot. A property of the
   store's MODE, not of what it points at.
2. An OT-index re-read must be a MEM_IN_STRUCT_P FIXED-address lhu to depend on its
   store; expand's memory_address() forces the constant into a reg (la+lhu 0(reg))
   unless you copy the whole struct into a 2-byte register local. This was the 468/469
   wall for every prior attempt.
3. A `la` above an idx*24 chain needs a single-set base pseudo emitted before the
   multiply: block-scope `{ Sprt24 *b_ = ARR; p = &b_[idx]; }`.
4. Recorded as NOT reachable from C: $v1-vs-$a0 for the last prim pointer is
   local-alloc's pointer-vs-temp priority tie. Permuter or a §419 density manoeuvre.
2026-09-02 11:03:52 -06:00
Drew T 1e314e7208 docs(cookbook): §424 - equal-priority stores emit REVERSED (sched1 LUID tie picks the last statement)
Byte-proven on ov_SC07_006/func_801890FC (387 ins). For two stores at equal priority,
sched1's LUID tie picks the LAST statement's store first; regalloc then gives the other
load $v0, where it sits behind its own $v0 predecessors, and sched2 pins that chain last.
Each equal-priority pair therefore appears reversed: source FE;E-=0x40;A-=0xEE;88;8A;8C
emits as E,88,A,8C,8A.

This is why "statement order is inert" is such a common wrong conclusion here - the
mapping is not identity, so trying orders at random explores the wrong space. Compute the
intended emission order, then invert each equal-priority pair.

Companion (§193-E): the prior draft left no different-address store between `sh 0xA` and
its re-read, so cse forwarded it as `andi 0xffff`. A store to a different address between
the two re-seeds cse - §416's "re-read the store" seen from the failure side.
2026-09-02 10:22:16 -06:00
Drew T 5ce3704e21 docs(cookbook): §422 QImode arithmetic + flag^1 temp; §423 the "cause not determined" typedef collision
§422 (resident/func_800D06E8, 344 ins): mips.h has no PROMOTE_MODE, so a u8 local is
really QImode - `(u8)(c-3) < 2` gives widen_operand a paradoxical subreg (raw $a0) and
combine.c:9246 drops the truncation before the sltiu, while `(u32)(c-3)` re-widens and
loses it. And `s1 = (cmp) ^ 1` puts the comparison in the destination pseudo; the flag
needs its own temp.

§423 (ov_SC03_092/func_8017FA74): match_one closeness 0 + gate reject + "cause not
determined" has a checkable cause. harvest_verify splices the draft where the
INCLUDE_ASM stub was; a file-scope typedef the TU also defines (five lines below, here)
makes gcc-2.7.2 exit 33 on a C89 redefinition, the TU fails, the gate reverts, and
nothing names the typedef. Fix is block scope, proven with a three-way control. Mirror
of §409 law 2 - together they cover collisions above and below the splice point.

Tool trap: a scratch TU copy needs -Isrc/<overlay> or cpp exits 1 on the relative
engine_core.h include and EVERY variant passes identically.
2026-09-02 05:49:58 -06:00
Drew T a10613fa4a docs(cookbook): §421 - a la $tN + addiu pair can be a RELOAD artifact no C spelling reaches
Byte-proven on md_SC07_003/func_801A293C (313 ins, 6 -> 0 in 23 compiles). $t0 there is
reload's scratch (regalloc.md L80: first wholly-unused call-clobbered reg), not an
allocation: a launder output goes to $v0 via local-alloc, and any $8 pin evicts every
mfhi/reload to $t1 (measured 3x). The reach is §385's single-instruction non-volatile
asm with the bare symbol as an INPUT.

Also: spelling an addPrim RMW as a libgpu P_TAG 24-bit addr bitfield makes
store_fixed_bit_field mask the value first, hoisting 0xFFFFFF before 0xFF000000 and
closing both the lui/ori and lw-swap clusters at once (6 -> 3); and an in-place `and $s0`
needs `s0 = s0 & 0xFFFFFF` written out, not the compound form.

The law: before spending iterations on a register you cannot get, ask whether it belongs
to regalloc at all - reload runs after every dial C gives you.
2026-09-02 05:42:42 -06:00
Drew T 2cedd19aaa fix(symfix): key the slate by (binary, fn); §420 multi-cluster rebase banks 4 in 57s
aprop_symfix deduped its slate by BARE FUNCTION NAME, so a four-row slate for
func_8016AB6C across ov_SC03_107/ov_SC07_007/010/011 reported "1 drafts audited" - and
the three dropped rows each needed a DIFFERENT rebase, because each overlay has its own
target symbols. Same root as reloc_filter's binof and gate_lane's homonym staging: three
tools, one R48/§238 defect.

With all four visible, the structure is two uniform delta clusters of two, identical in
shape across all four overlays - one seed body's two data clusters each moving as a
block. STALE-DELTA only admits ONE cluster, so it refused all four as AMBIGUOUS. §420
records the safe generalisation (runs of constant delta, every run >= 2 members, D_
symbols only) and the verification step.

Rebased by hand under that rule, all four still MATCH at closeness 0, and the gate
banked 4/4 in 57 seconds with no drafting (commit:3629). Frontier 165, 45 banked.
2026-09-02 05:38:28 -06:00
Drew T 5a39af246e docs(cookbook): §419 - when a pin is impossible, win the local-alloc density contest
Byte-proven on ov_SC01_000/func_8017DD04 (297 ins). Pinning the 0x80 constant to $7
loses its sched1 birthing boost, because $a3 and $a2 are ALSO set by the function's own
call-argument copies (reg_n_sets == 2) - a hard-register pin on an argument register is
unavailable to any function that passes arguments in it.

So win the ranking instead. local-alloc ranks by refs/live_length: 0x80 scored
13/319 = 4890 and took $6 (a pure $a2<->$a3 swap, 24 wrong). One six-input zero-byte
asm on mlo at the blk3/blk4 boundary buys 6 references, 5217 > 4890, mlo takes $6 and
0x80 falls to $7 with its boost intact. The boundary must be the one cut no hoisted
constant crosses, or you move the live lengths you are exploiting.

Measured inert: pinning mlo to $6 (cse never substitutes a hard reg for a bitfield
constant), and a dead hard-reg copy as a register suggestion (flow deletes it).
2026-09-02 05:12:40 -06:00
Drew T 16c4fc75e1 docs(cookbook): §418 - second index as a GIV, and keeping a table address unfolded
Byte-proven on ov_SC04_016/func_8017DF8C (184 ins, 32 -> 0 in seven compiles).

1. Writing the stride as `off = j * 0x50` (a giv of biv j) rather than a second biv
   fixes 14 preheader rows and 8 latch rows at once: loop.c chains givs LIFO
   (loop.c:4421), so with `j = 0` spelled first the `move $s0,$zero` emits last and the
   arg-3 giv lands in its natural record slot. When the PREHEADER ORDER is wrong, check
   which variables are bivs and which are givs before touching anything else.

2. To emit la + addu + lh 0(reg) instead of a folded %hi/%lo(sym+K), hoist the table
   pointer to a function-scope local set ONCE outside both loops. No LOG_LINK crosses
   basic blocks so combine cannot fold it, and with every $s taken reload rematerialises
   it from reg_equiv_constant at the use and deletes the init - so the hoist is free.
   Spell the sum `idx + (s32)tbl`; the reverse costs one operand swap.

Measured inert here: §328's volatile cast on a reg+sym address.
2026-09-02 04:53:00 -06:00
Drew T 46cfd92e0b docs(cookbook): §417 - a pin blocks jump.c's select collapse; unpinning exposes cse skip-blocks
Byte-proven on ov_SC03_013/func_8017E6F4 (182 ins). A pinned select arm expands as
ior+copy (two insns), so jump.c:728's `x=b; if(c) x=a;` collapse cannot fire. Unpinning
lets it fire - and then cse_end_of_basic_block's skip_blocks path walks between the two
D_80184D2C[idx] reads and CSEs the symbol_ref into $s3. The earlier agent read that as
"unpinning costs +2" and restored the pin, which re-blocked jump.c and hid the cse
behaviour: the function plateaued for three attempts on that misattribution.

The law: when removing a lever MOVES the residual instead of shrinking it, the new
residual is a different pass. Attribute it with a pass dump before re-adding the lever.
2026-09-02 04:38:41 -06:00
Drew T 072607df7b docs(phase-31): S71 gate 6 (+4, frontier 181) and cookbook §416
Four new byte-proven levers from the overnight lane, none previously in the cookbook:
re-read the store instead of passing the value (CSE store-forwarding), (&SYM)[3] vs a
pointer local as an ADDRESSING choice, one biv with +0/+2/+4 for combine_givs, and a
local's width choosing lh vs lhu+sll/sra.

Also recorded: the same-address twin hint was false three times tonight (ov_SC06_000,
ov_SC01_080, ov_SC03_030) while the same-TU neighbour was the real fuel in every case.

Three of the night's five post-limit MATCHes recovered a body off disk rather than
re-deriving it - func_80181A60 in 2 minutes instead of 16.
2026-09-02 04:32:08 -06:00
Drew T 2f46e3e0fc docs(cookbook): §415 - a file-scope decl merges the TU's later block-scope externs into it
gcc-2.7.2 pushdecl/different_binding_level: adding a file-scope extern for a callee that
the TU also declares at BLOCK scope merges those later externs into the global, which
then conflicts with the TU's own definition - and the error names the definition, not the
decl you added. Match the TU's binding LEVEL, not just its type. Byte-proven on
ov_SC04_011/func_80180B24 (215 ins), which also needed the house __asm__ alias for a
file-scope vs block-scope D_ spelling collision.
2026-09-02 02:01:50 -06:00
Drew T 6716100e57 docs: regenerated progress + backlog from the R22-green fleet (853/1919 = 44.45%, frontier 187) 2026-09-02 01:51:14 -06:00
Drew T dff33f66d9 docs(setup): WSL memory cap lowered 48GB -> 32GB (Drew, 2026-09-02); applies on next wsl --shutdown 2026-09-02 01:49:46 -06:00
Drew T 2f72f8b20d fix(pgate): REFUSE main — an incremental main gate is a FALSE PASS, not just a false diff
S71 ran main through parallel_gate, got "11 banked", committed it, and the R22
clean-fleet verify came back 212/213. main did not compile from clean; once the two
declaration conflicts were reconciled it built and was STILL not byte-identical. All 11
were then re-gated one at a time against a clean build — 11 of 11 REJECT.

The rule was already written down in ox_campaign.gate_main_batch: "main is gated by ONE
CLEAN REBUILD of the whole EXE, never incrementally … main's extract rewrites the linker
script, so an incremental main gate returns a FALSE DIFF." parallel_gate's worker IS
gate_stage, so it inherits that — and S58 recorded the false-DIFF direction while this is
the false-PASS one, which is worse: a false diff wastes drafts, a false pass commits wrong
bytes and reads green until the next clean fleet check (R53's signature — a failed build
leaves the previous object on disk and the SHA check downstream reads it).

Now a refusal naming tools/gate_main.py, not a docstring in the callee (R43).
Cookbook §414, including the two instrument errors made while recovering.
2026-09-02 01:45:21 -06:00
Drew T bfea4affd8 feat(draw): route the model tier off the prior RESIDUAL CLASS, not nins
Measured on S71's own wave: wall-clock tracks iteration count, and iteration count
tracks the residual class, not size. A 26-instruction function took 18 min / 31 tool
calls (regalloc, finished NEAR); a 122-instruction one took 80 s / 10. The 20-33 min
runs were all compiler-internal residuals — scheduling ties, birthing boost, register
colouring, LUID order — where every hypothesis costs a compile-and-measure cycle.

arm_for keys on nins alone, so a 47-instruction regalloc wall could not be drawn at
the higher tier and nothing escalates mid-run. arm_from_history() now reads the
function's own journal notes at draw time and returns fable when they name one of
those classes; it never downgrades the size ladder's choice.
R39 control over 3,147 functions with history x 3 bands = 9,441 decisions:
4,020 upgrades (43%), 0 downgrades.

The control's FIRST form passed over an empty set — it keyed on journal rows carrying
a binary, and there are none: the agent verdict schema never had that field, so every
historical note is name-keyed and the same name is a different function in another
overlay (§238). claude_wave_draft.js's VERDICT now requires `binary`, so new rows are
exact. Cookbook §413.
2026-09-02 01:29:59 -06:00
Drew T fecbfac5f8 docs(phase-31): §412 — §323 carve blocker 2 was a regex blind to __attribute__; 5 of 6 carve overlays cleared 2026-09-02 01:25:56 -06:00
Drew T 8f87334399 docs(setup): WSL2 memory reclaim — autoMemoryReclaim=gradual + the interim cache dropper
Task Manager showed WSL holding 30 GB while Linux was using 4 GB and ~22 GB was
reclaimable page cache (a gate wave reads the 450 MB asm/ tree plus every build
object). .wslconfig had a memory cap but no reclaim policy, so WSL2 never handed
freed pages back to Windows. Added autoMemoryReclaim=gradual (needs wsl --shutdown),
recorded the no-restart manual reclaim, and .run/memkeeper.sh as the interim
automatic form. R21.
2026-09-02 01:17:25 -06:00
Drew T 02e1b3a7e6 feat(waves): every pack now carries that function's own PAST-ATTEMPT history
tools/journal_notes.py mines the agent journals per (binary, fn) and appends a
PAST ATTEMPTS section to the pack; claude_wave_packs.py calls it automatically, so
it is the default rather than a step to remember. Idempotent, and R48-safe (a note
stamped with a different binary is never served — §238 homonyms).

Measured before adopting (S71 wave 1, 50 one-agent workflows over the 210-function
real frontier where every target had already refused an earlier wave):
  * 38/39 MATCH at closeness 0 (97.4%) vs S70's 124/131 (94.7%) on an EASIER pool
  * 29/39 agents cite a prior attempt as what they used
  * 4/39 banked by RECOVERING a body that already matched, from a path a note named
  * 11/39 matched on the first compile

The two costs it removes are re-testing a measured-inert lever (§406 lists twelve,
§407 fifteen, §410 four — each paid for by an agent and never seen again) and
re-deriving a body that already exists on disk.

Also: jr_isolate_all places file-local `static` definitions with the region that uses
them instead of refusing the whole file. A `static inline` helper (§82.1) has no
address by construction, which is not a defect; the R32 guard was refusing these and
blocking the isolate on 4 of the 6 overlays whose CARVE-REFUSED functions it is the
named remedy for. Two regions using one static is still a hard refusal (duplicating a
used static is a byte change, R43).

docs: cookbook §411, wave-playbook step 3b, accelerators entry.
2026-09-02 01:11:52 -06:00
Drew T 89c3cf831b docs(phase-31): S71 wave 1 — journal-fuelled packs, 100% first-pass MATCH; cookbook 1078
* Every pack carried PAST ATTEMPTS ON THIS EXACT FUNCTION, mined per-function from the
  historical agent journals (52 of 60 targets, 131 notes). Every landed agent returned
  MATCH at closeness 0 on the hardest frontier we have.
* §409 — the wave and the nine laws it produced. Law 1: a relocation-stream
  TRANSPOSITION is invisible to match_one, the permuter scorer and every similarity
  tier (HI16/LO16 masking; the §195-D blind spot for a different reloc class), and it
  retroactively explains "MATCH but the gate rejected it" verdicts.
* §410 — COPY THEN ACCUMULATE ON THE COPY: satisfies the $s2 in-place destination and
  the sched1 birthing boost at once, with the agent's measured refutation list.
2026-09-02 01:04:27 -06:00
Drew T 698f2959ae fix(campaign): R48 — reloc_filter resolves a draft's binary per-draft, not by bare name
* `binof = {c["fn"]: c["binary"]}` was last-writer-wins, and `status`, `det` and `subof`
  had the same shape — a draft of a name carried by two binaries was stamped with
  whichever card came last and then reloc-checked against the OTHER binary's symbols.
* Resolve per draft instead: the shard's own target list first
  (`.run/wave_<tag>_targets.<i>.json` = `targets[i::workers]`, each row carrying its
  binary), a unique-name card second, a counted refusal when neither can answer (R43).
* R39 negative control over every historical wave: 42,655 drafts, 0 regressions,
  2,317 (5.4%) previously mis-stamped; 2,107 homonym card names fleet-wide.
  Intra-shard ambiguity: 0 of 50,684 (shard, name) pairs over 302,370 shard files.

docs: §408 — §406 refuted as a sweep (0 MATCH / 14 applied, 0 / 210). The 134-member
census counted main's 960 LINKED library stubs and matched a symmetric SHAPE; derived
from the mine-vs-target residual the addressable set is 15 / 210. Decision-log entry
records the pivot: 64 of 210 (30.5%) already match standalone, so the frontier's
largest lane is §376 integration, not codegen.

tools/weave_sweep.py — the derived-selector sweep (R32 coverage, R41 denominators,
--lever-all ablation control).
2026-09-02 00:19:59 -06:00
Drew T 1632c6adec docs(phase-31): S70 FINAL-4 — 145 banked (355->210), 115/118 wave MATCH, 5 card defects (3 fixed), cookbook 1074 2026-09-01 23:40:28 -06:00
Drew T 2740f18373 docs(cookbook): §407 late-wave addenda — reorg delay-slot refusal, find_best_addr folding, and the empty-corpus scan caution 2026-09-01 23:27:21 -06:00
Drew T f83443ecdc docs(cookbook): §405 the S70 wave harvest (113 MATCH / 130 agents) + §406 the 134-function prologue-weave sweep
§405 — the generalisable residue of three waves, grouped by lever family:
  A. match_one compares .text ONLY, so a switch's jump table is invisible to it —
     a draft can score 110/110 with a PERMUTED table emitted as identity
     (resident/func_800D02D0, byte-witnessed). Some historical 'MATCH but gate
     rejected' verdicts were the ORACLE being wrong (R34 in our most-trusted tool).
  B. the scheduler dials, incl. the birthing-boost re-tie's PLACEMENT rule (must be
     a LATER basic block) and reorg's stop_search_p halting at any asm.
  C. regalloc from C without pins: variable identity picks global- vs local-alloc;
     a cross-arm join value loses first-fit and should be duplicated per arm for
     cross_jump to refund; pass-through params reserve arg regs at zero cost.
  D. integration is still the bottleneck — ~1/3 had byte-correct bodies blocked
     only by declarations; the TU is the authority.
  E. what the agents REFUTED: §137 invariance is false for CONFLICT-driven ties;
     §153's 'cse2 puts it back' fails for the dead-def case; §257-8 volatility
     polarity is per-site, not portable.

§406 — the prologue-weave class: 134 of 1,237 open stubs (11%) share the
sw  / move , / sw  shape, cause traced in cc1's .i.sched2 dump
(memrefs_conflict_p finds no dependence, potential_hazard picks sw $ra early), 12
variants measured inert, and ONE working lever (non-volatile memory-clobber asm
after the param copy). One lever x 134 known targets = a sweep, not an idiom.
2026-09-01 23:19:52 -06:00
Drew T f33c455747 docs(playbook): fix the packs invocation — the old form hid SYS.md from every drafting agent
claude_wave_packs writes out_dir/SYS.md + out_dir/packs/<fn>.md, so out_dir is the
WAVE dir. The playbook documented  plus an mv to undo the
resulting packs/packs nesting — which also put SYS.md at <wave>/packs/SYS.md while
claude_wave_draft.js tells every agent to read <wave>/SYS.md.

Net effect: the laws file did not exist where any agent looked, in every wave run
this way, and the brief silently degraded to the pack alone. Two S70 agents said so
verbatim; the rest never noticed. Passing the wave dir fixes it and removes the mv.
2026-09-01 22:55:19 -06:00
Drew T 64dc914afe chore(report): refresh digests after the §332b banks 2026-09-01 20:46:09 -06:00
Drew T db22b69081 docs(cookbook): correct §404 — harvest_verify DOES persist; the lost bank was my own git checkout 2026-09-01 20:36:41 -06:00
Drew T 9b57eaa2f0 chore(report): refresh digests after the S70 twin banks 2026-09-01 17:48:01 -06:00
Drew T cdac7502f9 docs(cookbook): §404 — harvest_verify verifies but does not bank; gate_stage persists 2026-09-01 17:42:44 -06:00
Drew T 957d0a822a docs(cookbook): §403 — record the shipped refusal + its negative control 2026-09-01 17:38:54 -06:00
Drew T 2fbf93d2e0 chore(report): refresh backlog + fleet progress after the S70 banks 2026-09-01 17:30:02 -06:00
Drew T 062ac7d100 docs(cookbook): §401 jtbl-carve probe blind spot · §402 path-resolved-in-another-cwd · §403 undo-journal keyed by name 2026-09-01 17:20:28 -06:00
Drew T 21372a2348 docs(decision-log): R31 — the S70 postgame reframe (tools scope to the CRACKED corpus, not the frontier) 2026-09-01 16:08:16 -06:00
Drew T 49f27f2293 chore(report): refresh backlog + fleet progress after the S69 banks 2026-09-01 15:45:46 -06:00
Drew T 20f80fd933 docs: §400 + SETUP + carve-state memory for the new-file adoption fix; correct a stale docstring
§400 — a baseline check that conflates "absent everywhere" with "changed under
us" silently drops new files. The general law: when a comparison uses two
different sentinels for "nothing" ("" from a failed command, None from a missing
file), it reports a difference that does not exist — and in a GUARD, a phantom
difference becomes a refusal, which looks exactly like the guard working.

Corollary recorded in both §400 and the carve-state memory: "never blanket-add"
covers SHARED carve state (overlays.mk, splat yamls). It does NOT cover a carve's
own new per-binary source file, which is named by a committed yaml and whose 31
siblings are tracked — that one must be adopted with the bank that created it.

Docstring correction: parallel_gate does NOT use `git add -u src/` (that is
gate_stage's form); it adds exactly the adopted paths. My first diagnosis of this
bug blamed `-u` on the strength of that stale line and was WRONG — the cause was
the baseline comparison. Noted in the docstring so the next reader is not
misdirected the same way.
2026-09-01 15:33:04 -06:00
Drew T 4cf531beea docs(cookbook): §399 — four levers from the final S69 round, harvested late
Caught by Drew asking whether the last waves were harvested. They were not: I
banked 1 of 5 (§398b) and left four lever sets in the notifications. Also found
two paid-for MATCHes that were never staged or gated.

(a) a fence BETWEEN two prologue loads, where source reorder does nothing —
    the order is fixed before statement order matters (md_MAIN_013/func_800CB56C)
(b) SINK a call into BOTH arms and let cross_jump keep only the jal suffix;
    88ins/close86 -> 92/13, then §3-T2 field order let each sh $zero fill an lhu
    load-delay. Duplicate in source so the compiler merges, rather than writing
    the merged form yourself (ov_SC07_001/func_8017EDC0)
(c) a $v0->$a0->$s3 DOUBLE COPY is a two-pseudo tell: SImode temp for the compare
    + separate HImode var for the tail (70->37); plus §195-N precondition 5 —
    nesting `return 1` with ONE trailing `return 0` blocks jump.c's store-flag
    transform so reorg fills both delay slots (18->0) (ov_SC02_017/func_8018347C)
(d) the re-tie as a BIV KILLER: a second set makes n_times_set>1 so loop.c
    refuses the pseudo as a biv, killing the combined address giv. volatile was
    worse, a dead read did nothing (ov_SC07_001/func_8017E4DC)

(d) makes THREE distinct uses of the zero-byte re-tie in one session — §380
un-hoists a move_movables invariant, §393 kills the scheduler's birthing boost,
§399d denies a biv. One line, three passes: when a single-set pseudo is being
treated specially, give it a second set.
2026-09-01 15:18:40 -06:00
Drew T 8a19b3ca52 docs(cookbook): §398b — naming a sub-expression changes which pseudo survives; inline it at both use sites 2026-09-01 15:01:06 -06:00