mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-27 22:45:39 -04:00
98 lines
8.2 KiB
Bash
98 lines
8.2 KiB
Bash
#!/usr/bin/env bash
|
||
# delever_cycle.sh — the Phase-36 batch cycle, mechanised (T3/T4). For each batch k in [START..END]:
|
||
# 1. the tree must be clean (src/ + config/); the oracle's calibration is refreshed (2–3 s: it is keyed to HEAD, every commit stales it);
|
||
# 2. `delever.py --apply --batch N --label <mode>k` judges every drawable body of the next N files and leaves the winning texts in place
|
||
# (the census is regenerated by the tool when its src stamp is stale); the tool's exit code and its `final X/X identical` are read (R97/R66);
|
||
# 3. the outer gate: the CLEAN fleet run (make clean && extract-all && check-all -> `218 passed, 0 failed of 218`, R22) — it also refreshes
|
||
# build/, the oracle's baseline objects;
|
||
# 4. the census is rerun on the new tree (the commit line quotes it), the phase log gets the batch's entry, the 🛑 headline is refreshed (R101),
|
||
# and src/ + the ledger/batch record/log + the census + the phase log are committed (R42).
|
||
# Stops on the first red (a non-zero tool exit, a final N/M with N != M, a fleet run that is not 218/218) — the batch's files are then
|
||
# still in place: inspect, then `tools/delever.py --restore` (never git checkout, R102). Stops cleanly when nothing is drawable.
|
||
# Usage: [LABEL_PREFIX=t3_] [TASK=T4] [REDRAW="REFUSED NOTHING-USABLE"] tools/delever_cycle.sh START END [BATCH=300] [MODE=tus|headers|gte] [ONLY="alias1 alias2 …"]
|
||
# RUN IT DETACHED from the Claude Code harness (its low-memory guard kills a long BACKGROUND task — batch tus3 died mid-apply, S98):
|
||
# setsid nohup bash -c 'TASK=T4 tools/delever_cycle.sh 3 12 300 tus; echo "cycle exit=$?"' > .run/P36/delever/cycle_<x>.log 2>&1 &
|
||
# and watch the log (a tiny waiter: `until grep -q 'cycle exit=' <log>; do sleep 60; done`). A killed batch: `tools/delever.py --restore`.
|
||
# FINISH=<label> START END …: a batch whose apply and fleet run were green but whose census/commit step failed (an instrument fault) is
|
||
# finished from its own logs — census → log entry → commit — without redoing the work.
|
||
# size a call so one batch stays < 10 min: TUs ≈ 8 s each single-threaded / 12 workers; a header ≈ 4 s (serial, includers in parallel).
|
||
set -o pipefail
|
||
cd "$(dirname "$0")/.." || exit 2
|
||
START=$1; END=$2; BATCH=${3:-300}; MODE=${4:-tus}; ONLY=${5:-}
|
||
[ -n "$START" ] && [ -n "$END" ] || { echo "usage: $0 START END [BATCH] [tus|headers] [ONLY]"; exit 2; }
|
||
case "$MODE" in
|
||
tus) HFLAG=""; TOOL="tools/delever.py --apply"; VPAT='delever: batch .*';;
|
||
headers) HFLAG="--headers"; TOOL="tools/delever.py --apply"; VPAT='delever: batch .*';;
|
||
gte) HFLAG=""; TOOL="tools/gte_consolidate.py --apply"; VPAT='gte_consolidate: batch .*';; # T5: the GTE consolidation per file
|
||
*) echo "MODE must be tus, headers or gte"; exit 2;;
|
||
esac
|
||
ONLYFLAG=""; [ -n "$ONLY" ] && ONLYFLAG="--only $ONLY"
|
||
REDRAWFLAG=""; [ -n "${REDRAW:-}" ] && REDRAWFLAG="--redraw $REDRAW" # e.g. REDRAW="REFUSED NOTHING-USABLE" after a tool fix
|
||
FLEET=$(ls config/check.*.sha | wc -l)
|
||
PY=.venv/bin/python
|
||
MARKER='## 🛑 SESSION CHECKPOINT' # the Log section ends at the checkpoint block: entries go right before it
|
||
for k in $(seq "$START" "$END"); do
|
||
label="${LABEL_PREFIX:-}${MODE}${k}"
|
||
log=.run/P36/delever/run_${label}.log
|
||
r22=.run/P36/baseline/r22_${label}.log
|
||
if [ -n "${FINISH:-}" ]; then
|
||
# FINISH=1: the batch's apply and fleet run already ran green (their logs exist) and the cycle stopped after them (a census
|
||
# instrument fault, a lost commit): redo only the census → log entry → commit steps, from the same logs
|
||
[ "$FINISH" = "$label" ] || { echo "cycle: FINISH=$FINISH does not name batch $label"; exit 2; }
|
||
[ -s "$log" ] && [ -s "$r22" ] || { echo "cycle: FINISH=$label — no apply/R22 logs to finish from"; exit 2; }
|
||
echo "cycle: finishing batch $label from its logs (census → log entry → commit)"
|
||
else
|
||
[ -z "$(git status --short -- src config)" ] || { echo "cycle: src/ or config/ is dirty — commit, or tools/delever.py --restore (R42/R102)"; exit 3; }
|
||
[ -z "$(git status --short --porcelain src | grep '^??')" ] || { echo "cycle: untracked files under src/ (a dotfile probe?) — sweep them first"; exit 3; }
|
||
$PY tools/delever_oracle.py --status >/dev/null 2>&1 || $PY tools/delever_oracle.py --calibrate ov_SC04_011 ov_SC03_015 ov_SC03_014 main -j 16 > .run/P36/delever/calibrate_${label}.log 2>&1 \
|
||
|| { echo "cycle: calibration FAILED"; tail -5 .run/P36/delever/calibrate_${label}.log; exit 1; }
|
||
{ /usr/bin/time -f "$label wall=%e s" $PY $TOOL --batch "$BATCH" --label "$label" $HFLAG $ONLYFLAG $REDRAWFLAG -j 12; echo "exit=$?"; } > "$log" 2>&1
|
||
fi
|
||
grep -q '^exit=0$' "$log" || { echo "cycle: batch $label — delever exited non-zero"; tail -4 "$log"; exit 1; }
|
||
if grep -qE 'nothing to do' "$log"; then echo "cycle: nothing drawable at $label — done"; exit 0; fi
|
||
vline=$(grep -oE "$VPAT" "$log" | tail -1)
|
||
[ -n "$vline" ] || { echo "cycle: batch $label — no verify line in $log (R32: an empty line is not a pass)"; tail -3 "$log"; exit 1; }
|
||
final=$(echo "$vline" | grep -oE 'final [0-9]+/[0-9]+' | grep -oE '[0-9]+/[0-9]+')
|
||
[ -n "$final" ] && [ "${final%/*}" = "${final#*/}" ] || { echo "cycle: batch $label — $vline"; exit 1; }
|
||
if [ "$(echo "$vline" | grep -oE 'written [0-9]+' | grep -oE '[0-9]+')" = "0" ]; then echo "cycle: batch $label wrote no file — $vline"; fi
|
||
if [ -z "${FINISH:-}" ]; then
|
||
{ /usr/bin/time -f "wall=%e s user=%U s sys=%S s" bash -c 'set -o pipefail; make clean && make extract-all JOBS=16 && make check-all JOBS=16'; echo "exit=$?"; } > "$r22" 2>&1
|
||
fi
|
||
line=$(grep -oE "check-all: [0-9]+ passed, [0-9]+ failed of [0-9]+" "$r22")
|
||
if ! grep -q '^exit=0$' "$r22" || [ "$line" != "check-all: $FLEET passed, 0 failed of $FLEET" ]; then echo "cycle: R22 RED after batch $label — $line (the batch's files are in place: inspect, then tools/delever.py --restore)"; exit 1; fi
|
||
$PY tools/lever_census.py --sites -j 16 > .run/P36/census/census_${label}.log 2>&1 || { echo "cycle: the census FAILED after batch $label"; tail -3 .run/P36/census/census_${label}.log; exit 1; }
|
||
cline=$(grep -oE "THE PHASE'S NUMBER.*" .run/P36/census/lever_census.txt | head -1)
|
||
[ -n "$cline" ] || { echo "cycle: the census table carries no PHASE'S NUMBER line after batch $label"; exit 1; }
|
||
TASK=${TASK:-T4} $PY - "$label" "$vline" "$line" "$cline" "$(grep -oE 'wall=[0-9.]+ s' "$r22" | head -1)" "$MARKER" <<'EOF' || exit 1
|
||
import os, pathlib, re, sys, time, subprocess
|
||
label, vline, r22line, cline, wall, marker = sys.argv[1:7]
|
||
task = os.environ.get("TASK", "T4")
|
||
p = pathlib.Path("phase-ends/CURRENT_PHASE.md"); t = p.read_text()
|
||
head = subprocess.run(["git", "rev-parse", "--short", "HEAD"], capture_output=True, text=True).stdout.strip()
|
||
entry = (f"\n- **{time.strftime('%Y-%m-%d')} — {task} batch `{label}`** (`.run/P36/delever/run_{label}.log`, `batch_{label}.json`): `{vline}` → R22 "
|
||
f"(`.run/P36/baseline/r22_{label}.log`) **`{r22line}`** (`{wall}`) → census `{cline}`.")
|
||
assert ("\n" + marker) in t, "phase log marker (the checkpoint heading) not found"
|
||
t = t.replace("\n" + marker, entry + "\n\n" + marker, 1)
|
||
# the 🛑 headline (R101): every task-advancing commit refreshes it
|
||
lines = t.split("\n")
|
||
for i, l in enumerate(lines):
|
||
if l.startswith("## 🛑 SESSION CHECKPOINT"):
|
||
base = re.sub(r"\s*\|\s*last batch.*$", "", l)
|
||
lines[i] = f"{base} | last batch `{label}` on {head}: {cline}"
|
||
break
|
||
p.write_text("\n".join(lines))
|
||
print("log:", label, cline)
|
||
EOF
|
||
# the index lock: wait out a transient holder (a harness hook's git status), clear a STALE one (no git process alive) — batch tus2
|
||
# lost its commit to a lock created during its own fleet run with no holder left (S98)
|
||
for i in 1 2 3 4 5 6; do
|
||
[ -e .git/index.lock ] || break
|
||
if [ -z "$(ps -eo cmd | grep -E '^git |/git ' | grep -v grep)" ]; then echo "cycle: stale .git/index.lock (no git process) — removed"; rm -f .git/index.lock; break; fi
|
||
sleep 10
|
||
done
|
||
git add -A src && git add .run/P36/delever .run/P36/census .run/P36/baseline phase-ends/CURRENT_PHASE.md || exit 1
|
||
git commit -q -m "src(phase-36): ${TASK:-T4} batch $label — $vline | R22 $line | census: $cline (delever_cycle)" || exit 1
|
||
echo "cycle: batch $label committed $(git log --oneline -1 | cut -c1-9) — $vline | $line"
|
||
done
|
||
echo "cycle: batches $START..$END done"
|