Files
BFM-decomp/tools/lanes/forever.sh
T
Drew T d53c4bf796 fix(R42): gate_main self-reverts on abort; campaign refuses to adopt main sources
Closes the gap that made main red for nine hours. R42 ('commit a dirty tree rather than
revert it') is correct for a per-binary gate that leaves PROVEN banks uncommitted, and WRONG
for gate_main, whose substitution is unverified by construction until the SHA matches.

Two guards, defense in depth:
1. gate_main installs atexit + SIGTERM/SIGINT/SIGHUP handlers that revert its own substitution
   unless a bank actually succeeded. Killed mid-run, it now cleans up after itself.
2. ox_campaign's dirty-tree commit REFUSES top-level src/*.c (main's sources), reverting those
   and committing the rest. Verified: src/800c.c and src/800.c refused, src/ov_*/... and
   src/shared/engine_core.h still commit.

Also versions the autonomous lane scripts under tools/lanes/ — they lived only in gitignored
.run/, so a fresh clone had no drafter, gater, maintenance or stallguard at all.
2026-08-24 10:27:34 -06:00

23 lines
979 B
Bash

#!/usr/bin/env bash
# Keep the wave campaign running indefinitely (Drew, 2026-08-23: "rinse and repeat forever").
#
# ox_campaign already loops draw -> draft -> gate -> bank -> next wave on its own; this only
# survives the two things that end it: the --waves cap, and a crash. It NEVER starts a second
# campaign alongside a live one — two campaigns would gate into one src/ tree concurrently.
#
# Clean stop: touch .run/ox_campaign.stop (current wave finishes, then everything exits)
set -u
cd /home/musashi/bfm-decomp
say(){ echo "[$(date +%H:%M:%S)] [watchdog] $*"; }
while true; do
if [ -e .run/ox_campaign.stop ]; then say "stop file present — watchdog exiting"; break; fi
if pgrep -f 'tools/ox_campaign\.py' >/dev/null || pgrep -f 'tools/idiom_serial\.py' >/dev/null; then
sleep 120; continue
fi
say "no campaign running — relaunching the chain"
.run/campaign.sh >> .run/campaign.log 2>&1
say "chain exited; restarting in 30s"
sleep 30
done