One clean whole-EXE rebuild verified the batch (gate_main), and main re-checked
BYTE-IDENTICAL against config/check.us.sha before anything was credited.
GetRCnt
StopRCnt
func_8005BED8
func_8005D6A0
func_8005D980
func_8005E9D4
func_8005F228
func_8005F728
One clean whole-EXE rebuild verified the batch (gate_main), and main re-checked
BYTE-IDENTICAL against config/check.us.sha before anything was credited.
func_80014094
func_8001599C
func_80015A2C
func_80016A7C
func_80017758
func_8001BFD0
func_8002AED0
One clean whole-EXE rebuild verified the batch (gate_main), and main re-checked
BYTE-IDENTICAL against config/check.us.sha before anything was credited.
func_80015978
func_800290E0
One clean whole-EXE rebuild verified the batch (gate_main), and main re-checked
BYTE-IDENTICAL against config/check.us.sha before anything was credited.
SYS_OBJ_11C0
SYS_OBJ_210
func_80016224
func_8005C29C
Uncommitted src/ changes found at gate entry. These are banked functions from a lane that gates with commit=False, not residue — preserved, not reverted. Top-level src/*.c (main TUs) are excluded by construction (S59).
One clean whole-EXE rebuild verified the batch (gate_main), and main re-checked
BYTE-IDENTICAL against config/check.us.sha before anything was credited.
GetODE
SYS_OBJ_1AA4
SYS_OBJ_604
SYS_OBJ_F00
SYS_OBJ_F24
_getctl
_status
func_80018C64
func_8001C0C8
func_80037FC4
func_8005ADB8
func_8005B710
func_8005D4B8
func_8005E1A4
func_8005EAE8
func_8005F6CC
One clean whole-EXE rebuild verified the batch (gate_main), and main re-checked
BYTE-IDENTICAL against config/check.us.sha before anything was credited.
_cwb
_dws
func_8005A600
One clean whole-EXE rebuild verified the batch (gate_main), and main re-checked
BYTE-IDENTICAL against config/check.us.sha before anything was credited.
SYS_OBJ_F58
func_80059CF4
func_8005AD34
One clean whole-EXE rebuild verified the batch (gate_main), and main re-checked
BYTE-IDENTICAL against config/check.us.sha before anything was credited.
DrawOTagEnv
func_8005BD7C
func_8005C054
One clean whole-EXE rebuild verified the batch (gate_main), and main re-checked
BYTE-IDENTICAL against config/check.us.sha before anything was credited.
func_800159E4
func_800290BC
func_8002A9B8
One clean whole-EXE rebuild verified the batch (gate_main), and main re-checked
BYTE-IDENTICAL against config/check.us.sha before anything was credited.
func_80039C5C
func_8005E13C
One clean whole-EXE rebuild verified the batch (gate_main), and main re-checked
BYTE-IDENTICAL against config/check.us.sha before anything was credited.
func_8002D59C
func_80036F98
func_8005D138
One clean whole-EXE rebuild verified the batch (gate_main), and main re-checked
BYTE-IDENTICAL against config/check.us.sha before anything was credited.
func_8001BFB0
func_8001D150
func_8002CCB4
func_8005D6CC
func_8005E480
Uncommitted src/ changes found at gate entry. These are banked functions from a lane that gates with commit=False, not residue — preserved, not reverted.
PROVEN: from 14:57:01 to 18:43:23 today HEAD built main to 307aa45d… against the
expected 143dbb89…, with NO draft substituted (measured under gate.main.lock, no
gate_main alive). Auto-commit commit:2693 had adopted a mid-flight gate_main
substitution — its carve-out reverted main's TUs, gate_main re-wrote them, and
`git add -A src/` swept the unverified bodies in (a TOCTOU race, 14 s after a
bisect chunk banked). Every main batch after it was doomed before its first
draft was judged: m00–m03 card cycles drafted ~737, slated 160, banked 0, and
burned ~50 clean rebuilds bisecting innocent slates. commit:2712 restored the
green content by accident (it swept this investigation's diagnostic checkout).
gate_main: on any batch failure, ONE try_batch([]) control runs first — if HEAD
itself is red it prints BASELINE RED, leaves the slate reusable, exits 3 (R40).
clean_build no longer reports a linked-but-mismatched build as "no binary" (the
build target embeds the SHA check), the compile-conflict shortcut fires only on
error-shaped lines naming a symbol some draft in the slate actually uses (the
baseline's own func_800143AC implicit-decl WARNING was matching — every m04
chunk died with "drafts declaring it: []"), reverts narrow to top-level src/*.c
(main_tus) so a main gate can never destroy overlay lanes' in-flight work, and
--assert-baseline is a first-class mode.
main_lane: every cycle opens with gate_main --assert-baseline and REFUSES to
draft or gate against a red baseline (R43) — BaselineRed parks nothing, burns
no tries, writes .run/main_lane.BASELINE_RED, re-checks every 30 min.
Adopters (ox_campaign ×3, maintenance.sh, gate_stage, gate_lane, idiom_serial):
main's TUs (top-level src/*.c) are never staged and never reverted by an
overlay/maintenance lane — one writer (gate_main), one committer (main_lane,
after the whole-EXE SHA re-checks green). Unstage-after-add is race-free where
the old revert-then-add was the losing half of the TOCTOU.
Diagnosis, evidence and the full timeline: docs/tool-designs/main-lane-fix-s59.md
STATUS BLINDNESS (Drew): status checks kept reporting the overlay drafter and the
gater — the lanes whose logs scroll — while the main, maintenance and distill lanes
went unmentioned for hours. A lane you do not report is a lane you do not notice
failing: the main lane spent an afternoon on an old config and bisected a whole batch
to zero banks without that ever reaching a status line. tools/campaign_status.py
prints every lane with ITS OWN metrics, read from artefacts rather than memory.
STRAGGLER GRACE 120 -> 700, tied to HTTP_TIMEOUT so they cannot drift. collect_drafts
queues a wave once 95% of shards finish, then waits this long for the rest — and 120s
is shorter than a single turn (~530s for a 16k generation at ~30 tok/s). So raising
the token budget converted truncated turns into agents guillotined mid-thought with NO
draft: overlay draft completion fell from 84-89% at 8k to 41% (bt) and 69% (bu).
DISTILL DEDUPE: each pass re-offers everything unmined, so the lane wrote a fresh
overlapping marker every five minutes — eight queued, each a superset of the last, and
a reviewer cannot tell which one is the work. One pending marker at a time.
I reported 240 of 244 turn-finishes truncated in wave bk and called it ~100%. That
count came from grepping lines containing 'finish=', which api_agent only prints when
a turn ends WITHOUT a tool call — so the denominator was not all turns, it was all
anomalous turns. I compared a subset against itself.
Counting every turn:
bk (8k / 420s): 240 truncated of 3,222 turns = 7.4%
bt (16k / 700s): 16 truncated of 1,210 turns = 1.3%
Still a ~6x improvement and the change stands on its own evidence, but it is a tax
reduction, not the collapse I described. Recorded alongside: a truncated turn is one
turn of 24, not a lost agent — the logs show the agent emitting its tool call on the
very next turn.
Both docs keep the wrong figure explicitly, with why it was wrong, so the next reader
does not re-derive it from the same grep.
SETUP gains rows for recover_rejects.py (free recovery of the 45% of drafts that never
reach the gate, 13% of which are a deterministic symbol rebase),
restart_main_lane_when_idle.sh, and a campaign-constants row recording MAXTOK 16000 /
HTTP_TIMEOUT 700 with the measurements behind them: reasoning_tokens=0 so the output
cap was the reasoning cap, 240 of 244 turn-finishes truncated at 8k, an uncapped hard
prompt wanting 8,067 tokens, ~30 tok/s, and the 1M-context / 131,072-max-completion
model ceiling that makes 16k our choice rather than a limit.
The runbook gains the same table plus the ordering rule (generation < HTTP_TIMEOUT <
stallguard's 1200s kill), the evidence that turn caps are NOT binding on the default
lane, one-lane-one-band with the size table that retired the 120-2000 slot, the
maintenance lane's new recovery job, and the main-lane restart helper.
Same problem as the drafter: an env/arg change (MAXTOK, HTTP_TIMEOUT) only reaches a
fresh shell, and the main lane is usually either drafting or gating. This waits for
the one safe window — no main-lane agents alive and no gate_main running, i.e.
between the gate and the next draw — then restarts. Mid-draft would discard drafted
work; mid-gate would abort a batch (safe, since gate_main reverts its own
substitution, but wasteful).
Probed ox-alpha directly on a real MIPS derivation:
no reasoning cap 265.2s finish=stop completion=8,067 reasoning=0 30 tok/s
reasoning cap 2000 22.3s finish=stop completion= 672 reasoning=0
reasoning cap 6000 41.4s finish=stop completion= 618 reasoning=0
Three findings. (1) ox reports reasoning_tokens=0 — its thinking is IN the content
stream, so the output cap was capping the reasoning; that is exactly why turns ended
in 'no tool call (finish=length)'. (2) The uncapped hard prompt wanted 8,067 tokens —
it was finishing precisely where the old 8k cap cut it off. (3) It generates at ~30
tok/s, not the ~54 I estimated from turn gaps, so a full 16k generation needs ~530s
and the 420s socket would have killed the very turns the bigger budget exists to
allow. A timeout wastes the whole turn; truncation at least leaves a partial.
HTTP_TIMEOUT=700 on both drafting lanes. The ordering that must hold is generation <
HTTP_TIMEOUT (700) < stallguard's wedged-agent kill (1200s). 420 was itself deliberate
— 1800 once parked a hung agent for thirty minutes — and 700 keeps a hang under 12
minutes without strangling legitimate deep reasoning.
Also recorded: a reasoning cap DOES work on ox, but it shortens the ANSWER too (618-672
total tokens), so it is a quality knob, not a fix for truncation.
THE OUTPUT CAP WAS EATING THE TURN BUDGET. Wave bk's shard logs: 240 of 244
turn-finishes were 'no tool call (finish=length) — NUDGE n/6'. The model was
exhausting its 8,000-token output budget BEFORE emitting a tool call, so the turn did
no work; an agent gets six nudges before giving up. That is why MATCHes average 2.8
oracle calls against a 24-turn budget — the turns are going to truncation, not
iteration. ox is free, so a bigger output budget costs latency and nothing else.
Measured alongside it, and worth recording because it redirects the obvious fix: turn
caps are NOT binding on the default lane. Across 1,166 agent completions, non-MATCH
runs used a median of 4 oracle calls and a p90 of 12, and exactly 1 of 194 reached 20
of the 24 available. Agents are not running out of turns; they are giving up early
after truncated turns. (The tells lane WAS cap-bound — 98 of 270 — which is why it
already has 40 turns.)
Plus tools/recover_rejects.py, wired into the maintenance lane: rebase the pre-gate
rejects whose body already matches and only the symbols are wrong (§171), stage them
for the lane's existing free gate. Zero model tokens; it only stages, so a bad
recovery can waste a build but never a bank.
Everything that reaches the GATE and fails gets a backlog row with closeness, class
and best draft. A draft the reloc pre-filter drops never reaches the gate, so it was
recorded nowhere and just sat on disk: 569 of 1,261 drafts across the last eight waves
— 45%.
They are not all garbage. 13% of the MISMATCH? rejects have a body that ALREADY
MATCHES and only the symbol names wrong, which is the deterministic aprop_symfix
stale-symbol class that banked 4 of 4 earlier this session. Roughly 6 recoverable
drafts per wave were being thrown away because no index existed to find them.
Now appended to .run/reloc_rejects.jsonl with the verdict, the shape (MATCH here means
right body, wrong symbols) and the first mismatches, so a recovery pass can work them
without re-drafting. Wrapped so telemetry can never break a gate.
The tells slot became redundant when build_wave_atlas started reserving 60 tell-lever
cards inside every ordinary wave: a dedicated tells wave draws 70-87 cards, a quarter
of a default wave, for a full 40-minute slot.
The 120-2000 slot is worse than redundant. Bank rate by size, measured: 57% under 50
instructions, 30% at 50-80, 22% at 80-120, 3% at 120-200, 6% above. Wave br drew 69
cards on that band — roughly 3 banks for a slot that a full-band wave turns into ~150.
Large functions are not abandoned: the full band contains them and the draw takes
mass-first within each gate group.
Takes effect at the next wave boundary via relaunch_drafter_shell.sh.
Drew's endgame deliverable is a workflow system another person can run solo on any
target, any compiler. We had three docs recording BFM's history (accelerators,
decision-log, automation-runbook) and none stating the SYSTEM. This is that document,
written to one rule: if it would still be true for a different console and a different
compiler, it belongs here.
Contents: the byte gate as the only arbiter and the oracle ladder around it (each
oracle must state its own blind spots); lanes and why the clock-limited one is never
stopped to ship a change; the CARD as fuel rather than a ticket, including the lever
lesson (a label a worker cannot look up is a dead end — 108 transcripts searched for a
word our knowledge base did not contain); draw-time refusal and the four measured
instances of the dominant defect class; free work before paid work; giving an excluded
population its own lane instead of an exclusion; model routing and per-lane budgets;
the flywheel with the one-wave lag and the inert-rider law (1 in 3 credited levers is
byte-inert, measured twice); the economics as measured; what transfers vs what does
not (the knowledge base is per-compiler, the machine that builds it is universal); and
a bootstrapping order for a new project.
Numbers are stated with their denominators so a new project calibrates rather than
copies.
corpus.stubs() misreports for a binary while a gate has draft bodies substituted into
its sources (R35) — but only for THAT binary. The blanket refusal cost far more than
it saved: the gater runs almost continuously, so nearly every fresh draw was refused
and the drafter fell back to PRE-DRAWN waves. Measured at 15:20 — wave br refused,
wave bj (drawn hours earlier) drafted instead.
That is worse than idle time: a pre-drawn wave carries the OLD draw-time defaults, so
every feature landed today — the tells quota, the jtbl quota, the -O0 filter, the
oversize filter — was silently not reaching the fleet, while the logs showed healthy
410-shard waves.
Which binaries are mid-gate is not a guess: gate_stage and gate_main hold
.run/auto/gate.<bin>.lock for exactly that window, so a non-blocking test-lock answers
it per binary. Those are added to EXCLUDE for that draw; the refusal survives only for
--only-bins draws where every requested binary is busy.
Verified live against a running gate: the draw that would have been refused now
returns 40 cards.
Uncommitted src/ changes found at gate entry. These are banked functions from a lane that gates with commit=False, not residue — preserved, not reverted.
One clean whole-EXE rebuild verified the batch (gate_main), and main re-checked
BYTE-IDENTICAL against config/check.us.sha before anything was credited.
func_8001D1C4
One clean whole-EXE rebuild verified the batch (gate_main), and main re-checked
BYTE-IDENTICAL against config/check.us.sha before anything was credited.
func_80014238
func_80017DC4
func_80029178
func_8002A790
func_8002AA00
func_8002D80C
func_8002D8A8
func_8002D8D4
func_8002E5BC
func_800342E8
func_800351E8
func_80036D24
func_8003A3D8
A bisect can run many levels; deferring the commit left byte-proven functions sitting
uncommitted in src/ for the whole descent — precisely the window in which any other
tool's blind revert destroys them (61 banked functions died that way once). The tree
is verified byte-identical on the line where the credit is granted; that is both when
it is safe to commit and when it must be.
The runbook was dated 2026-06-22 and described the reach-1 grinder pivot — it named
no lane that exists today, two months and an entire toolchain later. Rewritten around
what is actually running: the six lanes and their restart rules, the OpenRouter
drafting toolchain (cards, LEVER_CRIB, per-lane budgets, the draw's admit/refuse
census, quotas as floor AND ceiling), the banking toolchain by binary class
(sweep_parallel vs gate_main vs the gate-time jtbl carve vs -O0 objects), the main
lane, the distill lane and the flywheel's measured yield, the rate/credit numbers with
their denominators, and recovery.
Two ops laws are stated where they will be read rather than rediscovered: bash parses
a while-loop up front (so code, args and draw-defaults each take effect differently),
and never pkill -f a lane by a bare name because it matches the harness's own wrapper.
SETUP.md gains rows for main_lane, the distill lane and the three restart helpers.