# Row 78 (#1572): Claude pin default-path tests, candidate packet, round 1 Author: Rocko. Reviewer: Filbert. Brief: `docs/plans/2026-10-11_claude-pin-and-coder-grant.md`, section "Claude pin default-path tests" (blob 4784ee65, re-pinned by Sage at revs 567-568). This covers Filbert's row 72 note N1, comment 27460 on #1566. Base: `bbd22f1b` (`base.txt`). The packet is uncommitted. I made no commits, pushes or Gitea calls and read no token or private binding. ## Files (`files.txt`, `candidate-manifest.sha256`) | File | Change | |---|---| | `packages/cli/tests/host.test.mjs` | +1 test: "bus-service.sh refuses a default claude without the execute bit, or in a PATH dir with a space" | | `agents/rocko/work/queue-78/mutants.sh` | the mutant rerun: `mutants.sh ` | There's no change to `scripts/bus-service.sh` or `adapters/claude/adapter.sh`. ## What the test does It runs `bus-service.sh render` with no `--claude` under `bash`. `PATH` is the test's own bin dir plus a tools dir holding links to node, dirname, sed and readlink. This is the isolation row 72's test uses, and here it matters: this host has a real `/usr/bin/claude`. With `/usr/bin` on `PATH`, `command -v claude` skips a file without the execute bit and returns that real binary instead. I checked this in a throwaway directory before the build. 1. The only `claude` on `PATH` is a regular file, mode 0644. bash's `command -v` still returns it when no executable `claude` exists. Render exits 1, stderr says "not an executable file", and stdout is empty. 2. `claude`, mode 0755, sits in a `PATH` dir named `spaced bin`. Render exits 1, stderr says "cannot carry" and names the full path, and stdout is empty. As the brief expected, the code refuses both cases. There is no deviation, unlike row 72's directory case. ## Mutants (`out/mutants-candidate.txt`, `out/mutants-base.txt`) The existing `--claude` tests already exercise both checks for a given pin. Dropping either check outright is killed on the base, so it says nothing about the default path. Each mutant here instead makes one check skip only the default (`CLAUDE_SET=0`) and keeps it for `--claude`: | Mutant | Edit in `scripts/bus-service.sh` | Base `bbd22f1b` | Candidate | |---|---|---|---| | `default-skips-exec-check` | `[ "$CLAUDE_SET" = 0 ] \|\| { [ -f "$bin" ] && [ -x "$bin" ]; } \|\| die …` | **survived** | killed: host.test.mjs:640 (case 1's exit status) | | `default-skips-char-check` | `case "$bin" in *[!A-Za-z0-9/._+-]*) [ "$CLAUDE_SET" = 0 ] \|\| die … ;; esac` | **survived** | killed: host.test.mjs:647 (case 2's exit status) | The script saves the file, applies the sed and checks it changed something. It then runs `packages/cli/tests/host.test.mjs` and restores the file from the saved copy. The base run used a clean detached worktree at `bbd22f1b`, which I removed afterwards. `out/mutants-*/` holds each diff and log. The script exits 1 on the base, as it should when a mutant survives. I didn't add a mutant for the absolute-path check. `command -v` returns an absolute path unless a `PATH` entry is relative, and the brief doesn't name that case. ## Gate (`out/gate/`, sequential, scratch worktree at bbd22f1b with the candidate, `node_modules` linked) Run 00:05:37Z-00:09:03Z. | Suite | Result | |---|---| | cli `node --test 'packages/cli/tests/*.test.mjs'` | 114 pass, 0 fail, 0 skipped | | test-auth | 15 passed, 0 failed | | test-conductor | 17 passed, 0 failed | | test-config | 24 passed, 0 failed | | test-discord | 66 passed, 0 failed | | test-extension-package | 18 passed, 0 failed | | test-foundation | 44 passed, 0 failed | | test-queue | 27 passed, 0 failed | | test-release | 14 passed, 0 failed | | test-task | 98 passed, 0 failed (Docker) | The cli count is 114 against 113 at row 72's landing; the one added test is this row's. After the gate I removed the `rocko-r78_default` network.