#!/usr/bin/env bash # Row 137 round 3 (sage-0565): the candidate rebased onto 63c82f1c4 with the REQ-LAND-1 refusal # and the arbiter path. Every test file the candidate touches, plus row 139's hard-waits test, each # singly; scripts/test-land-work.sh; then one kill per new check. A kill edits one source file in # place, runs one test file, which must fail on the named test (and on exactly N tests when N is # given), and restores the file; the script checks every restored file's sha256 against the one it # started with. Last, the whole bus and seat suites. Not the full gate. # Usage: r3-round.sh set -uo pipefail WT=$(cd "$1" && pwd -P); LOGS=$(mkdir -p "$2" && cd "$2" && pwd -P) INHERITED_TMPDIR=/mnt/storage/scratch/tmp export TMPDIR="$HOME/darkwing-scratch/r137/tmp"; mkdir -p "$TMPDIR" SRCS=(packages/seat/src/working.mjs packages/bus/src/broker.mjs packages/bus/src/landing.mjs) declare -A SUM for f in "${SRCS[@]}"; do SUM[$f]=$(sha256sum "$WT/$f" | cut -d' ' -f1); done restore() { local f bad=0 for f in "${SRCS[@]}"; do if [ -f "$WT/$f.orig" ]; then mv -f "$WT/$f.orig" "$WT/$f"; fi [ "$(sha256sum "$WT/$f" | cut -d' ' -f1)" = "${SUM[$f]}" ] || { echo "RESTORE_MISMATCH $f"; bad=1; } done return $bad } trap restore EXIT echo "base $(git -C "$WT" rev-parse --short HEAD) start $(date -u +%H:%M:%S)" # run name package-dir test-file [tmpdir] run() { local log="$LOGS/$1.log" start; start=$(date -u +%H:%M:%S) (cd "$WT/$2" && TMPDIR="${4:-$TMPDIR}" timeout 600 node --test "tests/$3") > "$log" 2>&1 local rc=$? echo "$1 rc=$rc $start-$(date -u +%H:%M:%S) $(grep -E 'ℹ (pass|fail|skipped) ' "$log" | tr '\n' ' ')" return $rc } # probe name source sed-expression changed-line package-dir test-file fails test-name # fails is the exact number of failing tests, or "any" for one or more. probe() { local src="$WT/$2" cp -p "$src" "$src.orig" sed -i "$3" "$src" if [ "$(grep -cF -- "$4" "$src")" != 1 ]; then echo "STOP $1: the edit didn't apply"; exit 1; fi echo "$1 edit: $2 $(grep -nF -- "$4" "$src" | sed 's/^\([0-9]*\):\s*/line \1: /')" run "$1" "$5" "$6" local rc=$? log="$LOGS/$1.log" n restore || exit 1 n=$(grep -E '^ℹ fail [0-9]+$' "$log" | awk '{print $3}') if [ $rc -ne 0 ] && grep -qF "✖ $8" "$log" && { [ "$7" = any ] && [ "${n:-0}" -ge 1 ] || [ "${n:-}" = "$7" ]; }; then echo "$1 KILLED: \"$8\" failed, $n failing" else echo "STOP $1: expected \"$8\" to fail ($7 failing), got ${n:-none}"; exit 1 fi } run bus-land packages/bus land.test.mjs || { echo "STOP bus-land"; exit 1; } run bus-hard-waits packages/bus hard-waits.test.mjs || { echo "STOP bus-hard-waits"; exit 1; } run bus-project-runtime packages/bus project-runtime.test.mjs || { echo "STOP bus-project-runtime"; exit 1; } run seat-landing packages/seat landing.test.mjs || { echo "STOP seat-landing"; exit 1; } run seat-working packages/seat working.test.mjs || { echo "STOP seat-working"; exit 1; } run harness-bundle packages/harness bundle.test.mjs || { echo "STOP harness-bundle"; exit 1; } run harness-git-tools packages/harness git-tools.test.mjs || { echo "STOP harness-git-tools"; exit 1; } run harness-tools packages/harness tools.test.mjs || { echo "STOP harness-tools"; exit 1; } run cli-git-socket packages/cli git-socket.test.mjs || { echo "STOP cli-git-socket"; exit 1; } # The real-sandbox tests take the inherited TMPDIR (the bwrap runner fails under an override). run cli-launcher packages/cli launcher.test.mjs "$INHERITED_TMPDIR" || { echo "STOP cli-launcher"; exit 1; } run cli-thread-launch packages/cli thread-launch.test.mjs "$INHERITED_TMPDIR" || { echo "STOP cli-thread-launch"; exit 1; } start=$(date -u +%H:%M:%S) (cd "$WT" && timeout 600 bash scripts/test-land-work.sh) > "$LOGS/test-land-work.log" 2>&1 rc=$? echo "test-land-work rc=$rc $start-$(date -u +%H:%M:%S) $(tail -1 "$LOGS/test-land-work.log")" [ $rc -eq 0 ] || { echo "STOP test-land-work"; exit 1; } FIRST="REQ-DEC-2: a merge-gate raise its arbiter resolved lands through the host op" LAND1="REQ-LAND-1: a gated merge decision refuses not-authorized" HELD="landHeld is true only for an approved, unspent cross-role merge decision" probe kill-b1-patch-drift packages/seat/src/working.mjs \ 's/if (appliedId !== patch_id) refuse("patch-drift"/if (false) refuse("patch-drift"/' \ 'if (false) refuse("patch-drift"' packages/seat working.test.mjs 1 \ "a landing whose applied diff isn't the reviewed one refuses patch-drift and leaves no worktree" probe kill-b2-against-root packages/seat/src/working.mjs \ 's/"merge-base", commit, "refs\/heads\/main"\])).ok) refuse("unrelated-history"/"merge-base", commit, "refs\/heads\/root"])).ok) refuse("unrelated-history"/' \ '"merge-base", commit, "refs/heads/root"])).ok) refuse("unrelated-history"' packages/seat working.test.mjs 1 \ "once the root shares no history with a landed main, a push is checked against main, not the root" # (a) REQ-LAND-1: without the refusal, the human-approved gated decision lands. probe kill-a-gated-refusal packages/bus/src/broker.mjs \ "s/if (cls === 'gated') fail('not-authorized');/if (false) fail('not-authorized');/" \ "if (false) fail('not-authorized');" packages/bus land.test.mjs 1 "$LAND1" # (b) without the arbiter path, every arbiter-resolved landing refuses not-human. probe kill-b-arbiter-path packages/bus/src/landing.mjs \ "s/const arbitrated = arbiter && d.class/const arbitrated = false \&\& d.class/" \ "const arbitrated = false && d.class" packages/bus land.test.mjs any "$FIRST" # Item 5: the arbiter path takes only a cross-role decision, so a gated one an arbiter resolved fails it. probe kill-5-cross-role-only packages/bus/src/landing.mjs \ "s/const arbitrated = arbiter && d.class === 'cross-role' && /const arbitrated = arbiter \&\& /" \ "const arbitrated = arbiter && d.route_to" packages/bus land.test.mjs 1 "$LAND1" # land-work's call passes no `arbiter`, so it stays human-only. probe kill-arbiter-default packages/bus/src/landing.mjs \ "s/{ into, arbiter = false })/{ into, arbiter = true })/" \ "{ into, arbiter = true })" packages/bus land.test.mjs 1 "$FIRST" # landHeld offers the land op only for a cross-role decision. probe kill-held-cross-role packages/bus/src/broker.mjs \ "s/if (d.class !== 'cross-role' || this.#raisedThread(d) !== record.thread) continue;/if (this.#raisedThread(d) !== record.thread) continue;/" \ "if (this.#raisedThread(d) !== record.thread) continue;" packages/bus land.test.mjs any "$HELD" # The whole bus and seat suites once more, on the restored candidate. for pkg in bus seat; do start=$(date -u +%H:%M:%S) (cd "$WT/packages/$pkg" && timeout 900 node --test tests/*.test.mjs) > "$LOGS/$pkg.log" 2>&1 rc=$? echo "$pkg rc=$rc $start-$(date -u +%H:%M:%S) $(grep -E 'ℹ (pass|fail|skipped) ' "$LOGS/$pkg.log" | tr '\n' ' ')" [ $rc -eq 0 ] || { echo "STOP $pkg"; exit 1; } done echo "ROUND_PASSED $(date -u +%H:%M:%S)"