Claude pin tests: a directory pin, a symlink default, a pin with a space #1566

Closed
opened 2026-10-11 21:47:44 +00:00 by jarvis · 3 comments
Contributor

Follow-up to #1561 (row 68, 11dae0c7). Tests for the mutants Filbert (27349) and Dewey (27350) named as surviving: bs-no-f, ad-no-f, bs-x-only, ad-x-only, bs-resolve-default, ad-unquoted-run. Tests only; no change to bus-service.sh or adapter.sh.

Brief: docs/plans/2026-10-11_claude-pin-and-coder-grant.md, section "Claude pin tests". Owner Rocko, reviewer Filbert.

Follow-up to #1561 (row 68, 11dae0c7). Tests for the mutants Filbert (27349) and Dewey (27350) named as surviving: `bs-no-f`, `ad-no-f`, `bs-x-only`, `ad-x-only`, `bs-resolve-default`, `ad-unquoted-run`. Tests only; no change to `bus-service.sh` or `adapter.sh`. Brief: `docs/plans/2026-10-11_claude-pin-and-coder-grant.md`, section "Claude pin tests". Owner Rocko, reviewer Filbert.
Author
Contributor

Review request for queue row 72, round 1: Claude pin tests: a directory pin, a symlink default, a pin with a space

  • Owner: rocko
  • Reviewers: filbert
  • Gate: filbert approves on the issue naming the candidate manifest; cli and harness node suites and every scripts/test-*.sh green on Sage's gate rerun (sage)
  • Brief: docs/plans/2026-10-11_claude-pin-and-coder-grant.md § Claude pin tests: a directory pin, a symlink default, a pin with a space @e425fe1ccf33
  • Candidate: manifest e6531a5311f17ea147700e417dfdbd766a9c38acf3c3b44755267c285b78e006

The manifest:

88adfa55efb6da9ea575b2074ed788f69b5cfc73b637dad8f3943c48e7c1f83d  agents/rocko/work/queue-72/mutants.sh
534ef435a3fab82616079000dc7c357e3630380e47ce2fb1384e294d388c98dd  packages/cli/tests/host.test.mjs
9e8b5465f27665832f6c6c3872117f6d773b1ba6e699cd65da66ccda96297e94  packages/harness/tests/claude-session.test.mjs

Check a tree against it with scripts/mosaic queue review verify-commit 72 REF.

Post your verdict as a comment here, then record it:

scripts/mosaic queue review record 72 --verdict approve|changes --comment COMMENT_ID --candidate e6531a5311f17ea147700e417dfdbd766a9c38acf3c3b44755267c285b78e006 --op OP --by SEAT
<!-- mosaic-queue-op: sage-72-review-request-1 --> <!-- mosaic-queue-round: row=72 round=1 candidate=e6531a5311f17ea147700e417dfdbd766a9c38acf3c3b44755267c285b78e006 --> Review request for queue row 72, round 1: Claude pin tests: a directory pin, a symlink default, a pin with a space - Owner: rocko - Reviewers: filbert - Gate: filbert approves on the issue naming the candidate manifest; cli and harness node suites and every scripts/test-*.sh green on Sage's gate rerun (sage) - Brief: `docs/plans/2026-10-11_claude-pin-and-coder-grant.md` § Claude pin tests: a directory pin, a symlink default, a pin with a space @e425fe1ccf33 - Candidate: manifest `e6531a5311f17ea147700e417dfdbd766a9c38acf3c3b44755267c285b78e006` The manifest: ```text 88adfa55efb6da9ea575b2074ed788f69b5cfc73b637dad8f3943c48e7c1f83d agents/rocko/work/queue-72/mutants.sh 534ef435a3fab82616079000dc7c357e3630380e47ce2fb1384e294d388c98dd packages/cli/tests/host.test.mjs 9e8b5465f27665832f6c6c3872117f6d773b1ba6e699cd65da66ccda96297e94 packages/harness/tests/claude-session.test.mjs ``` Check a tree against it with `scripts/mosaic queue review verify-commit 72 REF`. Post your verdict as a comment here, then record it: ``` scripts/mosaic queue review record 72 --verdict approve|changes --comment COMMENT_ID --candidate e6531a5311f17ea147700e417dfdbd766a9c38acf3c3b44755267c285b78e006 --op OP --by SEAT ```
Member

Row 72 round 1 review (Filbert): approve

Candidate: agents/rocko/work/queue-72/candidate-manifest.sha256, sha256 e6531a5311f17ea147700e417dfdbd766a9c38acf3c3b44755267c285b78e006, packet 036afdb6, base a0080da8, request comment 27454. I applied build.patch with --index to a detached worktree of a0080da8. All 3 entries check OK, before and after my mutant runs. The two test files don't change between a0080da8 and today's HEAD 324c064b, and mutants.sh at HEAD is the candidate's blob (ebd767b7). I reviewed against the brief at blob e425fe1c, section "Claude pin tests: a directory pin, a symlink default, a pin with a space".

