Files
stack/agents/rocko/work/queue-78/build.patch
T
jason.woltjeandClaude Opus 5.5 2ece44919e rocko: row 78 round 1 packet, BUILD-LOG and SESSIONS (#1572)
Packet agents/rocko/work/queue-78/ (packet manifest 9e067f40, 32 files,
candidate manifest 3016dbf1), Rocko's BUILD-LOG and SESSIONS appends.
Committed by Sage for Rocko, who has no credential.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 19:10:16 -05:00

96 lines
4.2 KiB
Diff

diff --git a/agents/rocko/work/queue-78/mutants.sh b/agents/rocko/work/queue-78/mutants.sh
new file mode 100755
index 00000000..0909b5b5
--- /dev/null
+++ b/agents/rocko/work/queue-78/mutants.sh
@@ -0,0 +1,43 @@
+#!/usr/bin/env bash
+# Row 78 (#1572): rerun the mutants against a tree. Usage: mutants.sh <tree>.
+# Each mutant makes one check in scripts/bus-service.sh skip the default pin
+# (no --claude) while still applying to --claude, runs the cli host tests,
+# and restores the file from a saved copy, so the tree need not be
+# committed. Prints "killed" or "SURVIVED" per mutant; exit 1 if any
+# survives, a sed doesn't change the file, or the unmutated run fails.
+set -euo pipefail
+TREE="$(cd "${1:?usage: mutants.sh <tree>}" && pwd)"
+cd "$TREE"
+SCRIPT=scripts/bus-service.sh
+TESTS=(packages/cli/tests/host.test.mjs)
+run_tests() { node --test "${TESTS[@]}" >"$1" 2>&1; }
+
+# name | sed expression
+MUTANTS=(
+ 'default-skips-exec-check|s/^ \[ -f "\$bin" \] && \[ -x "\$bin" \] || die / [ "$CLAUDE_SET" = 0 ] || { [ -f "$bin" ] \&\& [ -x "$bin" ]; } || die /'
+ 'default-skips-char-check|s/^ case "\$bin" in \*\[!A-Za-z0-9\/._+-\]\*) die / case "$bin" in *[!A-Za-z0-9\/._+-]*) [ "$CLAUDE_SET" = 0 ] || die /'
+)
+
+OUT="${OUT:-$TREE/.mutants}"
+mkdir -p "$OUT"
+run_tests "$OUT/baseline.log" || { echo "baseline run failed: $OUT/baseline.log" >&2; exit 1; }
+echo "baseline: pass"
+status=0
+for m in "${MUTANTS[@]}"; do
+ IFS='|' read -r name expr <<<"$m"
+ cp -p "$SCRIPT" "$OUT/orig"
+ sed -i -e "$expr" "$SCRIPT"
+ if cmp -s "$OUT/orig" "$SCRIPT"; then
+ echo "$name: NOT APPLIED (sed matched nothing)"; status=1; continue
+ fi
+ diff -u "$OUT/orig" "$SCRIPT" >"$OUT/$name.diff" || true
+ if run_tests "$OUT/$name.log"; then
+ echo "$name: SURVIVED"; status=1
+ else
+ echo "$name: killed ($(grep -E '^✖' "$OUT/$name.log" | grep -v 'failing tests' | sed 's/ ([0-9.]*ms)$//' | sort -u | tr '\n' ';'))"
+ fi
+ cp -p "$OUT/orig" "$SCRIPT"
+ cmp -s "$OUT/orig" "$SCRIPT" || { echo "restore failed: $SCRIPT" >&2; exit 1; }
+ rm -f "$OUT/orig"
+done
+exit "$status"
diff --git a/packages/cli/tests/host.test.mjs b/packages/cli/tests/host.test.mjs
index 13a621ae..6f0961af 100644
--- a/packages/cli/tests/host.test.mjs
+++ b/packages/cli/tests/host.test.mjs
@@ -611,3 +611,41 @@ test("bus-service.sh refuses a directory pin and keeps a symlink default unresol
assert.equal(pinned(r.stdout), join(linkBin, "claude"));
assert.ok(!r.stdout.includes(real), "the target never reaches the unit");
});
+
+// Row 78 (#1572): the default from `command -v claude` takes the same checks
+// as --claude. PATH holds only the test's dirs, so a real claude elsewhere on
+// the host can't stand in for the one under test.
+test("bus-service.sh refuses a default claude without the execute bit, or in a PATH dir with a space", (t) => {
+ const dir = tmp(t);
+ const script = join(REPO, "scripts", "bus-service.sh");
+ const tools = join(dir, "tools");
+ mkdirSync(tools);
+ symlinkSync(process.execPath, join(tools, "node"));
+ for (const tool of ["dirname", "sed", "readlink"]) {
+ const at = ["/usr/bin", "/bin"].map((d) => join(d, tool)).find((p) => existsSync(p));
+ symlinkSync(at, join(tools, tool));
+ }
+ const bash = ["/usr/bin/bash", "/bin/bash"].find((p) => existsSync(p));
+ const run = (bin) => spawnSync(bash, [script, "render"], { encoding: "utf8", env: { PATH: `${bin}:${tools}`, HOME: dir } });
+ const stand = (bin, mode) => {
+ mkdirSync(bin);
+ writeFileSync(join(bin, "claude"), '#!/bin/sh\necho "9.9.9 (Claude Code)"\n');
+ chmodSync(join(bin, "claude"), mode);
+ return bin;
+ };
+
+ // The only claude on PATH has no execute bit: `command -v` still returns
+ // it, and the -x check refuses it.
+ let r = run(stand(join(dir, "noexec-bin"), 0o644));
+ assert.equal(r.status, 1);
+ assert.match(r.stderr, /not an executable file/);
+ assert.equal(r.stdout, "");
+
+ // claude in a PATH dir with a space: systemd would split the pin there.
+ const spaced = stand(join(dir, "spaced bin"), 0o755);
+ r = run(spaced);
+ assert.equal(r.status, 1);
+ assert.match(r.stderr, /cannot carry/);
+ assert.ok(r.stderr.includes(join(spaced, "claude")), r.stderr);
+ assert.equal(r.stdout, "");
+});