R30/R31 capture while hot: the resolver pivot (63 zero-token banks of 245 staged of 424 judged of
1,352 nominated), the RED-fleet finding (15/214 baseline-RED refusing 174/182 doubly-verified
drafts), the three byte-proven repairs so far, and rule candidates R56–R58.
Drew asked whether waves cracked better before MAXTOK went 8000 -> 16000. Recording both halves
of the answer so next session does not relitigate it from memory:
CLEAN: raising to 16k did cause a real regression — draft completion 84-89% (8k) -> 41% on wave
bt, 69% on bu — but the cause was a harness interaction, not the model. A 16k generation runs
~530 s at ~30 tok/s while STRAGGLER_GRACE was 120 s, so agents were cut off mid-thought with no
draft. Grace at 700 s fixed it; completion has run 97-99% since.
CONFOUNDED: on banks per draft the 8k era looks better (S59: 1,335 of 2,996 = 44.6%; today's best
16k waves dd 34.7%, de 29.7%) — but the populations differ completely. 8k waves had never-drafted
work; today's draw from skeletons that refused six times. Budget and exhaustion moved together, so
neither figure isolates the other. Neither should be cited as evidence about the budget.
AGAINST the simple story: truncated-turn rate is INVERSELY correlated with bank rate (cx 8.7%
trunc/43.9% bank, dd 8.3%/51.4% vs dl 1.3%/0.5%, ej 0.6%/0%). Budget exhaustion driving the
decline would produce the opposite relationship.
THE A/B: split ONE wave's card pool — half the shards at 8k, half at 16k, same generation mix,
same binaries, same gate, same tree, grace 700 s in both arms. Compare banks per DRAFT and per
GATE MINUTE. Holding the population constant is the whole point; every historical comparison
fails exactly there. If 8k matches 16k, the cheaper budget also buys more agents per unit time.
Every campaign process stopped deliberately at session end (0 alive, verified after settling).
.run/ox_campaign.stop and .run/auto/STOP are SET — delete both before relaunching, or every lane
exits immediately.
One dirty overlay TU left by a killed gate was BUILD-VERIFIED as an abandoned substitution (the
binary failed to build with it) and reverted rather than committed — R42's distinction between a
proven bank and mid-gate residue, decided by the bytes.
Two shutdown hazards recorded: pkill on a lane's shell leaves its python running (hit the
drafter, gater and main lane tonight — kill by PID, verify with ps -o lstart), and a bash case
pattern 'src/[a-z0-9_]*.c' matches ACROSS SLASHES, which classified an overlay TU as a main TU
and nearly reverted the wrong file.
Also committing the two lanes built today: tools/lanes/elastic.sh (starts serial idiom lanes when
the API window is idle and the gate queue is deep — it scales the work that is NOT gate-bound,
because adding drafters to a full gate queue makes the backlog worse) and
tools/lanes/grinder_lane.sh (runs tools/grinder.py, the Phase-21 LLM-free permuter, which had
never been run this campaign against 5,388 near-miss rows).
Re-gate of the false-verdict waves finished 21:42: ei 34 · ej 0 · ek 4 · el 6 · em 3 · en 8 =
55 recovered from 2,814 pre-paid drafts for zero model tokens. Only ei paid well (18% of gated);
the rest returned 0-4% because the live lanes had already banked those functions in the interim,
so they come back NOT-A-STUB rather than as banks.
IMPORTANT FOR PLANNING: this does NOT confirm the uncollapsed-wave thesis. eh's 129/380 (34%)
stays an outlier with ei's 18% as its only corroboration — do not plan on sibling drafting
reproducing eh without more evidence.
Session close: 2,238 banked by the commit-message count (the stub invariant is higher — the
A-prop lane's banks ride in chore commits the regex cannot see), open crackable 2,981, fleet
98.2% instruction-weighted and 96.4% distinct-code, up from 97.4%/94.6% this morning.
Next session starts from docs/tool-designs/frontier-analysis-s60.md: the wall is an INTEGRATION
wall, and the first build is the zero-token integration-resolver lane.
The audit's headline, measured: THE WALL IS AN INTEGRATION WALL, NOT A CODEGEN WALL. Of the 292
functions the gate has refused 6+ times, 178 (61%) have ALREADY produced a closeness-0 draft —
match_one byte-equality, whole-binary gate rejection. The blocker is symbols/decls/TU plumbing,
and the fleet keeps re-drafting them: 10,049 reject rows over 574 distinct functions. Highest-EV
build is a zero-token integration-resolver lane, not more drafting.
CORRECTIONS TO MY OWN NUMBERS, verified against the tree before accepting:
* siblings are 1,334 behind 480 multi-member groups, NOT ~3,900. 1,292 groups are SINGLETONS
carrying 57% of open instruction mass. I conflated the never-drafted stub count with the sibling
count and overstated remap leverage ~3x, in this checkpoint and repeatedly in conversation.
* 'everything drawable is gen6+' holds only for the collapsed wave-eligible view; whole-pool
generation is 53% gen0/1, 25% gen6+, and only 292 fns are 6+ GATE-refused.
* '30-67 min gates at 8% CPU' conflated wall_min (includes drafting/queue) with gate wall (12-31
min healthy). Gate cost is proportional to FAILURES, not drafts: ~3 whole-binary builds per
failing draft, so banks/gate-min fell 17.5 -> 0.10 as conversion fell.
* the 5,388 closeness<=2 rows de-dupe to ~543 open functions; my own 19:40 re-measure found 290
still open, down from its 470 — the re-gate and grinder are draining that pool now.
* campaign_status's 'banked today' undercounts: the stub invariant says ~2,644 net, because the
A-prop lane's 357 rode in a chore commit its regex cannot see.
One documented counterexample to 'model quality is not a bottleneck': func_80181714, where
ox-alpha plateaued at closeness 4 while Opus/GLM/DeepSeek each reached reloc-verified MATCH —
argues for a small escalation tier AFTER the resolver drains the fake walls.
Taken on trust and flagged as such: the A-prop residual split (169 STRUCT / 121 no-seed-decl /
73 IMM / 12 void) — the refusal mechanisms exist in aprop_autodraft.py but no file carries those
counts; re-derive before building the decl-inference tool.
~2,200 banked today. Throughput went 65 -> 554 req/min peak by removing harness defects, not by
changing models. The registry was wiped THREE times by four non-atomic truncating writes, now
routed through tools/mk_write.py; each wipe made every gate reject every draft.
The strategic picture for next session: 3,062 open crackable collapse to ~334 drawable skeletons,
~308 of them generation 6+, with ~3,900 siblings behind them that bank by remap. Wide waves
convert at 1-5% and the GATE is the bottleneck (30-67 min at 8% CPU). Optimise banks per gate
minute. The reasoning budget is NOT the cause of the decline — truncation is inversely correlated
with bank rate.
A Fable analyst is writing docs/tool-designs/frontier-analysis-s60.md, briefed that we are not
married to the ox-wave model; that document is the first thing to read next session.
Five rule candidates (R51-R55), each earned by a defect that fired today.
1,947 banked today. Throughput went 65 -> 341 req/min peak and gates 63 -> 39 min, all by
removing harness defects rather than changing models. The registry incident (config/overlays.mk
committed EMPTY, taking main and every overlay gate down) is written up with its blast radius
and the config_sane guard that now prevents it.
The strategic finding is the part that matters for planning: 3,652 open crackable functions
collapse to 334 DRAWABLE skeletons, of which 308 are gen6+ walls — the ~2,900 untouched
functions sit behind those skeletons and bank by mechanical remap, not by drafting. Wide
drafting now converts at 5%. main is 327 crackable, not 1,288.
Four rule candidates for PhaseEnd (R51-R54), each earned by a defect that fired today.
1,342 banked, 140 commits, open stubs 6,575 (main 1,493 / overlay-md 5,082).
The session's one lesson, measured six times: every lane that looked like the models
underperforming was a harness defect — an -O0 oracle nothing ever passed, a lane
retired on a card-size verdict, carve machinery nothing fed, a poisoned main baseline
that made 737 drafts read as bad, a soft 429 killing 44-72% of shards at turn 1, and a
stager consuming one bit of one verdict.
Records what landed (jtbl island split + gate automation, the -O0 census and unlock,
the new main and distill lanes, two RED binaries fixed, the throughput settings with
their probe evidence, the portable-workflow doc), seven rule candidates for PhaseEnd
approval, the ranked open threads with the A-prop residual named and sized, and a
resume procedure that starts from campaign_status.py and verifies from the process
rather than the file.
Records the per-type answer to 'can the waves draw and bank this now', the four
commits that landed after the agents returned, three rule candidates for PhaseEnd
(a card may not name a lever the knowledge base lacks; draw-time bankability; a
budget is part of the harness), and the ranked open work from the agents' docs.
jtbl: the 154-A island split is byte-proven (one config line + jr_isolate_all --only),
with the object-level sh_size control a green SHA cannot give; four md_*/main tool
blindnesses fixed; one delay-slot instruction short of the first bank, logged.
o0: the census (167 real -O0 of 14,400; 116/14,148 ins stranded), the handoff's
md_MAIN_003/011 refutation shown to be itself wrong, the never-wired -O0 oracle fixed,
and 79 unbankable card-draws across 19 waves stopped at the source.
tells: restored and pinned to band 5-80 — the lane gap was a card-size gap, and 235
is refuted as the cause by the recorded pre-gate verdicts.
Three Fable agents in flight; their briefs and every fact they were given are recorded
here so a crash costs a re-spawn, not the knowledge.
jtbl (36,685 ins, but 150 of 177 groups are singletons): Fable's review says the fix is SMALLER
than proposed — ONE inserted .rodata carve line plus jr_isolate_all --only. No _pre piece (it
cannot build), no ld_interleave change (the native script is already rodata-first). Harden
parse_config FIRST: it corrupts md_*/main configs on disk before erroring, which is why
jtbl_carve now hard-refuses them. The ox study's negative control is misattributed — build a
fresh one.
o0/cc1 (6,564 + 6,511 ins): the study is half refuted, and the doc header says which half.
md_MAIN_003/011 do NOT carry the -O0 fingerprint; the 311 files that contain $fp are the real
population. The unanswered load-bearing question for both is whether the EXISTING gate can bank
them unchanged — a lane that drafts what the gate cannot accept has already cost two sessions.
tells (86,602 ins): removed from drafting on four waves of evidence. aprop_autodraft is NOT the
destination (4.2% overlap, checked after I asserted it three times). The live hypothesis is
cookbook §235, the phantom symbol — one wave with it in the brief tests it cheaply.
CURRENT_PHASE.md gains a CRASH-RECOVERY checkpoint (not a fresh-session handoff): what is
running, restart order, the measured fleet/scaling facts, the fixes that must not regress,
and the ordered work queue.
Lanes: drafter (never stop it), gater (restartable), maintenance (free A-prop sibling lane),
stallguard (60s auto-repair). Drafting holds no lock; one narrow draw-vs-gate lock exists
because build_wave_atlas reads corpus.stubs and misreads substituted drafts mid-gate.
main is off the wave critical path — 157 drafts parked to .run/main_queue/ rather than
stalling the gater for another hour on a bisecting whole-EXE rebuild.
api_agent: 5xx retried like 429 (a 502 was abandoning functions at near-19), HTTP_TIMEOUT
420s not 1800 (a hung request parked an agent 30 min), EXTRA_READABLE for tooling briefs,
and bare-directory paths no longer refused against their own granted root.
R42: gate_main reverted 61 byte-proven overlay banks it could not distinguish from its own
substitution (sweep_parallel gates commit=False by design). Fixed by committing overlay banks
before the main batch, chunking main at 8 to bound bisect cost, and replacing every blind
'git checkout -- src/ config/' with commit-or-refuse in ox_campaign and idiom_serial.
R43: sweep_parallel had an explicit branch admitting main, which cannot be gated incrementally
— wave ab banked 0/105 main cards while its non-main cards banked 94/115 (82%), and the wave
read as a drafting failure. sweep_parallel now refuses main and names gate_main.py.
Also: validate_targets now prefers the card's own addr field (named symbols like SYS_OBJ_F00
were MALFORMED and discarded whole 220-card waves); ox_campaign deals model lanes by
smallest-ratio scheduling (a 73-card wave had put 73 shards on ox and 0 on deepseek);
docs/accelerators.md gains the four vacuous-check defects.
An external-model bake-off, not a banking session. Nothing was banked; that is
the next session's first task.
FINDINGS
- CARD FUEL is the biggest lever, bigger than model choice: the same 10 cards
went 4/10 -> 9/10 when seed_ref/tu_ref/decl_prior were injected. The
"60-instruction ceiling" was an artifact of withholding fuel.
- Sub-50 is near-free: 19/19 verified MATCH at $0.007/function, blind.
7,724 sub-50 open functions = 73.5% of the remaining set.
- A free model (stealth/ox-alpha) cracked a 611-ins function and a jtbl
exemplar, and distilled §206 — whose two negative results were
independently byte-confirmed before banking.
- §206 transfers WITHIN a family (40 turns -> 11) but NOT across (56 turns,
0 compiles). jtbl costs ~40 turns of learning per family, not per class.
TOOL FIXES (all negative-controlled)
- family_remap.gather_externs: took the first ALPHABETICAL extern across the
overlay's TUs, carrying two types swapped (sh/lh vs lbu/sb). Now prefers
the extracted unit's own file. Blocked a 4-member/2,444-ins family.
- atlas.member_lever: aprop_card was loaded and never read while a bare
ledger DIFF forced needs-autopsy. PURE now outranks it — rescues 32
members / 11 families / 3,810 ins.
- decl_prior._ASM_SYM: the %hi/%lo arm had never fired (0 of 1,210 over four
waves). jal 306->306 zero regressions, data 0->299.
- api_agent.py (new): --cards, --brief, --max-cost, nudge loop, 429
attribution + backoff, transport retry, non-fatal tool faults, and a
repeated-call guard.
RULES PROPOSED: R40 (exonerate the instrument before attributing a failure to
its subject — seven instances this session) and R41 (a cost/rate/yield number
ships with its denominator — I quoted $0.30 against a $6.31 bill).
Wave AA: 69 cards / 6,539 ins / 8 gate groups, 33 siblings, snapshotted 69/69.
All 69 passed the S46 validity gate pre-draft — the first wave drawn through it
since it was wired into build_wave_atlas, and the honest population negative
control for that gate (zero false refusals; a poisoned card is refused
OUT-OF-RANGE).
decl_prior now contributes 165 DATA rows to the cards (0 on every prior wave,
the §204-E fix). The 49 uncopyable pointer-to-function spellings are marked
`fleet_note` rather than dropped: the consensus is real information, the
rendering is not valid C. NOT fixed at the source — gate_main.typesig is the
banking driver's conflict oracle, so the safe fix is a display-only
pretty-printer in decl_prior, and no index rebuild is needed since the tuple is
what the index stores.
Audit after "did you update tooling for those findings" found three gaps
beyond the four committed fixes:
- R21: docs/SETUP.md had no record of any of it. Adds the "four flow traps"
table — each trap, its measured cost, and where it is now caught.
- family_sweep --only had no coverage assertion, so the 3-vs-50 mis-scope
could recur silently. It now resolves member addrs to their family, always
prints the coverage line, and refuses when it resolves to zero families.
- pregate_check modelled the banking driver's typedef strip but never checked
the consequence. Adds [DROP-RISK] §203 USE-BEFORE-TYPEDEF. R39 NC: flags
the known-bad splice, 0 false positives on the post-hoist file and all 7
other wave-Z TUs (first draft read a typedef named in its own comment).
Also corrects §203 and the phase log: the text that banked was the RENAMED
variant, because gate_stage's backlog.save_draft() overwrote the original on
the failed attempt. Bytes are correct (R22 213/213); the claim "draft
byte-unchanged" was not.
Wave Z: 74/75 MATCH, 72 banked first gate, 2 recovered for zero agent tokens
(§203 address-order typedef hoist; §202 alias on a DEFINITION for the §183.3
DEF-side return wall). Sibling sweep re-scoped after --only was keyed on the
atlas gid rather than family_hseq's exemplar: 3 -> 50 banked.
Harvest: 82 gap reports -> 5 laws, 16 rejected, 30 already-covered; the
adversarial verifier killed 7 of 12 claims. §204 written (510 lines).
Tooling, all negative-controlled:
- the S46 validity gate was off the path for waves T-Z; wired into
build_wave_atlas where cards are born, with the PRE-DRAFT-ONLY constraint
documented (it condemns banked work if run later)
- wave_snapshot honors the card's `sub` (9/9 legacy byte-identical, 66/66
split-TU recovered)
- §204-E: decl_prior's %hi/%lo arm had never fired (jal 306->306 zero
regressions, data 0->299)
Refreshed rather than appended: the previous checkpoint (commit:2542) was outrun by the §201-A fix,
wave Z's redraw and wave Y's harvest, and a checkpoint the tree has moved past is worse than none
because it is believed. Written for a session that has none of this context: what banked, the seven
results that outlive the count, every tool shipped, the eight-step wave-closing sequence, the exact
invocation that fires the staged wave Z, the four known-open near-misses with their attributions,
and the transient-failure recovery that worked five times tonight.
Wave-metrics gains a single six-wave table: 405 drafted, 405 banked or recovered.
547 banked this session, fleet 96.0% instr-weighted / 91.7% distinct / 97.07% fn-count, R22 213/213
twice for wave Y. Wave Z drawn and staged at .run/wave_p31z_workflow.js + .run/wave_z_args.json
(75 cards / 6,517 ins / 8 gate groups) per Drew's instruction not to launch it. Wave Y's harvest is
the one outstanding step of the seven-step closing sequence -- three launches lost every agent to
529 Overloaded at zero tokens; gap reports and target snapshots are on disk and the checkpoint
carries the exact resume invocation.
344 functions banked (235 gated heads + 108 mechanical siblings + 1 main), fleet 95.9%
instr-weighted / 91.4% distinct / 97.02% fn-count, R22 213/213 from a clean tree after each wave.
The checkpoint records the five results that outlive the count (Reconcile-inside-the-wave, §192's
main-only pre-gate ladder, §193-A/§194-E's dead card pointer, §195-D's invisible internal j, and the
already-covered majority in every harvest) and the next-session order of operations.
build_wave_atlas: --one-per-gid collapses same-skeleton siblings to one card and defers
them to <out>.siblings.json for the post-bank family_sweep remap (R32 accounting asserted);
--rank total ranks gate groups by DELIVERED mass (card + deferred siblings). Measured on the
wave-T draw: 6,557 drafted ins carrying 12,709 sibling ins behind 69 of 71 gids = 19,266
instructions of potential for 71 agents, vs 9,985 behind 57 under --rank mass. R39 NC: the
flag is byte-inert on a pool whose gids are unique.
gate_main/pregate_check (§192): three defects that made the pre-gate ladder main-only while
reporting "clean" on overlay slates — (1) resolve_conflicts/substitute hardcoded
corpus.stubs('main') -> per-binary _stubs_for(); (2) sym_of returned the keyword `void` for
every `extern void (*D_x[])(...)`, manufacturing 192 phantom CONFLICTING-EXTERNs (NC over
5,526,100 declarations: 189,301 changed verdicts, 0 regressions); (3) `void f()` and
`void f(void)` were normalized together, costing 40 more phantoms — C89's unspecified-
parameter rule is now gate_main.sig_conflict. §192b: the tool refuses when it substituted 0
files, and prints the per-draft [DROP] reasons it used to compute and discard.
Same overlay slate now reports 2 failures, both real (duplicate typedef; memcpy declared two
ways). Cookbook §192/§192b + index regenerated (585 sections).
Wave P was the first full run of the 6k-ins doctrine: 60 cards / 6,589 ins in 2 gate groups,
59/60 claimed and 58/60 independently re-verified MATCH (6,372 ins), reloc_identity 58/58 AGREE
with ZERO symbol errors -- the second consecutive clean wave on symbol identity.
Banking cost a dozen rebuilds and exposed four more gate_main defects plus three regressions of
my own. The tool fixes, all NC'd:
- resolve_conflicts never read a draft's OWN DEFINITION, so the DEF-side wall (a draft defining
s32 func_X against a TU prototyping void func_X) reached the compiler. Now definition-aware:
it caught 13 conflicts up front where the build had been finding them one rebuild at a time.
- DECL and both typedef patterns anchored on end-of-line, so a TRAILING COMMENT hid a declaration
or typedef entirely -- and agents comment nearly everything they declare. Seventh instance of
one root cause: a scanner that looks green while reading less than it claims (R32).
- typedef handling is now BODY-AWARE and POSITION-AWARE, in a single pass:
* identical definition visible ABOVE the insertion point -> strip and reuse;
* same name, different shape -> rename (private to the draft);
* definition below the insertion point -> never reuse (it is not in scope there).
Three wrong strategies preceded this, each costing a rebuild: blanket strip (the file's copy can
sit BELOW the draft -> implicit-int, then a collision), blanket rename (breaks drafts that share
an IDENTICAL typedef, because their externs stop agreeing -- my regression, three drafts at
once), and a rescan loop that found the definition it had just renamed and stripped it as a
self-duplicate -> 'parse error before *'.
KNOWN LIMIT, recorded not fixed: the conflict check compares spelled type NAMES, so three drafts
each defining their own Slot54 with different layouts all declared func_80032A74(Slot54*) and
looked compatible. Comparing struct LAYOUTS for locally-defined types is the real fix.
13 + 4 verified-correct drafts are parked in two named buckets (competing local type models;
immovable TU declarations that gate_main reverts before every build).
A wave is now sized by INSTRUCTION MASS, not card count. The metric is instruction-weighted, so a
wave is worth what its instructions are worth: the 12-42-ins card lanes carried ~1,400 ins/wave
(~0.011pp, ~440 waves to finish) while wave O carried 6,266 ins at the same gate cost and the same
draft rate.
build_wave_atlas --target-ins draws cards until the instruction budget is met (still capped by n)
and refuses to under-fill silently. Standard recipe: --target-ins 6500 --min-ins 60 --max-ins 200
--max-bins 4, levers now including UNKNOWN.
THE MEASUREMENT BEHIND IT: draft rate barely decays with size -- wave M 98% at avg 51 ins, wave N
92% at avg 65, wave O 96% at avg 128. Mass is nearly free.
THE UNKNOWN UNLOCK: UNKNOWN is not a difficulty label, it means the atlas could not name a lever,
and it had been routed as needing its own bespoke lane. Wave O's 22-card R37 probe drafted it like
any other lane -- reclassifying ~138k ins (a quarter of everything open) as ordinary wave fuel.
With UNKNOWN in, 9,224 fns / 417,325 ins = 70% of all open instructions are agent-draftable; the
60-200-ins mass band alone is 164,357 ins ~= 27 waves, and is the band to work first.
Also banks the five-step PRE-GATE PROTOCOL (independent re-verify -> reloc_identity -> dry-run to
0-dropped -> reconcile declarations toward the form the match needs -> gate), cookbook §176g.
R37 probe: 20 shape-verified AND symbol-verified stored drafts, 5 gate groups -> 1 banked (5%),
statistically the same as the project's A10 stored-verdict law (~0-8%; T1 measured 0/23 on the same
kind of pile earlier this phase). The null is the finding: a stored draft's rejection is almost
never symbol identity, it is TU plumbing (§176d) or staleness. reloc_identity's real home is a
PRE-GATE check on FRESH drafts, not a backlog resurrection tool. The remaining 30 groups are not
worth 30 rebuilds -- lane closed rather than pursued because the tooling was new and interesting.
Also names the SYMBOL-COLLAPSE class in the fixer's refusal (one draft extern standing in for N
distinct globals; a textual rename moves every occurrence together, so it needs one extern per
site) and records the R38 self-note: the 0/23 prior was already in the phase log.
§174 law 1c recorded match_one's relocation blindness as a caution to the reader ('check every
symbol by hand after MATCH'). It is a computation, not a human's job. Banks the arithmetic, the two
failure shapes it separates (uniform-delta stale seed symbols vs wrong field offset), the four
traps that bit me building it (splat-derived names absent from the symbol files; MIPS o32 REL keeps
the addend in the instruction; index alignment is a precondition; a nearest-symbol label needs a
tight window), and the honest limit measured the same session: symbol-verified + shape-verified is
still NOT sufficient for a bank -- the first re-gate group of five such drafts banked 0/5, because
what remains is TU plumbing (§176d), not identity.
--fix rewrites only unambiguously-wrong symbols (every mismatch naming a symbol must imply the SAME
corrected base) and refuses otherwise: 10 of 12 repaired, 2 correctly refused.
build_wave_atlas.py:
- taken-set was a hardcoded 'abcdefghijkl' wave-letter literal -> glob('.run/wave_*_cards.json')
(R33 derive, don't re-derive). NC: 634 -> 726 taken, strict superset, +92 cards from waves m/n
that the literal would have silently re-issued.
- --exclude-bins defaulted to 'main' on the REFUTED link-defect rationale; default now empty and
the help states the real reason (main cannot be gated incrementally; use tools/gate_main.py).
- new --only-bins allow-list: main waves need it, since gate_main rebuilds once per SLATE.
gate_lane.py: an unhandled gate_stage exception produced no JSON line -> v={} -> '0 banked',
indistinguishable from an honest empty gate (cost 2 cycles in P31). Now a non-zero rc or a missing
JSON line is labelled CRASH with the stderr tail, recorded in the results JSON, listed in the
summary as NEVER GATED, and exits non-zero. R39 NC both directions.