parallel_gate merged 17 across 16 binaries, aborted on a real red (ov_SC04_011). Reverted that one
file (func_80181F0C); the other 17 fns verify green from a full clean rebuild.
CORRECTION to my own first read: I attributed the ov_SC04_011 failure to func_80182DCC, whose agent
had flagged a needed jtbl carve for that same binary. The merged-and-failing draft was actually
func_80181F0C — I inferred from the binary name matching the carve note instead of reading the diff.
The carve-prediction pattern is still real and worth acting on, on the evidence that does hold:
three agents this session named, in advance, the integration reason the whole-binary gate would
refuse a draft they had just matched in isolation (func_801588CC's §8e/§260-A tail-class jtbl carve;
func_80182DCC's jtbl_801ED970 8-word carve in tail19.data.s; func_8001AF34's JTBL_PADS residual).
Those are gate-side work, not drafting failures, and must not be re-drafted — that is how
ov_SC06_022:func_80181664 burned three slots.
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.
Hardest draw of the session: 23 of 25 targets over 120 instructions (up to 138), and the FIRST wave
whose packs auto-carried the residual class's cookbook bucket (15 of 25). Agents self-reported
25/25 MATCH with zero NEAR — against O21's 34/40 earlier the same day on an EASIER band. One wave
is not causation (the arm mix also moved toward opus), but the notes changed character: they cite
and EXTEND banked laws instead of grinding.
Gate refused 2, and BOTH were predicted by their own agents as integration rather than codegen:
func_801588CC's note named the §8e/§260-A tail-class jtbl carve (jtbl_80199FF8 parked adjacent to
.rodata) and said it needs the gate's jtbl lever, not C. func_8017E498 likewise. Reverted those two
binaries; the other 16 verify green from a full clean rebuild.
Headline lever from this wave (func_80181E98) is a SCOPE CORRECTION to §186, the same shape as the
§167-05 polarity fix earlier today: §186 says no C-level barrier steers cross-jumping — true for
STEERING, but a zero-byte __asm__ __volatile__("") before an arm's goto BLOCKS a suffix merge
outright. Traced to gcc's own jump.c: simplejump cross-jumping calls find_cross_jump(insn,
JUMP_LABEL(insn), minimum=1) and walks BACKWARDS from the j; the empty asm is an ASM_INPUT that
fails rtx_renumbered_equal_p at compare #0, so last1==0 and no merge occurs, for zero emitted bytes.
Closeness 75 -> 40 plateau -> MATCH.
Round-3 harvest measured a RETRIEVAL defect, not a knowledge gap: func_800CDBA8 and func_800CB00C
both re-derived laws the book already states (§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 — they never grepped the index. SYS.md already tells them to ('START AT
docs/cookbook-index.md — it is symptom-keyed'); the instruction is there and gets skipped.
So stop asking. When the pack has ALREADY MEASURED the prior draft's residual and therefore knows
its klass, paste the matching symptom bucket from docs/cookbook-index.md straight into the pack,
capped at 40 rows with a pointer to the rest. Retrieval becomes push, not pull.
Mapping is klass -> bucket (REGALLOC-PERM/LOCAL -> register allocation & pins; SCHEDULE-REORDER,
OPCODE-MIXED, LENGTH-DRIFT -> instruction scheduling; DELAY-SLOT/BRANCH-POLARITY -> delay slots &
branches; WIDTH/IMM-VALUE/IMM-OFFSET -> types, signedness & width; ADDRESSING -> CSE; CC1-FAIL ->
declarations). An unmapped klass yields no bucket rather than a wrong one.
Negative control on the O21 slate, both directions: 12 packs carry a measured residual, 10 of those
get a bucket (2 have an unmapped klass and correctly get none); packs with no residual get none.
The loop closes visibly — the func_8017EDE8 pack now carries this round's OWN addendum about
§137's barrier failing in a cross-jump shared tail, which is exactly that function's residual class.
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.
parallel_gate merged 23 drafts across 22 binaries; its R22 caught 5 real failures
(ov_SC03_110:func_80180270, ov_SC06_025:func_8018098C, ov_SC03_024:func_8017DE8C+func_801838CC,
ov_SC02_037:func_801588CC, ov_SC07_010:func_8017EC6C). Reverted those five binaries' files; the
remaining 22 fns verify green from a full clean rebuild.
Lane conversion this round, same models and packs, drawn minutes apart:
O21 overlays 40 targets, 18-128 ins -> 34 self-reported MATCH (85%), 22 gated
M2 main 15 targets, 74-102 ins -> 4 self-reported MATCH (27%), 1 gated
Size does not explain it (M2's band sits inside O21's). Nearly every O21 MATCH cites an in-TU twin
or neighbour — overlays are ~134 near-copies of one engine, so a structural relative is usually
already banked. src/800.c is single-copy game code with no twin to lean on. Budget main at roughly
a third of the overlay rate, and reach for the permuter there rather than more drafting slots:
main's NEARs cluster at closeness 3-16, i.e. regalloc tail, not wrong code.
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.
parallel_gate merged 8, aborted on a real red (ov_SC06_022 fails a clean rebuild). Reverted that
one file; the remaining 7 verify green.
ov_SC06_022:func_80181664 has now failed the whole-binary gate TWICE, from two independently
written drafts — the O1 wave and then the O1 RESUME, which re-drafted it because a resume replays
the ORIGINAL args and so bypasses the openness/refusal filter added in commit:3301. Two independent
refusals is a wall signal, not a drafting failure: it belongs on the permuter/wall ledger, and the
refusal ledger should be keyed (binary, fn) and consulted by the DRAW — the way twin_sweep already
keys its refusals by (target, exemplar).
Batched main gating (batches of 8, per the measured lesson that batch-40 strands good drafts in
chunks the bounded bisect abandons). Both batches' bisects CONVERGED this time — batch 0: 3 of 7 in
13 rebuilds; batch 1: 1 of 3 in 5 rebuilds — no BISECT ABORTED, so nothing was stranded.
BUG IN MY WRAPPER (R42): gate_main --apply re-extracts and re-splices main on every invocation, so
running batch 1 REVERTED batch 0's three banks. Only batch 1's survived to the tree. The wrapper
must COMMIT between batches; re-running batch 0 to recover them.
parallel_gate merged 17 drafts across 16 binaries then aborted on "check-all: 212 passed, 1 failed".
The red was REAL: ov_SC06_022 still failed from a fully clean rebuild. Reverted that one file
(func_80181664, back to the drafting queue); the remaining 16 verify green with
make clean && make extract-all && make check-all.
CORRECTION to what I claimed while diagnosing the earlier x1 abort: parallel_gate's R22 IS a proper
clean rebuild — it calls sh(["make","clean"]) at tools/parallel_gate.py:257 before extract-all and
check-all. I had grepped for the string "make clean", which cannot match the arg-list form, and
wrongly concluded the tool was reading incrementally. The x1 red was real too; my revert of its two
bad drafts is what made the fleet green. The genuinely stale read was MY OWN bare `make check-all`
run after that revert, which still reported the old 211/213 from leftover objects and nearly led me
to discard 21 good banks. R40 (exonerate the instrument) applies to the instrument's SOURCE, not
just its output: read the code before blaming it.
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.
The x1 parallel_gate merged 23 files then ABORTED on 'check-all: 211 passed, 2 failed'
(ov_SC03_124, ov_SC03_001), correctly leaving the merge in the tree for inspection (R42).
That red was a STALE INCREMENTAL ARTIFACT, not a bad draft: after reverting the two named
binaries' files, a bare 'make check-all' still reported the same 211/213, but rebuilding
ov_SC03_124 from a cleaned build dir produced 0b3991853c39d8c3d8d12e145e3312dd333f2189 —
exactly config/check.ov_SC03_124.sha. The authoritative sweep (make clean && make extract-all
&& make check-all) then returned 213 passed, 0 failed of 213.
Lesson re-earned (R22's own rationale): a bare check-all is an incremental read and must never
be used to diagnose a red fleet — it nearly cost 21 byte-verified banks. The two reverted
drafts (func_8018009C, func_80182BB8) go back to the drafting queue.
Measured against corpus.stubs at gate time on this session's own waves:
w2 80 drawn / 12 still open -> 85% of its agents re-derived already-banked functions
w3 80 drawn / 39 still open -> 51%
x1 80 drawn / 71 still open -> 11%
~109 of 240 agents in w2+w3 spent full budgets on work that was already banked, by the concurrent
parallel_gate commit or by sibling propagation from a twin remap. The agents DID notice ('stale
pack', 'target .s no longer exists') but only after reading the pack, and several reconstructed the
banked body just to have something to submit.
draw_waves filters against the DRAWN ledger, which stops drawing a target twice but says nothing
about whether it is still OPEN. In a campaign where gates land continuously, a wave drawn at T and
launched at T+2h is stale by construction. Openness is the same class of assertion wave_args already
makes about the .s and the pack, so it belongs here, where it costs nothing.
Negative control (both extremes): x1 drops exactly its 9 closed targets and keeps 71; w2 drops 68
and keeps 12 — matching the independent corpus.stubs measurement.
Auto-reconcile loop dropped 1 batch-aborting draft (func_8005E8E8), then bisected 40 candidates in
24 full-EXE rebuilds: 7 explicitly rejected, 5 chunks unresolved when the bisect hit its own bounded
step limit. gate_main reported 'BANKED 3'; corpus.stubs('main') went 132 -> 130, so 2. SECOND
instance of gate_main over-reporting its bank count by one (R14) — trust the oracle, not the tool.
gate_main.py clean-rebuild gate over the 41 compatible drafts of the 54 drawn (11 dropped for
in-TU decl conflicts, 3 more dropped as batch-aborting compile conflicts by the auto-reconcile
loop). Bisect stopped itself after 24 full-EXE rebuilds with 3 chunks unresolved -- a bounded
failure by design. Final: 143dbb89f34491258bbc27810d0a12ec8b43a8dd BYTE-IDENTICAL.
Explicitly rejected: func_80013154, func_8001AAD0, func_8001BC6C, func_80021174, func_800241C0,
func_80031988.
- match_one.py: a CPP/CC1/MASPSX/AS failure printed bare text and exited 1 even under --json, so
every programmatic caller got json.loads of a non-JSON line. claude_wave_packs swallowed 4 of 19
prior drafts as 'residual not measured: Expecting value' — the most actionable datum a pack can
carry (the draft does not COMPILE, here is the error) was the one it dropped. Negative control:
a near draft still measures identically (closeness 2, same residual rows); human mode unchanged.
- claude_wave_packs.py: renders that verdict, pointing the agent at the card's decl_prior block.
Coverage on wave r1 went 15/19 -> 19/19 packs carrying a measured verdict.
- wave_args.py (new): emits the claude_wave_draft.js args from <wave>/targets.json, asserting the
.s exists, that sub is exactly its parent dir, and that the pack exists. Written because I
hand-typed sub as 'ov_SC03_112/jr_80181D08' when the truth is
'asm/ov_SC03_112/nonmatchings/ov_SC03_112_jr_801817E0' (a stub's asm dir is named for its jr-carve
block, not itself) — all 19 agent oracles would have failed identically and read as a model
failure. Negative control: that exact string is REFUSED.
- draw_waves.py (new): draws waves off corpus.stubs cheapest-first, ledger-filtered, with
name-collision deferral (packs are name-keyed and refuse a duplicate). Re-measured the frontier:
the S65 tier map's '~557 cheap singletons (3-17 ins)' conflated one-member FAMILIES with small
functions — only 28 undrawn non-main stubs are <=17 ins; the bulk is 51-120 (258) and >120 (245).
CURRENT_PHASE.md now holds 27 checkpoint blocks and several older ones say 'supersedes every earlier
block' — true when written, false now. The S64 FINAL block sits ~370 lines above the live S65 FINAL-4
one and makes the same claim, so a fresh session reading top-down could anchor on a state the tree has
moved past by 647 banked functions. Banner at the top states the rule: the LAST block is the live one.
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.
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.
The lock I added earlier today guards a real hazard (the driver mutates the shared tree and is not
parallel-safe), but I scoped it to the whole tool instead of the mutating path. --probe-only execs
blocker_probe, which compiles in its own scratch dir and touches nothing — excluding it buys no
safety and costs a free diagnostic.
Measured cost: a t7b drafting agent (func_801832E0) tried the probe TWICE, was refused both times by
a concurrent sweep holding the lock, and submitted with its blocker unconfirmed — exactly the $0
diagnostic the pack tells agents to run first.
Control: with the lock held, --probe-only now returns rc 0 and its verdict table; the mutating path
still returns rc 1 REFUSED.
The seam decays hard as it is worked out. Measured across four rounds today: 139/157 = 88.5%, then
178/234 = 76%, then 71/165 = 43%, then 1/95 = 1%. By the last round almost every candidate was one a
previous round had already tried and the gate had refused, so the sweep spent ~7 minutes of builds to
bank one function.
A refusal is deterministic for a given (target, EXEMPLAR) pair — the same exemplar remaps to the same
text — so the ledger keys on both and skips those by default. A NEW exemplar for the same target is a
different question and is retried automatically, which matters because the pool refills as banking
mints exemplars. --retry-refused overrides.
The ledger starts empty (today's rounds predate it) and populates from .run/pgate_results.json.
The distill prompt asserted 'the whole-binary byte-gate ACCEPTED the final draft, so the final body is
ground truth' for EVERY target. With --with-unbanked now feeding it drafts the gate REFUSED, that
sentence would have laundered an unproven body into a byte-proven cookbook entry (R14/G3). A target
with banked=False now gets an explicit PROVENANCE WARNING telling the distiller to extract the lever
anyway (cookbook 52: a model that FAILS still distils the idiom that cracks its siblings) but to mark
every claim UNPROVEN and never assert byte-equality; the verifier is told the same so its
entry_markdown carries the label. Exercised this session: the one surviving ADDENDUM came from an
unbanked draft and is filed UNPROVEN.
Also regenerates the scoreboard after the day's banks.
parallel_gate.py — the per-binary byte gate was serial BY HARNESS, not by nature. Each binary already
compiles into its own build/<bin>/, links its own .ld and checks its own SHA; what serialized it was
shared mutable state in the ONE checkout (the splice, assert_write_set's GLOBAL git status, and the
deliberately-broad `git add -u src/` that must stay broad). Measured: a 109-binary sweep ran ~1
min/binary on a 32-core box at load 1.4 (~4% utilisation), and an xargs -P 4 attempt over the shared
tree CORRUPTED it earlier today.
Fix is ISOLATION, not locking: one git worktree per worker (own index, own src/, own build/). Workers
gate and NEVER commit; the orchestrator adopts only drafts the gate ACCEPTED, and only where the main
tree still matches the pinned baseline (otherwise REFUSED, never clobbered), then ONE commit and ONE
R22 clean-fleet sweep verifies the merged whole.
Measured on 85 binaries / 234 candidates: 178 banked in 12m19s wall for 127m40s CPU = 10.4x
parallelism, ~7x end-to-end vs serial, 99 files merged, 0 refused, check-all 213/213.
Five things a fresh worktree does NOT have, each found by measurement and each first appearing as
"the draft failed": splat-generated include/*.inc, the EMPTY tools/maspsx submodule, gitignored
tools/bin (cc1) + tools/psyq, build/{<bin>,assets/<bin>} outputs, and extracted/retail. Dirs mixing
tracked and untracked content cannot be symlinked wholesale (ln -s nests INSIDE them) — hence
link_missing(). The negative control that catches all of it: an UNMODIFIED binary must build
BYTE-IDENTICAL in the worktree. Before that control, the first parallel run reported a clean,
plausible "0 banked across 4 binaries" that was pure environment artifact.
twin_sweep.py — enumerate every open stub that has an ALREADY-BANKED structural twin, remap it
mechanically, gate it. Yields measured today: h_exact 139/157 = 88.5%, h_norm 36/45 then 178/234
= 76-80%. h_seq stays refused (Phase-26) and is not used. THE POOL REFILLS: each bank becomes an
exemplar for its siblings — 165 fresh candidates existed immediately after banking 178. Run it
BEFORE drawing any wave; t5_cards does not build seed_ref, so cards assert "no banked twin" for
these and agents redraft answers we already hold (a t5u Opus slot ground ov_SC03_023:func_8017BEBC
to closeness 45 while ov_SC02_004 held a byte-identical banked copy).