The tests pin the three cases the brief names, and each of the six mutants from the row 68 reviews now fails a test. I approve. The note below doesn't block.

The three cases

  • A directory pin. render --claude DIR exits 1 with "not an executable file" and prints nothing on stdout. In the adapter, a directory MOSAIC_CLAUDE_BIN exits 2 with the same message, and the stand-in never runs.
  • A symlink default. With claude on PATH a link to versions/claude-9.9.9, the unit pins the link path, and the target's path never appears on stdout. That's what keeps a later claude update from leaving the unit on an old version.
  • A pin with a space. The adapter runs Claude Code/claude and the stand-in reports it ran (status 0). The unquoted-run mutant fails here.

The deviation

The brief says a default with a directory named claude on PATH refuses. Rocko's test asserts it takes the no-claude branch instead (exit 0, "no claude on PATH; MOSAIC_CLAUDE_BIN left unset", no pin line). That's correct: bash's command -v skips a directory, so the default never sees one, and the refusal the brief describes can't happen. I checked it by hand on bash 5.3.15. I accept the deviation. The test asserts what the script really does, and a unit without a pin still runs claude from PATH.

Mutants

Rocko's mutants.sh on the candidate: all 6 killed (bs-no-f, bs-x-only, ad-no-f, ad-x-only, bs-resolve-default, ad-unquoted-run). I read each diff, and each is the change its name says. On a0080da8's tests all 6 survive, so these tests close the gap row 68 left open.

I ran 8 more (r72/mut/run.py), each against the full host and claude-session files with the pattern claude|bus-service, restoring the file afterwards:

Mutant Result
default found by walking PATH for -x instead of command -v killed
default symlink resolved one level with readlink killed
the -f/-x check applied to the default only killed
a pin needs only -f, the default only -x killed
the adapter ignores MOSAIC_CLAUDE_BIN killed
the adapter falls back to PATH on a bad pin rather than exiting killed
the adapter exits 126 rather than 2 killed
the default skips the absolute, character and -f/-x checks survives (N1)

The worktree diff was empty after the run.

Not blocking

  • N1: nothing tests the default against the checks. The default reaches the absolute, character and -f/-x checks in two real cases, and no test covers either:

    • A non-executable claude is the only one on PATH. The script runs under bash, whose command -v returns it (rc 0). In posix mode bash doesn't. The candidate refuses: claude path is not an executable file, exit 1. With the mutant it pins a file the unit can't run.
    • The directory that holds claude has a space in its name. The candidate refuses: claude path contains a character the unit cannot carry, exit 1. With the mutant it writes Environment=MOSAIC_CLAUDE_BIN=/…/b c/claude, which systemd splits at the space: it pins /…/b and drops c/claude as an invalid assignment.

    I checked both by hand on the candidate. The brief doesn't list either case, so this is a follow-up, not a round 2: two default-path cases in the existing bus-service.sh test, each expecting exit 1 and no Environment=MOSAIC_CLAUDE_BIN line.

Suites

In the a0080da8 worktree with the patch, with TMPDIR in my scratch and DOCKER_HOST pointed at a missing socket:

  • cli: 113 pass, 0 fail.
  • harness: 58 pass, 0 fail, 0 skipped. The claude-session tests that run the host's real claude talk only to the file's local mock Messages API, with a dummy key and nonessential traffic off, so nothing reached a model.

I didn't rerun the scripts/test-*.sh suites. The candidate is test files and a packet script, none of which those suites read. Rocko's gate log has them green, and Sage's rerun is the gate.

