Files
BFM-decomp/tools/lanes
Drew T 84706c9860 feat(draw): draft EVERY instance, siblings included (ONE_PER_GID=0) + K attempts per card
Two ways to spend a free drafting window on a tail that is 92% walls.

ONE_PER_GID=0 — the sibling collapse exists because a same-gid sibling banks by mechanical
remap once its exemplar cracks, so drafting it pays for what the remap does free. That prices
AGENT TOKENS as the scarce resource. On the free ox window they are not, and the collapse is
what makes 3,271 open crackable functions look like 334 drawable skeletons — of which 308 are
gen6+ walls whose exemplars have already refused six waves each. A sibling drafted directly
can crack on its OWN terms instead of waiting on an exemplar that never will.

Measured on a live draw rather than argued:
    uncollapsed  627 cards / 44,403 ins / 160 binaries / 215 gate groups = 2.9 drafts per rebuild
    collapsed    334 cards / 30,926 ins / 104 binaries / 127 gate groups = 2.6 drafts per rebuild
The gate cost is per (binary, TU) group and chunked, so siblings landing in binaries the wave
already touches are close to free at the gate — the card count nearly doubles and the gate gets
MORE efficient per build, not less.

ATTEMPTS=K — K independent shots at each card. The gate cost does not multiply: reloc_filter
keys by fn and staging writes <binary>/<fn>.c, so a function still gets exactly one whole-binary
build per wave; the attempts compete to BE that build, ranked by match_one, which is local and
needs no build. Alternates stay on disk for a later recovery pass. Default 1 (no-op).

A BUG I CAUGHT IN MY OWN SELECTOR before it shipped: it passed binof[fn] (a BINARY NAME) where
match_one wants --asm-subdir (an asm DIRECTORY). Every attempt would have scored identically at
infinity and the picker would have silently degraded to first-seen while appearing to rank —
the same "true number about the wrong thing" class as the day's other defects. Fixed with a
subof map, and a missing subdir now returns neutral instead of a fake score.
2026-08-25 16:18:43 -06:00
..

Autonomous lanes (P31 S58)

The unattended campaign architecture. These are the RUNNING copies' source of truth — the live lanes execute from .run/, which is gitignored, so a fresh clone would otherwise have none of it. Copy back with cp tools/lanes/*.sh .run/ before launching.

lane role rule
drafter.sh draw → shard → draft → queue a ready marker, forever NEVER stop it to ship a code change. Measured 2026-08-23: 139 of 162 idle minutes were exactly that
gater.sh reloc pre-filter → gate → commit → harvest → ledger safe to kill/restart at will
maintenance.sh the free A-prop sibling lane triggers on 150+ newly banked functions, not a timer
stallguard.sh 60s: revive dead lane shells, kill agents silent >20min, kill gates >90min the only thing that works at 3am

Start: setsid nohup .run/<lane>.sh >> .run/<lane>.log 2>&1 </dev/null & Stop everything: touch .run/ox_campaign.stop

Editing a lane requires replacing its SHELL, not just its python — bash has the loop body parsed, so killing the python restarts it with the old arguments. Verify from the startup banner, never from the file.