infra/fast-time/fork-gate.mjs: H1 and H2 honest and mining through every phase, B the third node; modes attack (B's key fresh, 3 of 5 CPU threads in the split), third (B at about half of the table, accepted) and partition (H1 against H2, the heavier side wins with the gate on as with it off). A reorg is read from the chain (getVirtualChainFromBlock of the pre-cut tip lists removed blocks), never from a key; blue work compared as BigInt; leftovers stopped by pid file, never by name. infra/fast-time/fork-gate-gate.mjs runs the six cases side by side (known-failed first) and is GREEN only when every case gives the verdict it must and the two partition heals agree. tools/fast-time-remote.sh runs a harness on a build box under a slot with a holder line and a JSONL row (the node binaries from a fork worktree's target on the box, results fetched back); it carries the whole-body block and is listed in the check. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
29 lines
2.5 KiB
Bash
Executable file
29 lines
2.5 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# The edited-while-running class (7 October 2026, 03:0x UTC): bash reads a script incrementally, so editing tools/build-remote.sh while a
|
|
# four-minute remote build was in flight made the running copy continue at shifted bytes and die with a syntax error after the build
|
|
# had succeeded on the box (the artefacts were never fetched). Rule: a long-running tool's body sits in ONE brace block that ends with
|
|
# `exit`, which bash parses entirely before running a line of it, so a later edit cannot reach a running copy. This check reads the
|
|
# tools listed below and fails when the line after the library source is not `{ # whole-body` or the file does not end `exit 0` `}`.
|
|
#
|
|
# tools/ci/whole-body-check.sh # exit 1 with the file and the reason
|
|
# tools/ci/whole-body-check.sh --self-test # the real tools pass; a copy with the block removed fails
|
|
set -euo pipefail
|
|
cd "$(dirname "$0")/../.."
|
|
TOOLS=(tools/build-remote.sh tools/cross-remote.sh tools/workers-remote.sh tools/fast-time-remote.sh infra/build-server/hands/move-hand.sh)
|
|
check() { # <file>
|
|
local f="$1" src
|
|
src=$(grep -nE '^\. "\$HERE/(\.\./)+(infra/build-server/)?lib\.sh"' "$f" | head -1 | cut -d: -f1)
|
|
[ -n "$src" ] || { echo "whole-body: $f: no library source line to anchor the block"; return 1; }
|
|
local opener; opener=$(sed -n "$((src + 1)),\$p" "$f" | grep -vE '^\s*$' | head -1) # the next non-blank line
|
|
[ "$opener" = '{ # whole-body: bash parses this block entirely before running a line of it, so an edit to this file while a run is in' ] || { echo "whole-body: $f: the first line after the library source is not the whole-body block opener"; return 1; }
|
|
[ "$(tail -2 "$f" | head -1)" = 'exit 0' ] && [ "$(tail -1 "$f")" = '}' ] || { echo "whole-body: $f: the file does not end with 'exit 0' and '}'"; return 1; }
|
|
echo "whole-body: $f: body in one block (after line $src to the end)"
|
|
}
|
|
if [ "${1:-}" = --self-test ]; then
|
|
t=$(mktemp -d); trap 'rm -rf "$t"' EXIT
|
|
for f in "${TOOLS[@]}"; do check "$f" >/dev/null || { echo "whole-body self-test: the real $f FAILED"; exit 1; }; done
|
|
grep -vE '^\{ # whole-body|^ # flight cannot reach|^exit 0$|^\}$' tools/cross-remote.sh > "$t/no-block.sh"
|
|
if check "$t/no-block.sh" >/dev/null 2>&1; then echo "whole-body self-test: a copy without the block PASSED (blind)"; exit 1; fi
|
|
echo "whole-body self-test: the real tools pass; a copy without the block fails"; exit 0
|
|
fi
|
|
fail=0; for f in "${TOOLS[@]}"; do check "$f" || fail=1; done; exit $fail
|