Files
stack/agents/darkwing/work/queue-92/r2/mutants.sh
T
jason.woltjeandClaude Opus 5.5 4643911ac1 darkwing: row 92 round 2 packet, candidate 8166bade (#1586)
Filbert's six changes and Dewey's N1-N3: five table rows, two launcher
tests, README sentences. 34/34 mutants killed, 14 suites green.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 17:03:58 -05:00

71 lines
5.3 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# Row 92 (#1586) round 2 mutants: round 1's 26, then the sites Filbert's
# round 1 run left alive and their neighbours. Run from the candidate
# worktree's root:
# LOG=<dir> bash mutants.sh /path/to/mut.mjs > mutants.txt
# Each mutant edits one site with mut.mjs (exactly one match, else exit 3),
# runs the named test files and restores the file. "killed" means the run
# failed; "survived" means it passed.
set -u
MUT=$1
run() {
local name=$1 file=$2 from=$3 to=$4; shift 4
cp -- "$file" "$file.orig"
if ! node "$MUT" "$file" "$from" "$to"; then
echo "$name: NO MATCH"; mv -- "$file.orig" "$file"; return
fi
if node --test "$@" > "${LOG:-.}/mut-$name.log" 2>&1; then
echo "$name: survived"
else
echo "$name: killed ($(grep -m1 -o 'ℹ fail [0-9]*' "${LOG:-.}/mut-$name.log"), $(grep -m1 '^✖' "${LOG:-.}/mut-$name.log" | cut -c1-90))"
fi
mv -- "$file.orig" "$file"
}
S=packages/seat/src/sandbox.mjs
E=packages/seat/src/session.mjs
L=packages/cli/src/launcher.mjs
U=packages/cli/systemd/mosaic-bus.service.in
ST=(packages/seat/tests/sandbox.test.mjs)
SE=(packages/seat/tests/session.test.mjs)
LT=(packages/cli/tests/launcher.test.mjs)
ALL=(packages/seat/tests/sandbox.test.mjs packages/seat/tests/session.test.mjs packages/cli/tests/launcher.test.mjs)
# Binds
run no-workspace-bind $S $' { kind: "rw", src: workspace, why: "the instance\'s workspace, where the harness works" },\n' '' "${ST[@]}"
run runDir-read-only $S '{ kind: "rw", src: runDir,' '{ kind: "ro", src: runDir,' "${ST[@]}"
run bind-all-runs $S '{ kind: "rw", src: runDir,' '{ kind: "rw", src: dirname(runDir),' "${ST[@]}"
run bundle-writable $S $' { kind: "ro", src: join(runDir, "bundle"), why: "the run\'s bundle stays as the host wrote it" },\n' '' "${ST[@]}"
run session-json-writable $S $' { kind: "ro", src: join(runDir, "session.json"), why: "the session file stays as the host wrote it" },\n' '' "${ST[@]}"
run no-private-tmp $S $' { kind: "rw", src: join(runDir, "tmp"), dest: "/tmp", why: "a private /tmp, on disk in the run directory" },\n' '' "${ST[@]}"
run bind-checkout $S ' for (const f of RUNNER_FILES) out.push(' $' out.push({ kind: "ro", src: REPO, why: "x" });\n for (const f of RUNNER_FILES) out.push(' "${ST[@]}"
run node-modules-always $S 'if (harness === "pi") out.push' 'if (true) out.push' "${ST[@]}"
run runner-file-missing $S $' "packages/business/src/vocabulary.mjs",\n' '' "${ST[@]}"
run no-remount-ro $S '...argsOf(list), "--remount-ro", "/", "--setenv"' '...argsOf(list), "--setenv"' "${ST[@]}"
run host-home $S '"--setenv", "HOME", join(runDir, "home")' '"--setenv", "HOME", process.env.HOME' "${ST[@]}"
# Namespaces and death
run no-pid-namespace $S '"--unshare-pid", "--unshare-ipc", "--as-pid-1"' '"--unshare-ipc"' "${ALL[@]}"
run die-with-parent $S '"--unshare-ipc", "--as-pid-1"]' '"--unshare-ipc", "--as-pid-1", "--die-with-parent"]' "${LT[@]}"
run no-pdeathsig $S 'const KILL_WITH_PARENT = ["/usr/bin/setpriv", "--pdeathsig", "KILL", "--"];' 'const KILL_WITH_PARENT = [];' "${LT[@]}"
run exit-code-not-mapped $E $' if (!signal && code > 128 && SIGNALS[code - 128]) return { code: null, signal: SIGNALS[code - 128] };\n' '' "${SE[@]}" "${LT[@]}"
run recover-matches-unshare $L '(cmdlineOf(s.pid) ?? [])[0] === bwrap)' '(cmdlineOf(s.pid) ?? [])[0] === "unshare")' "${LT[@]}"
# Refusals
run no-sandbox-check $L $' if (unavailable) throw new Refusal("sandbox-unavailable", unavailable);\n' '' "${LT[@]}"
run probe-always-ok $S $' if (!existsSync(bwrap)) return `${bwrap} is missing`;\n' $' return null;\n' "${ST[@]}" "${LT[@]}"
run no-credential-check $L 'if (model.harness === "claude-code" && !hasSessionCredential(env))' 'if (false)' "${LT[@]}"
run proxy-key-alone $E '["ANTHROPIC_AUTH_TOKEN", "ANTHROPIC_BASE_URL"]]' '["ANTHROPIC_AUTH_TOKEN"]]' "${SE[@]}" "${LT[@]}"
run proxy-key-ignored $E ', ["ANTHROPIC_AUTH_TOKEN", "ANTHROPIC_BASE_URL"]]' ']' "${SE[@]}" "${LT[@]}"
run any-variable-will-do $E 'SESSION_CREDENTIALS.some((set) => set.every(' 'SESSION_CREDENTIALS.some((set) => set.some(' "${SE[@]}" "${LT[@]}"
run claude-bin-not-bound $L 'claudeBin: env.MOSAIC_CLAUDE_BIN || null,' 'claudeBin: null,' "${LT[@]}"
run launch-socket-always $L 'launchSocket: resolved.launch ? launchSocketPath(dataRoot) : null,' 'launchSocket: launchSocketPath(dataRoot),' "${LT[@]}"
# The unit
run unit-no-envfile $U 'EnvironmentFile=-' '# EnvironmentFile=-' packages/cli/tests/host.test.mjs
run unit-envfile-required $U 'EnvironmentFile=-' 'EnvironmentFile=' packages/cli/tests/host.test.mjs
# Round 2: Filbert's survivors (changes 1 to 4) and their neighbours
run no-ipc-namespace $S '"--unshare-pid", "--unshare-ipc", "--as-pid-1"]' '"--unshare-pid", "--as-pid-1"]' "${ST[@]}"
run host-proc $S 'args.push("--proc", b.dest)' 'args.push("--ro-bind", "/proc", b.dest)' "${ST[@]}"
run host-dev $S 'args.push("--dev", b.dest)' 'args.push("--dev-bind", "/dev", b.dest)' "${ST[@]}"
run pi-no-node-modules $S 'if (harness === "pi") out.push' 'if (false) out.push' "${ST[@]}"
run launcher-raw-exit $L 'resolve(sessionExit(code, signal))' 'resolve({ code, signal })' "${LT[@]}"
run credential-every-harness $L 'if (model.harness === "claude-code" && !hasSessionCredential(env))' 'if (!hasSessionCredential(env))' "${LT[@]}"
run pdeathsig-term $S '"--pdeathsig", "KILL"' '"--pdeathsig", "TERM"' "${LT[@]}"
run workspace-read-only $S '{ kind: "rw", src: workspace,' '{ kind: "ro", src: workspace,' "${ST[@]}"