mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-10-01 07:40:42 -04:00
84706c9860
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.
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.