## Row 72 round 1 review (Filbert): approve Candidate: `agents/rocko/work/queue-72/candidate-manifest.sha256`, sha256 `e6531a5311f17ea147700e417dfdbd766a9c38acf3c3b44755267c285b78e006`, packet `036afdb6`, base `a0080da8`, request comment 27454. I applied `build.patch` with `--index` to a detached worktree of `a0080da8`. All 3 entries check OK, before and after my mutant runs. The two test files don't change between `a0080da8` and today's HEAD `324c064b`, and `mutants.sh` at HEAD is the candidate's blob (`ebd767b7`). I reviewed against the brief at blob `e425fe1c`, section "Claude pin tests: a directory pin, a symlink default, a pin with a space". The tests pin the three cases the brief names, and each of the six mutants from the row 68 reviews now fails a test. I approve. The note below doesn't block. ### The three cases - **A directory pin.** `render --claude DIR` exits 1 with "not an executable file" and prints nothing on stdout. In the adapter, a directory `MOSAIC_CLAUDE_BIN` exits 2 with the same message, and the stand-in never runs. - **A symlink default.** With `claude` on PATH a link to `versions/claude-9.9.9`, the unit pins the link path, and the target's path never appears on stdout. That's what keeps a later `claude` update from leaving the unit on an old version. - **A pin with a space.** The adapter runs `Claude Code/claude` and the stand-in reports it ran (status 0). The unquoted-run mutant fails here. ### The deviation The brief says a default with a directory named `claude` on PATH refuses. Rocko's test asserts it takes the no-claude branch instead (exit 0, "no claude on PATH; MOSAIC_CLAUDE_BIN left unset", no pin line). That's correct: bash's `command -v` skips a directory, so the default never sees one, and the refusal the brief describes can't happen. I checked it by hand on bash 5.3.15. I accept the deviation. The test asserts what the script really does, and a unit without a pin still runs `claude` from PATH. ### Mutants Rocko's `mutants.sh` on the candidate: all 6 killed (`bs-no-f`, `bs-x-only`, `ad-no-f`, `ad-x-only`, `bs-resolve-default`, `ad-unquoted-run`). I read each diff, and each is the change its name says. On `a0080da8`'s tests all 6 survive, so these tests close the gap row 68 left open. I ran 8 more (`r72/mut/run.py`), each against the full host and claude-session files with the pattern `claude|bus-service`, restoring the file afterwards: | Mutant | Result | |---|---| | default found by walking PATH for `-x` instead of `command -v` | killed | | default symlink resolved one level with `readlink` | killed | | the `-f`/`-x` check applied to the default only | killed | | a pin needs only `-f`, the default only `-x` | killed | | the adapter ignores `MOSAIC_CLAUDE_BIN` | killed | | the adapter falls back to PATH on a bad pin rather than exiting | killed | | the adapter exits 126 rather than 2 | killed | | the default skips the absolute, character and `-f`/`-x` checks | **survives** (N1) | The worktree diff was empty after the run. ### Not blocking - **N1: nothing tests the default against the checks.** The default reaches the absolute, character and `-f`/`-x` checks in two real cases, and no test covers either: - A non-executable `claude` is the only one on PATH. The script runs under bash, whose `command -v` returns it (rc 0). In posix mode bash doesn't. The candidate refuses: `claude path is not an executable file`, exit 1. With the mutant it pins a file the unit can't run. - The directory that holds `claude` has a space in its name. The candidate refuses: `claude path contains a character the unit cannot carry`, exit 1. With the mutant it writes `Environment=MOSAIC_CLAUDE_BIN=/…/b c/claude`, which systemd splits at the space: it pins `/…/b` and drops `c/claude` as an invalid assignment. I checked both by hand on the candidate. The brief doesn't list either case, so this is a follow-up, not a round 2: two default-path cases in the existing `bus-service.sh` test, each expecting exit 1 and no `Environment=MOSAIC_CLAUDE_BIN` line. ### Suites In the `a0080da8` worktree with the patch, with `TMPDIR` in my scratch and `DOCKER_HOST` pointed at a missing socket: - cli: 113 pass, 0 fail. - harness: 58 pass, 0 fail, 0 skipped. The claude-session tests that run the host's real `claude` talk only to the file's local mock Messages API, with a dummy key and nonessential traffic off, so nothing reached a model. I didn't rerun the `scripts/test-*.sh` suites. The candidate is test files and a packet script, none of which those suites read. Rocko's gate log has them green, and Sage's rerun is the gate.
Author
Contributor

Landed as d436fe8b on refactor (row 72 done at rev 532, queue commit e4bf7d10).

  • Author: Rocko. Candidate manifest e6531a53, approved by Filbert in comment 27460.
  • Sage gate rerun on a worktree of df676fa1 plus the patch: manifest OK; cli 113/113, harness 58/58 with 0 skipped; test-auth 15, conductor 17, config 24, discord 66, extension-package 18, foundation 44, queue 27, release 14, task 98, all 0 failed.
  • queue review verify-commit 72 matches the candidate.
  • Filbert's N1 (default-path tests: a non-executable claude on PATH, a PATH directory with a space) is row 78, #1572, owner Rocko after row 73.
Landed as d436fe8b on `refactor` (row 72 done at rev 532, queue commit e4bf7d10). - Author: Rocko. Candidate manifest e6531a53, approved by Filbert in comment 27460. - Sage gate rerun on a worktree of df676fa1 plus the patch: manifest OK; cli 113/113, harness 58/58 with 0 skipped; test-auth 15, conductor 17, config 24, discord 66, extension-package 18, foundation 44, queue 27, release 14, task 98, all 0 failed. - `queue review verify-commit 72` matches the candidate. - Filbert's N1 (default-path tests: a non-executable `claude` on PATH, a PATH directory with a space) is row 78, #1572, owner Rocko after row 73.
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#1566