review(rocko): row 72 round 1 packet, Claude pin tests (#1566)
Rocko's packet agents/rocko/work/queue-72/ (candidate manifest e6531a53,
base a0080da8) with their BUILD-LOG and SESSIONS appends, and Sage's
SESSIONS line for the jarvis review request (comment 27454).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -4248,3 +4248,11 @@ After: feat 743c01e3, which `queue review verify-commit 75 HEAD` matches to roun
|
||||
Gate (Sage, scratch worktree of 8b351c3d plus the candidate, sequential and teed, finished 22:49Z): webui 50/50 node tests; test-auth 15, test-conductor 17, test-config 24, test-discord 66, test-extension-package 18, test-foundation 44, test-queue 27, test-release 14, test-task 98, all 0 failed (Docker on). Manifest OK. The sage-g75_default network, node_modules link and worktree were removed. Row 75 done at rev 519 (f0c37f75); #1569 closed with comment 27434.
|
||||
|
||||
Not yet installed. The preview flags make serve refuse until row 74 lands; Filbert approved row 74 at rev 518 (27433). Filbert's notes N1-N5 are row 77, #1571, brief 8b351c3d, owner Rocko, after the cutover.
|
||||
|
||||
### 2026-10-11 — Rocko, row 72 round 1 candidate: Claude pin tests (#1566)
|
||||
|
||||
Before (a0080da8): no test covered a directory pin, a symlink default or a pin with a space. All six mutants of bus-service.sh and adapter.sh pass the existing tests, as listed in agents/rocko/work/queue-72/BUILD.md (-f to -e, -x only, readlink -f on the default, unquoted run).
|
||||
|
||||
After (candidate, uncommitted packet agents/rocko/work/queue-72/, candidate manifest e6531a53): one test in host.test.mjs, one in claude-session.test.mjs, and mutants.sh. All six mutants are killed on the candidate and all six survive on the base. Deviation from the brief: a directory named claude on PATH can't reach the default pin, because bash's command -v skips directories. The test asserts the real behaviour: no pin, with exit 0. No change to bus-service.sh or adapter.sh.
|
||||
|
||||
Gate (Rocko, scratch worktree a0080da8 plus the candidate, sequential): cli 113/113, harness 58/58 with 0 skipped; test-auth 15, test-conductor 17, test-config 24, test-discord 66, test-extension-package 18, test-foundation 44, test-queue 27, test-release 14, test-task 98, all with 0 failed (Docker). Removed the rocko-r72_default network. No commits, no pushes, no tokens read.
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
# Row 72 (#1566): Claude pin tests, candidate packet, round 1
|
||||
|
||||
Author: Rocko. Reviewer: Filbert. Brief:
|
||||
`docs/plans/2026-10-11_claude-pin-and-coder-grant.md`, section "Claude pin
|
||||
tests: a directory pin, a symlink default, a pin with a space". Base:
|
||||
`a0080da8` (`base.txt`). At 2026-10-11T23:03Z the checkout HEAD `ebd90554`
|
||||
has no change since the base to either test file, `bus-service.sh` or
|
||||
`adapter.sh`, and `build.patch` applies to it cleanly. Tests only: no
|
||||
change to `bus-service.sh`, `adapter.sh`, the launcher or the session code.
|
||||
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 directory pin and keeps a symlink default unresolved" |
|
||||
| `packages/harness/tests/claude-session.test.mjs` | +1 test: "claude adapter: a directory pin exits 2 before it runs; a pin with a space runs" |
|
||||
| `agents/rocko/work/queue-72/mutants.sh` | the mutant rerun, so a reviewer can repeat it: `mutants.sh <tree>` |
|
||||
|
||||
## What the tests check
|
||||
|
||||
- `render --claude DIR` (a 0755 directory) exits 1 with "not an executable
|
||||
file" and prints nothing on stdout.
|
||||
- **Deviation from the brief: the default with a directory named `claude` on
|
||||
`PATH`.** The brief says it refuses with "not an executable file". That
|
||||
can't happen: bash's `command -v` never returns a directory. With
|
||||
only a directory named `claude` on PATH it finds nothing (rc 1); with
|
||||
`/usr/bin` behind it, it returns `/usr/bin/claude`. So the default goes down
|
||||
the "no claude on PATH" branch: exit 0, a comment, no pin. The test
|
||||
asserts that, and that the directory's path never reaches the unit. The
|
||||
code is not wrong. The hazard the brief names, a unit carrying a directory
|
||||
pin, can't come from the default, only from `--claude`, and the first case
|
||||
covers that. I checked this by hand before writing the test (`env -i`, PATH
|
||||
of only the directory plus the tools).
|
||||
- The default with a symlink named `claude` on PATH, pointing to an
|
||||
executable in another directory: `MOSAIC_CLAUDE_BIN` is the link's path,
|
||||
and the target's path appears nowhere in the unit.
|
||||
- Adapter, `MOSAIC_CLAUDE_BIN` a directory: exit 2 with "MOSAIC_CLAUDE_BIN is
|
||||
not an executable file", and the stand-in on PATH never runs.
|
||||
- Adapter, a stand-in at `<dir>/Claude Code/claude`: exit 0, and that
|
||||
stand-in is the one that ran.
|
||||
|
||||
The host test runs bash with a PATH of only the test directory and a tools
|
||||
directory (node, dirname, sed, readlink), as row 68's no-claude case does, so
|
||||
the host's own claude can't stand in. No test spawns a real claude.
|
||||
|
||||
## Mutants (`out/mutants-candidate.txt`, `out/mutants-base.txt`)
|
||||
|
||||
The reviewers' comments name the mutants but don't write them out on the
|
||||
checkout, so `mutants.sh` defines each from the brief's description:
|
||||
|
||||
| Mutant | Edit | Base `a0080da8` | Candidate |
|
||||
|---|---|---|---|
|
||||
| `bs-no-f` | bus-service `claude_line`: `[ -f "$bin" ]` → `[ -e "$bin" ]` | survived | killed (host directory-pin test) |
|
||||
| `bs-x-only` | bus-service: only `[ -x "$bin" ]` | survived | killed (host) |
|
||||
| `ad-no-f` | adapter: `[ -f "$MOSAIC_CLAUDE_BIN" ]` → `[ -e … ]` | survived | killed (adapter test) |
|
||||
| `ad-x-only` | adapter: only `[ -x "$MOSAIC_CLAUDE_BIN" ]` | survived | killed (adapter) |
|
||||
| `bs-resolve-default` | bus-service: default `bin` passed through `readlink -f` | survived | killed (host symlink case) |
|
||||
| `ad-unquoted-run` | adapter: `"$CLAUDE" -p` → `$CLAUDE -p` | survived | killed (adapter space case) |
|
||||
|
||||
Per mutant, the script checks that the sed changed the file, saves the
|
||||
diff, runs the five pin tests, then restores the file from git. Before
|
||||
mutating, it refuses if either file is already modified or if the unmutated
|
||||
run fails. `out/mutants-candidate/` and `out/mutants-base/` hold each
|
||||
mutant's diff and log.
|
||||
|
||||
## Gate (`out/gate/`, sequential, scratch worktree at a0080da8 with the patch, `node_modules` linked)
|
||||
|
||||
| Suite | Result |
|
||||
|---|---|
|
||||
| cli `node --test 'packages/cli/tests/*.test.mjs'` | 113 pass, 0 fail |
|
||||
| harness `node --test 'packages/harness/tests/*.test.mjs'` | 58 pass, 0 fail, 0 skipped (claude on PATH) |
|
||||
| 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) |
|
||||
|
||||
After the gate I removed the `rocko-r72_default` network.
|
||||
@@ -0,0 +1 @@
|
||||
a0080da8c901c4db6a653598f14a692567bd832a
|
||||
@@ -0,0 +1,168 @@
|
||||
diff --git a/agents/rocko/work/queue-72/mutants.sh b/agents/rocko/work/queue-72/mutants.sh
|
||||
new file mode 100755
|
||||
index 00000000..ebd767b7
|
||||
--- /dev/null
|
||||
+++ b/agents/rocko/work/queue-72/mutants.sh
|
||||
@@ -0,0 +1,47 @@
|
||||
+#!/usr/bin/env bash
|
||||
+# Row 72 (#1566): rerun the six mutants the row 68 reviewers named against a
|
||||
+# tree with the candidate tests. Usage: mutants.sh <tree>. Each mutant edits
|
||||
+# one line of bus-service.sh or adapter.sh, runs the pin tests, and restores
|
||||
+# the file from git. Prints "killed" or "SURVIVED" per mutant; exit 1 if any
|
||||
+# mutant survives, a sed doesn't change its file, or the unmutated run fails.
|
||||
+set -euo pipefail
|
||||
+TREE="$(cd "${1:?usage: mutants.sh <tree>}" && pwd)"
|
||||
+cd "$TREE"
|
||||
+BS=scripts/bus-service.sh
|
||||
+AD=adapters/claude/adapter.sh
|
||||
+PATTERN='directory pin|symlink default|pin with a space|pins the claude|MOSAIC_CLAUDE_BIN wins'
|
||||
+TESTS=(packages/cli/tests/host.test.mjs packages/harness/tests/claude-session.test.mjs)
|
||||
+run_tests() { node --test --test-name-pattern="$PATTERN" "${TESTS[@]}" >"$1" 2>&1; }
|
||||
+
|
||||
+# name | file | sed expression
|
||||
+MUTANTS=(
|
||||
+ 'bs-no-f|'"$BS"'|s/\[ -f "\$bin" \] \&\& \[ -x "\$bin" \]/[ -e "$bin" ] \&\& [ -x "$bin" ]/'
|
||||
+ 'bs-x-only|'"$BS"'|s/\[ -f "\$bin" \] \&\& \[ -x "\$bin" \]/[ -x "$bin" ]/'
|
||||
+ 'ad-no-f|'"$AD"'|s/\[ -f "\$MOSAIC_CLAUDE_BIN" \] \&\& \[ -x "\$MOSAIC_CLAUDE_BIN" \]/[ -e "$MOSAIC_CLAUDE_BIN" ] \&\& [ -x "$MOSAIC_CLAUDE_BIN" ]/'
|
||||
+ 'ad-x-only|'"$AD"'|s/\[ -f "\$MOSAIC_CLAUDE_BIN" \] \&\& \[ -x "\$MOSAIC_CLAUDE_BIN" \]/[ -x "$MOSAIC_CLAUDE_BIN" ]/'
|
||||
+ 'bs-resolve-default|'"$BS"'|s/^ bin="\$(command -v claude || true)"$/ bin="$(command -v claude || true)"; [ -z "$bin" ] || bin="$(readlink -f "$bin")"/'
|
||||
+ 'ad-unquoted-run|'"$AD"'|s/^"\$CLAUDE" -p /$CLAUDE -p /'
|
||||
+)
|
||||
+
|
||||
+OUT="${OUT:-$TREE/.mutants}"
|
||||
+mkdir -p "$OUT"
|
||||
+git diff --quiet -- "$BS" "$AD" || { echo "refusing: $BS or $AD already modified" >&2; exit 1; }
|
||||
+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 file expr <<<"$m"
|
||||
+ sed -i -e "$expr" "$file"
|
||||
+ if git diff --quiet -- "$file"; then
|
||||
+ echo "$name: NOT APPLIED (sed matched nothing)"; status=1; continue
|
||||
+ fi
|
||||
+ git diff -- "$file" >"$OUT/$name.diff"
|
||||
+ if run_tests "$OUT/$name.log"; then
|
||||
+ echo "$name: SURVIVED"; status=1
|
||||
+ else
|
||||
+ echo "$name: killed ($(grep -E '^✖' "$OUT/$name.log" | sed 's/ ([0-9.]*ms)$//' | sort -u | tr '\n' ';' ))"
|
||||
+ fi
|
||||
+ git checkout -q -- "$file"
|
||||
+done
|
||||
+git diff --quiet -- "$BS" "$AD" || { echo "restore failed" >&2; exit 1; }
|
||||
+exit "$status"
|
||||
diff --git a/packages/cli/tests/host.test.mjs b/packages/cli/tests/host.test.mjs
|
||||
index 0a5d6825..13a621ae 100644
|
||||
--- a/packages/cli/tests/host.test.mjs
|
||||
+++ b/packages/cli/tests/host.test.mjs
|
||||
@@ -559,3 +559,55 @@ test("bus-service.sh pins the claude binary, refuses one the unit can't carry, a
|
||||
assert.match(none.stdout, /^# MOSAIC_CLAUDE_BIN unset: no claude on PATH at install time$/m);
|
||||
assert.doesNotMatch(none.stdout, /@CLAUDE_ENV@/);
|
||||
});
|
||||
+
|
||||
+// Row 72 (#1566): mutants row 68's tests left alive. A directory is -x, so
|
||||
+// only the -f check keeps a directory pin out of the unit; the default pin
|
||||
+// keeps a symlink as given, so a claude that updates through it is followed.
|
||||
+test("bus-service.sh refuses a directory pin and keeps a symlink default unresolved", (t) => {
|
||||
+ const dir = tmp(t);
|
||||
+ const script = join(REPO, "scripts", "bus-service.sh");
|
||||
+ const pinned = (out) => out.match(/^Environment=MOSAIC_CLAUDE_BIN=(.*)$/m)?.[1];
|
||||
+ 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 = (args, bin) => spawnSync(bash, [script, ...args], { encoding: "utf8", env: { PATH: `${bin}:${tools}`, HOME: dir } });
|
||||
+
|
||||
+ // --claude DIR: a directory passes -x and fails -f.
|
||||
+ const pinDir = join(dir, "claude-dir");
|
||||
+ mkdirSync(pinDir);
|
||||
+ chmodSync(pinDir, 0o755);
|
||||
+ let r = run(["render", "--claude", pinDir], join(dir, "empty"));
|
||||
+ assert.equal(r.status, 1);
|
||||
+ assert.match(r.stderr, /not an executable file/);
|
||||
+ assert.equal(r.stdout, "");
|
||||
+
|
||||
+ // A directory named claude on PATH: bash's `command -v` never returns a
|
||||
+ // directory, so the default finds no claude and pins nothing. It never
|
||||
+ // pins the directory.
|
||||
+ const dirBin = join(dir, "dir-bin");
|
||||
+ mkdirSync(join(dirBin, "claude"), { recursive: true });
|
||||
+ chmodSync(join(dirBin, "claude"), 0o755);
|
||||
+ r = run(["render"], dirBin);
|
||||
+ assert.equal(r.status, 0, r.stderr);
|
||||
+ assert.match(r.stderr, /no claude on PATH; MOSAIC_CLAUDE_BIN left unset/);
|
||||
+ assert.equal(pinned(r.stdout), undefined);
|
||||
+ assert.ok(!r.stdout.includes(join(dirBin, "claude")));
|
||||
+
|
||||
+ // A symlink named claude on PATH: the pin is the link, not its target.
|
||||
+ const real = join(dir, "versions", "claude-9.9.9");
|
||||
+ mkdirSync(dirname(real));
|
||||
+ writeFileSync(real, '#!/bin/sh\necho "9.9.9 (Claude Code)"\n');
|
||||
+ chmodSync(real, 0o755);
|
||||
+ const linkBin = join(dir, "link-bin");
|
||||
+ mkdirSync(linkBin);
|
||||
+ symlinkSync(real, join(linkBin, "claude"));
|
||||
+ r = run(["render"], linkBin);
|
||||
+ assert.equal(r.status, 0, r.stderr);
|
||||
+ assert.equal(pinned(r.stdout), join(linkBin, "claude"));
|
||||
+ assert.ok(!r.stdout.includes(real), "the target never reaches the unit");
|
||||
+});
|
||||
diff --git a/packages/harness/tests/claude-session.test.mjs b/packages/harness/tests/claude-session.test.mjs
|
||||
index eb680836..213c811e 100644
|
||||
--- a/packages/harness/tests/claude-session.test.mjs
|
||||
+++ b/packages/harness/tests/claude-session.test.mjs
|
||||
@@ -215,6 +215,50 @@ test("claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute e
|
||||
}
|
||||
});
|
||||
|
||||
+// Row 72 (#1566): a directory pin exits 2 with the adapter's own message,
|
||||
+// not 126 at exec; a pin under a directory whose name has a space runs,
|
||||
+// which needs "$CLAUDE" quoted.
|
||||
+test("claude adapter: a directory pin exits 2 before it runs; a pin with a space runs", (t) => {
|
||||
+ const dir = scratch(t);
|
||||
+ mkdirSync(join(dir, "bin"));
|
||||
+ const stand = (p, word) => {
|
||||
+ writeFileSync(p, `#!/bin/sh\necho ${word} > "$WHO_OUT"\necho ok\n`);
|
||||
+ chmodSync(p, 0o755);
|
||||
+ return p;
|
||||
+ };
|
||||
+ stand(join(dir, "bin", "claude"), "path");
|
||||
+ for (const f of ["prompt.md", "settings.json", "mcp.json"]) writeFileSync(join(dir, f), "{}");
|
||||
+ const run = (bin) => spawnSync("/bin/sh", [ADAPTER], {
|
||||
+ encoding: "utf8",
|
||||
+ stdio: ["ignore", "pipe", "pipe"],
|
||||
+ env: {
|
||||
+ PATH: `${join(dir, "bin")}:/usr/bin:/bin`,
|
||||
+ WHO_OUT: join(dir, "who"),
|
||||
+ MOSAIC_SYSTEM_PROMPT_FILE: join(dir, "prompt.md"),
|
||||
+ MOSAIC_REQUEST: "x",
|
||||
+ MOSAIC_WORKSPACE: join(dir, "ws"),
|
||||
+ MOSAIC_SESSION_DIR: join(dir, "session"),
|
||||
+ MOSAIC_MODEL: "claude-sonnet-5-5",
|
||||
+ MOSAIC_CLAUDE_SETTINGS: join(dir, "settings.json"),
|
||||
+ MOSAIC_CLAUDE_MCP_CONFIG: join(dir, "mcp.json"),
|
||||
+ MOSAIC_CLAUDE_BIN: bin,
|
||||
+ },
|
||||
+ });
|
||||
+ const pinDir = join(dir, "claude-dir");
|
||||
+ mkdirSync(pinDir);
|
||||
+ chmodSync(pinDir, 0o755);
|
||||
+ let r = run(pinDir);
|
||||
+ assert.equal(r.status, 2, r.stderr);
|
||||
+ assert.match(r.stderr, /MOSAIC_CLAUDE_BIN is not an executable file/);
|
||||
+ assert.equal(existsSync(join(dir, "who")), false);
|
||||
+
|
||||
+ mkdirSync(join(dir, "Claude Code"));
|
||||
+ const spaced = stand(join(dir, "Claude Code", "claude"), "spaced");
|
||||
+ r = run(spaced);
|
||||
+ assert.equal(r.status, 0, r.stderr);
|
||||
+ assert.equal(readFileSync(join(dir, "who"), "utf8").trim(), "spaced");
|
||||
+});
|
||||
+
|
||||
test("claude: CLAUDE.md files and auto-memory don't reach the model; without --restricted they do", { skip }, async (t) => {
|
||||
const { dir, workspace, env } = await session(t, []);
|
||||
const slug = realpathSync(workspace).replace(/[/.]/g, "-");
|
||||
@@ -0,0 +1,3 @@
|
||||
88adfa55efb6da9ea575b2074ed788f69b5cfc73b637dad8f3943c48e7c1f83d agents/rocko/work/queue-72/mutants.sh
|
||||
534ef435a3fab82616079000dc7c357e3630380e47ce2fb1384e294d388c98dd packages/cli/tests/host.test.mjs
|
||||
9e8b5465f27665832f6c6c3872117f6d773b1ba6e699cd65da66ccda96297e94 packages/harness/tests/claude-session.test.mjs
|
||||
@@ -0,0 +1,3 @@
|
||||
agents/rocko/work/queue-72/mutants.sh
|
||||
packages/cli/tests/host.test.mjs
|
||||
packages/harness/tests/claude-session.test.mjs
|
||||
Executable
+47
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env bash
|
||||
# Row 72 (#1566): rerun the six mutants the row 68 reviewers named against a
|
||||
# tree with the candidate tests. Usage: mutants.sh <tree>. Each mutant edits
|
||||
# one line of bus-service.sh or adapter.sh, runs the pin tests, and restores
|
||||
# the file from git. Prints "killed" or "SURVIVED" per mutant; exit 1 if any
|
||||
# mutant survives, a sed doesn't change its file, or the unmutated run fails.
|
||||
set -euo pipefail
|
||||
TREE="$(cd "${1:?usage: mutants.sh <tree>}" && pwd)"
|
||||
cd "$TREE"
|
||||
BS=scripts/bus-service.sh
|
||||
AD=adapters/claude/adapter.sh
|
||||
PATTERN='directory pin|symlink default|pin with a space|pins the claude|MOSAIC_CLAUDE_BIN wins'
|
||||
TESTS=(packages/cli/tests/host.test.mjs packages/harness/tests/claude-session.test.mjs)
|
||||
run_tests() { node --test --test-name-pattern="$PATTERN" "${TESTS[@]}" >"$1" 2>&1; }
|
||||
|
||||
# name | file | sed expression
|
||||
MUTANTS=(
|
||||
'bs-no-f|'"$BS"'|s/\[ -f "\$bin" \] \&\& \[ -x "\$bin" \]/[ -e "$bin" ] \&\& [ -x "$bin" ]/'
|
||||
'bs-x-only|'"$BS"'|s/\[ -f "\$bin" \] \&\& \[ -x "\$bin" \]/[ -x "$bin" ]/'
|
||||
'ad-no-f|'"$AD"'|s/\[ -f "\$MOSAIC_CLAUDE_BIN" \] \&\& \[ -x "\$MOSAIC_CLAUDE_BIN" \]/[ -e "$MOSAIC_CLAUDE_BIN" ] \&\& [ -x "$MOSAIC_CLAUDE_BIN" ]/'
|
||||
'ad-x-only|'"$AD"'|s/\[ -f "\$MOSAIC_CLAUDE_BIN" \] \&\& \[ -x "\$MOSAIC_CLAUDE_BIN" \]/[ -x "$MOSAIC_CLAUDE_BIN" ]/'
|
||||
'bs-resolve-default|'"$BS"'|s/^ bin="\$(command -v claude || true)"$/ bin="$(command -v claude || true)"; [ -z "$bin" ] || bin="$(readlink -f "$bin")"/'
|
||||
'ad-unquoted-run|'"$AD"'|s/^"\$CLAUDE" -p /$CLAUDE -p /'
|
||||
)
|
||||
|
||||
OUT="${OUT:-$TREE/.mutants}"
|
||||
mkdir -p "$OUT"
|
||||
git diff --quiet -- "$BS" "$AD" || { echo "refusing: $BS or $AD already modified" >&2; exit 1; }
|
||||
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 file expr <<<"$m"
|
||||
sed -i -e "$expr" "$file"
|
||||
if git diff --quiet -- "$file"; then
|
||||
echo "$name: NOT APPLIED (sed matched nothing)"; status=1; continue
|
||||
fi
|
||||
git diff -- "$file" >"$OUT/$name.diff"
|
||||
if run_tests "$OUT/$name.log"; then
|
||||
echo "$name: SURVIVED"; status=1
|
||||
else
|
||||
echo "$name: killed ($(grep -E '^✖' "$OUT/$name.log" | sed 's/ ([0-9.]*ms)$//' | sort -u | tr '\n' ';' ))"
|
||||
fi
|
||||
git checkout -q -- "$file"
|
||||
done
|
||||
git diff --quiet -- "$BS" "$AD" || { echo "restore failed" >&2; exit 1; }
|
||||
exit "$status"
|
||||
@@ -0,0 +1,123 @@
|
||||
✔ every screen and overlay fits 120x36, 80x24 and the narrow layout, row for row (8166.765346ms)
|
||||
✔ width counts terminal cells: wide CJK and emoji 2, U+FE0F after a one-cell base 1, marks 0 (572.522763ms)
|
||||
✔ broker text is shown, never interpreted: no raw control character or bidi override reaches the terminal (997.261698ms)
|
||||
✔ NO_COLOR: no escape codes, except reverse video on the selected row (1366.594383ms)
|
||||
✔ 1-9 shows the decide flow's own lines and question; only y resolves (324.985306ms)
|
||||
✔ the app shows the same decide text as mosaic decide (105.472122ms)
|
||||
✔ any key but y or Y at the question answers No; nothing is sent (979.98217ms)
|
||||
✔ below 40x10 the question is hidden, so every key answers it No, y included (Filbert R3) (537.613643ms)
|
||||
✔ a throw while answering the question goes to crash, sends nothing and leaves no job pending (139.952237ms)
|
||||
✔ type-ahead never answers the question: a paste, keys typed before it is drawn, keys inside askMs (907.979929ms)
|
||||
✔ quitting at the question answers No and sends nothing, armed or not (115.13296ms)
|
||||
✔ a timer tick reads nothing under an overlay, never answers the question, and keeps a resolved status (124.787577ms)
|
||||
✔ a long question is cut inside the question; the action, target, choice and prompt stay (Dewey B1) (110.884622ms)
|
||||
✔ a decide box too big for the terminal says so, and every key answers it No, y included (Dewey B1, round 3) (1166.07854ms)
|
||||
✔ at every size the decide box shows each line y depends on, or says it is hidden (31504.438386ms)
|
||||
✔ outcome unknown: the CLI's sentence, no retry, then the trail or a re-read (440.615391ms)
|
||||
✔ refused and failed reads keep the last list, marked stale; a refused decide says refused (184.256448ms)
|
||||
✔ keys: views, moving, trail of a selection, the command line, help and quit (437.25353ms)
|
||||
✔ one option: the status line says Press 1, not 1-1 (56.747724ms)
|
||||
✔ no business: the app says so and :business picks one (36.701946ms)
|
||||
✔ mosaic with no argument: exit 3 in an agent run, exit 4 with the usage off a terminal, the app on one (4.497651ms)
|
||||
✔ scripts/mosaic with no argument reaches the app entry; the seat usage it printed before has not drifted (852.094435ms)
|
||||
✔ strings to keep exactly live once, in the decide flow and the transport; the app does not restate them (1.039678ms)
|
||||
✔ decide with --note still asks; a No sends nothing (30.558987ms)
|
||||
✔ the app's business comes from a live bus host only (4.039615ms)
|
||||
✔ runApp leaves the terminal as it found it on q, end of input, SIGTERM, SIGINT, SIGHUP and an error, the first frame's included (48.387881ms)
|
||||
✔ draw is pure: same state, same frame (4.095435ms)
|
||||
✔ inbox lists only decisions routed to the human, with what approving authorizes and how to decide (70.100468ms)
|
||||
✔ decide resolves by id prefix with --yes, and the trail shows it in broker order with the task to follow (89.010174ms)
|
||||
✔ decide refuses without a terminal or --yes, on an unknown option and on a short reference (131.922309ms)
|
||||
✔ decide prints a declining choice as declining (136.78509ms)
|
||||
✔ an unknown outcome is reported once and never resent (118.819165ms)
|
||||
✔ a decision closed before the answer arrives exits 2 and points at its trail (137.479336ms)
|
||||
✔ a prefix that matches two open decisions exits 2 and resolves neither (178.591685ms)
|
||||
✔ without --business a command uses the live host's business, and a stale host.json is not a host (91.800624ms)
|
||||
✔ every human command refuses inside an agent run before it touches the bus (77.839866ms)
|
||||
✔ usage errors exit 4; no business and no host is a usage error (138.875876ms)
|
||||
✔ agents and tasks print through the broker (60.090991ms)
|
||||
✔ notify.json: missing, loose, malformed and extra keys refuse; a binding or null passes (5.32231ms)
|
||||
✔ bootConfig builds the broker's boot message for one business, with no trackers key when no project names one (279.470054ms)
|
||||
✔ trackers come from the tracker.* variables of the one project that names a tracker project (517.50159ms)
|
||||
✔ with two projects, the one that sets tracker.project supplies the tracker and the other is no conflict (406.234323ms)
|
||||
✔ two projects that each name a tracker project refuse, since the boot shape holds one (222.948756ms)
|
||||
✔ a business without tracker.baseUrl gets no trackers entry (257.879607ms)
|
||||
✔ an unknown business and a broken system config refuse with exit 3 (352.978931ms)
|
||||
✔ empty views say so (4.151914ms)
|
||||
✔ the trail keeps the broker's order and names a decision's task without its rows (5.793327ms)
|
||||
✔ tasks print the tracker fields the snapshot carries (0.504836ms)
|
||||
✔ the host boots the broker, binds a launch in process, and the notifier DMs a blocking decision exactly once (2032.065812ms)
|
||||
✔ a notifier that dies takes the host down with exit 1, so the unit restarts the pair (1258.637038ms)
|
||||
✔ a second host for the same data root refuses with exit 3 while the first runs (504.679874ms)
|
||||
✔ a broker reply that misses the wait breaks the channel: the late reply answers nothing, later requests refuse, the host exits 1 (1447.090939ms)
|
||||
✔ a broker reply with another request's id, or none, breaks the channel and the host exits 1 (1028.567302ms)
|
||||
✔ a broker reply with no request waiting breaks the channel and the host exits 1 (626.653723ms)
|
||||
✔ a notifier that refuses stops the broker and the host refuses with exit 3 (792.780229ms)
|
||||
✔ a notifier that refuses after the broker died still refuses with exit 3, without a send to the dead broker (827.588805ms)
|
||||
✔ a notifier that dies before it replies, after the broker died, still refuses, without a send to the dead broker (448.928319ms)
|
||||
✔ a close send that fails with EPIPE after the notifier refuses still gives the notifier's refusal, exit 3 (959.559717ms)
|
||||
✔ a close send that fails with EPIPE after the notifier dies unanswered still gives the notifier's error (374.582964ms)
|
||||
✔ close() whose stop and close sends fail with EPIPE still finishes, with exit 1 (1041.924964ms)
|
||||
✔ watchChildren reports a child that died before it was called, and one that dies later (272.326327ms)
|
||||
✔ bus stop refuses to signal a live pid that is not a bus host (212.075795ms)
|
||||
✔ bus start refuses with exit 3 and the code when the broker refuses to boot; bus status names the lock (1877.931965ms)
|
||||
✔ bus start refuses with exit 3 without a notifier config (410.231009ms)
|
||||
✔ bus start runs until bus stop; status reports it while it runs (2751.420173ms)
|
||||
✔ bus-service.sh renders the unit and installs it into a given directory (271.391306ms)
|
||||
✔ bus-service.sh pins the claude binary, refuses one the unit can't carry, and renders without one (286.635166ms)
|
||||
✔ bus-service.sh refuses a directory pin and keeps a symlink default unresolved (124.634862ms)
|
||||
✔ bus start --pm: the PM runs under its own PID namespace, registered, with a manifest (2202.417372ms)
|
||||
✔ the PM launches a coder through its launch tool; the coder answers; refusals name their code (2405.387947ms)
|
||||
✔ a runner that stops at once ends its launch with the runner's reason (888.819534ms)
|
||||
✔ a host that died hard leaves its sessions to the next host, which kills them and ends their runs so the role can be launched again (2968.426852ms)
|
||||
✔ a host that died hard leaves its sessions to the next host, which finds one already exited (23) and ends their runs so the role can be launched again (5984.400948ms)
|
||||
✔ a malformed sessions.json refuses the host start with exit 3 and stays as it was (297.688892ms)
|
||||
✔ an over-long launch request is refused at once, not at the 10 s idle timeout (524.428233ms)
|
||||
✔ a launch client that never closes its side doesn't hold the host's close (483.523483ms)
|
||||
✔ a runner that ignores SIGTERM is killed when the host closes (1622.655595ms)
|
||||
✔ claudeVersion asks MOSAIC_CLAUDE_BIN when set, else claude on PATH (36.065044ms)
|
||||
✔ zoned uses the IANA zone across DST (73.655648ms)
|
||||
✔ each open blocking decision is DM'd once, across polls and a restart; non-blocking ones are not (124.612806ms)
|
||||
✔ two blocking decisions get two DMs with different nonces (164.020027ms)
|
||||
✔ the digest nonce differs per business and per day and fits Discord's 25 characters (1.77021ms)
|
||||
✔ a failed DM is journaled, backs off, and is retried until it lands (107.037673ms)
|
||||
✔ five definite refusals stop a DM: one gave-up line, one log line, and a restart keeps the count (176.700103ms)
|
||||
✔ 429s, 5xx-style unknowns and refusals without a status never count toward the limit (163.738237ms)
|
||||
✔ a crash between the fifth refusal and its gave-up line: the next poll appends it and sends nothing (266.590884ms)
|
||||
✔ polled every POLL_MS against a permanent 403, a DM is sent at 0, 30, 60, 90 and 120 min and gives up only then (606.701328ms)
|
||||
✔ a restart after the second refusal does not send before that refusal's 30 min are up (306.405387ms)
|
||||
✔ the digest goes at 08:00 Chicago once a day, with blocking ones marked as DM'd (93.252035ms)
|
||||
✔ a late start with no digest for the day sends one at once; an empty inbox gets one line (62.239756ms)
|
||||
✔ an inbox read failure is logged and the next poll retries (5.72164ms)
|
||||
✔ no Discord id reaches the journal or the log (67.389748ms)
|
||||
✔ the journal: a torn tail is copied out and truncated, so an append after it reopens cleanly (8.573637ms)
|
||||
✔ the journal: a crash between the copy and the truncate leaves a tail the next open repairs (43.865237ms)
|
||||
✔ the journal: a whole file that is one torn line truncates to empty (28.752236ms)
|
||||
✔ the journal: a malformed complete line refuses and leaves the file and any torn tail alone (5.797293ms)
|
||||
✔ the journal: a loose file mode, a loose directory or a symlinked journal refuses (2.434898ms)
|
||||
✔ the journal: a line with a wrong type refuses with exit 3 and names the field (21.052982ms)
|
||||
✔ the journal: a symlinked directory refuses and says it is a link (1.121274ms)
|
||||
✔ the journal: a dangling directory link, a parent that is a file and a journal that is a directory each refuse with exit 3 (1.177906ms)
|
||||
✔ the journal: an append after the file was swapped for a symlink refuses and writes nothing through it (0.937541ms)
|
||||
✔ the journal: a directory it cannot write or create refuses with exit 3 and names the path (1.23765ms)
|
||||
✔ digest content stays within Discord's 2000 characters (6.139295ms)
|
||||
✔ runLoop never overlaps ticks and stops after the one in flight (124.934955ms)
|
||||
task.close {} answered: invalid-request; fake saw 18 requests, first GET /info 200, GET /projects/1 200, GET /projects/1/views 200
|
||||
task.close on a missing task answered: task-not-found; it made GET /tasks/999 404
|
||||
✔ bootConfig trackers reach the S3 adapter in the real broker child, which goes ready against a fake Vikunja (1711.354145ms)
|
||||
✔ the transport writes {business, verb, args} to the child and reads its JSON (537.477436ms)
|
||||
✔ a bus code on stderr becomes the exit code; garbage and timeouts are outcome problems (3013.392452ms)
|
||||
✔ busExit and refuseInsideAgent (3.705285ms)
|
||||
✔ talk sends a REQUEST, prints and reads everything that arrives, and stops at the reply (325.919449ms)
|
||||
✔ talk --wait 0 only sends; no reply within --wait exits 1 and says where it will show (1130.145307ms)
|
||||
✔ talk, stop and launches off/on refuse inside an agent run; bad arguments are usage errors (127.353818ms)
|
||||
✔ launches off and on go to the broker and change the business's launch state (89.503237ms)
|
||||
✔ launches list reads sessions.json and marks a stale entry; stop reports it and refuses a non-runner (124.261264ms)
|
||||
ℹ tests 113
|
||||
ℹ suites 0
|
||||
ℹ pass 113
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 49813.574688
|
||||
@@ -0,0 +1 @@
|
||||
2026-10-11T23:03:44Z
|
||||
@@ -0,0 +1,66 @@
|
||||
✔ sessionModel: agent vars win, then the system's execution settings (220.571303ms)
|
||||
✔ a pi bundle: prompt, policy, tools and manifest, 0600 in a 0700 directory (38.138242ms)
|
||||
✔ a claude-code bundle adds the wrapped gate hook and the MCP config (14.587866ms)
|
||||
✔ a bundle is written once: an existing file refuses (11.013312ms)
|
||||
✔ a path with a single quote can't go into the hook command (7.472368ms)
|
||||
✔ allow exits 0, a deny exits 2 with the reason on stderr (1091.107942ms)
|
||||
✔ a missing or wrong policy, or a bad event, exits 2 (370.064293ms)
|
||||
✔ the bundle's wrapped command: a missing gate or node still blocks (1524.139979ms)
|
||||
✔ claude: typed tools through MCP, the hook blocks, builtins outside --tools don't exist (5239.695758ms)
|
||||
✔ claude: the hook alone blocks a path outside the workspace (3505.114261ms)
|
||||
✔ claude: a second turn resumes the first turn's session (7090.980712ms)
|
||||
✔ claude adapter: --restricted is always passed (62.080941ms)
|
||||
✔ claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable (346.323108ms)
|
||||
✔ claude adapter: a directory pin exits 2 before it runs; a pin with a space runs (158.882322ms)
|
||||
✔ claude: CLAUDE.md files and auto-memory don't reach the model; without --restricted they do (5097.218294ms)
|
||||
✔ claude: a missing hook or MCP file refuses before claude starts (199.143816ms)
|
||||
✔ pi: policy tools and typed tools pass, anything else is blocked (16.151597ms)
|
||||
✔ claude: builtins map from pi names, typed tools need the mcp prefix (10.439093ms)
|
||||
✔ file tool paths must resolve inside the workspace (5.524028ms)
|
||||
✔ pi's own path normalisation can't be used to step out (11.975103ms)
|
||||
✔ a symlink inside the workspace that points out is outside (24.472476ms)
|
||||
✔ a dangling symlink is refused at any depth, in both harnesses (36.341784ms)
|
||||
✔ read is checked under every spelling pi's read would open, in both harnesses (134.447906ms)
|
||||
✔ other spellings cover directories, dangling links and pi's cwd (23.176456ms)
|
||||
✔ a relative path climbs from the workspace's real path, in both harnesses (41.832941ms)
|
||||
✔ claude path fields per tool (1.844369ms)
|
||||
✔ glob patterns stay inside the workspace (4.749344ms)
|
||||
✔ a path that can't be checked is blocked (1.197203ms)
|
||||
✔ initialize, ping and tools/list (512.567722ms)
|
||||
✔ tools/call goes through the tool socket; a refusal is an isError result (290.30019ms)
|
||||
✔ unknown tools and methods are JSON-RPC errors and never reach the socket (191.976474ms)
|
||||
✔ a missing argument is a usage error (186.292495ms)
|
||||
✔ pi: typed tools reach the socket, the gate blocks, agent_end writes the marker (2292.59352ms)
|
||||
✔ pi: a write through a dangling symlink is blocked, and nothing appears outside (1843.612383ms)
|
||||
✔ pi: a read is refused when pi would open another spelling outside (1603.970397ms)
|
||||
✔ pi: a relative path climbs from the real path of a workspace behind a symlink (2127.541578ms)
|
||||
✔ pi: a relative path climbs from the real path of a dataRoot behind a symlink (2310.586378ms)
|
||||
✔ pi: a missing extension refuses before any model call (49.689892ms)
|
||||
✔ pi: an extension without its configuration fails pi's start (1448.161485ms)
|
||||
✔ founderCheck: founder variables, then a needed service without a usable token (13.603367ms)
|
||||
✔ turnRequest names the sender, class, reply and decision (0.519624ms)
|
||||
✔ a message becomes a turn, the answer goes back as a RESULT, SIGTERM releases and exits 0 (984.434421ms)
|
||||
✔ a SIGTERM before the claim stops the runner with exit 0 and no claim (252.636326ms)
|
||||
✔ typed tools carry the runner's capability; launch goes to the host's launch socket (1356.107063ms)
|
||||
✔ a RESULT gets no automatic reply; failed turns reply with the reason (2195.652619ms)
|
||||
✔ SIGTERM during a turn kills the turn's process group and still exits 0 (462.989047ms)
|
||||
✔ founder credentials stop before the claim (20) (589.454895ms)
|
||||
✔ a refused claim exits 21; an ended run's capability exits 22 (803.196677ms)
|
||||
✔ the launch ending under a running session exits 22 (386.836143ms)
|
||||
✔ a broker that stays unreachable exits 23 after brokerRetries polls (435.829225ms)
|
||||
✔ a broker that is down at the claim exits 23, not 21 (675.200131ms)
|
||||
✔ no capability, or a malformed one, on stdin exits 2 (999.096123ms)
|
||||
✔ a missing or malformed policy exits 2 before the claim (496.057533ms)
|
||||
✔ the PM gets launch, its task verbs and the reads (34.817657ms)
|
||||
✔ a coder gets no launch, no resolve_decision, and no task tools without a tracker (28.313991ms)
|
||||
✔ launch only when the business's launch block names the instance as launcher (12.055749ms)
|
||||
✔ an action outside the instance's authority has no tool (16.601564ms)
|
||||
✔ callTool: one JSON line out, the result back, a refusal rejects (57.019666ms)
|
||||
ℹ tests 58
|
||||
ℹ suites 0
|
||||
ℹ pass 58
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 22008.973676
|
||||
@@ -0,0 +1 @@
|
||||
2026-10-11T22:58:58Z
|
||||
@@ -0,0 +1,11 @@
|
||||
cli rc=0 ℹ pass 113 ℹ fail 0 ℹ skipped 0
|
||||
harness rc=0 ℹ pass 58 ℹ fail 0 ℹ skipped 0
|
||||
test-auth rc=0 selftest: 15 passed, 0 failed
|
||||
test-conductor rc=0 selftest: 17 passed, 0 failed
|
||||
test-config rc=0 selftest: 24 passed, 0 failed
|
||||
test-discord rc=0 discord suite: 66 passed, 0 failed
|
||||
test-extension-package rc=0 extension package selftest: 18 passed, 0 failed
|
||||
test-foundation rc=0 selftest: 44 passed, 0 failed
|
||||
test-queue rc=0 queue suite: 27 passed, 0 failed
|
||||
test-release rc=0 selftest: 14 passed, 0 failed
|
||||
test-task rc=0 selftest: 98 passed, 0 failed
|
||||
@@ -0,0 +1,17 @@
|
||||
OK status with missing harness credential exits 3 and still lists accounts
|
||||
OK status reports harness credential (read-only) + mosaic accounts
|
||||
OK api key material never reaches output
|
||||
OK oauth token material never reaches output
|
||||
OK unparseable credential file exits 2
|
||||
OK symlinked credential file exits 4
|
||||
OK env-side credential names reported
|
||||
OK env var values never reach output
|
||||
OK accounts without an accounts dir reports none and creates nothing
|
||||
OK accounts lists files and marks the active one
|
||||
OK loose account perms flagged in listing
|
||||
OK agent --auth with missing account file refuses (exit 4)
|
||||
OK agent --auth with non-0600 account file refuses
|
||||
OK agent --auth with invalid account name refuses
|
||||
OK auth.sh without valid config refuses
|
||||
|
||||
selftest: 15 passed, 0 failed
|
||||
@@ -0,0 +1,23 @@
|
||||
On branch refactor
|
||||
Your branch is up to date with 'origin/refactor'.
|
||||
|
||||
nothing to commit, working tree clean
|
||||
OK dry-run: allowed change, exit 0, nothing committed (exit 0)
|
||||
OK dry-run committed nothing
|
||||
OK apply: allowed change exits 0 (exit 0)
|
||||
OK apply: attribution in commit subject
|
||||
OK apply: target tree clean after commit
|
||||
OK disallowed path refused (exit 1)
|
||||
OK disallowed path: target untouched
|
||||
OK syntax gate refused broken .mjs (exit 1)
|
||||
OK syntax gate: target untouched
|
||||
OK suite failure refused (exit 1)
|
||||
OK suite failure: target reverted to clean
|
||||
OK disabled policy refused (exit 2)
|
||||
OK disabled policy: target untouched
|
||||
OK failed run refused (exit 1)
|
||||
OK failed run: target untouched
|
||||
OK missing run exits 4 (exit 4)
|
||||
OK invalid policy exits 2 (exit 2)
|
||||
|
||||
selftest: 17 passed, 0 failed
|
||||
@@ -0,0 +1,26 @@
|
||||
OK absent adapter defaults to pi
|
||||
OK adapter mock validates (exit 0)
|
||||
OK unsupported adapter exits 2 (exit 2)
|
||||
OK env exports adapter
|
||||
OK bootstrap creates default when absent (exit 0)
|
||||
OK bootstrap wrote config file
|
||||
OK bootstrap is idempotent on existing config (exit 0)
|
||||
OK bootstrap did not rewrite existing config
|
||||
OK validate missing config exits 3 (exit 3)
|
||||
OK malformed JSON exits 2 (exit 2)
|
||||
OK unsupported configVersion exits 2 (exit 2)
|
||||
OK unknown top-level key exits 2 (exit 2)
|
||||
OK unknown execution key exits 2 (exit 2)
|
||||
OK unsupported backend exits 2 (exit 2)
|
||||
OK unsupported environment exits 2 (exit 2)
|
||||
OK relative dataRoot exits 2 (exit 2)
|
||||
OK non-canonical dataRoot exits 2 (exit 2)
|
||||
OK filesystem root dataRoot exits 2 (exit 2)
|
||||
OK home directory dataRoot exits 2 (exit 2)
|
||||
OK dataRoot containing config dir exits 2 (exit 2)
|
||||
OK control character in provider exits 2 (exit 2)
|
||||
OK symlinked config file exits 2 (exit 2)
|
||||
OK env exports resolve correctly
|
||||
OK failed validation modified nothing
|
||||
|
||||
selftest: 24 passed, 0 failed
|
||||
@@ -0,0 +1,70 @@
|
||||
toolchain: node v26.8.1
|
||||
|
||||
OK syntax: packages/discord/src/approvals.mjs
|
||||
OK syntax: packages/discord/src/authorize.mjs
|
||||
OK syntax: packages/discord/src/binding.mjs
|
||||
OK syntax: packages/discord/src/cli.mjs
|
||||
OK syntax: packages/discord/src/connector.mjs
|
||||
OK syntax: packages/discord/src/context.mjs
|
||||
OK syntax: packages/discord/src/engine-pi.mjs
|
||||
OK syntax: packages/discord/src/errors.mjs
|
||||
OK syntax: packages/discord/src/gateway.mjs
|
||||
OK syntax: packages/discord/src/git.mjs
|
||||
OK syntax: packages/discord/src/journal.mjs
|
||||
OK syntax: packages/discord/src/notify.mjs
|
||||
OK syntax: packages/discord/src/rest.mjs
|
||||
OK syntax: packages/discord/src/setspark.mjs
|
||||
OK syntax: packages/discord/src/tools.mjs
|
||||
OK syntax: packages/discord/src/web.mjs
|
||||
OK syntax: packages/discord/bin/git-credential.mjs
|
||||
OK syntax: packages/discord/extension/tools.mjs
|
||||
OK syntax: packages/discord/tests/approvals.test.mjs
|
||||
OK syntax: packages/discord/tests/authorize.test.mjs
|
||||
OK syntax: packages/discord/tests/binding.test.mjs
|
||||
OK syntax: packages/discord/tests/connector.test.mjs
|
||||
OK syntax: packages/discord/tests/context.test.mjs
|
||||
OK syntax: packages/discord/tests/engine.test.mjs
|
||||
OK syntax: packages/discord/tests/fake-pi.mjs
|
||||
OK syntax: packages/discord/tests/gateway.test.mjs
|
||||
OK syntax: packages/discord/tests/git.test.mjs
|
||||
OK syntax: packages/discord/tests/helpers.mjs
|
||||
OK syntax: packages/discord/tests/journal.test.mjs
|
||||
OK syntax: packages/discord/tests/notify.test.mjs
|
||||
OK syntax: packages/discord/tests/recover.test.mjs
|
||||
OK syntax: packages/discord/tests/rest.test.mjs
|
||||
OK syntax: packages/discord/tests/setspark.test.mjs
|
||||
OK syntax: packages/discord/tests/tools.test.mjs
|
||||
OK syntax: packages/discord/tests/web.test.mjs
|
||||
OK syntax: packages/discord/fixtures/claim-worker.mjs
|
||||
OK syntax: packages/discord/fixtures/legacy-owner-worker.mjs
|
||||
OK syntax: scripts/discord.sh
|
||||
OK syntax: scripts/discord-service.sh
|
||||
OK packages/discord declares no dependencies
|
||||
OK no bot-token-shaped string in packages/discord
|
||||
OK fixture binding uses placeholder ids only
|
||||
OK fixture binding validates
|
||||
OK real pi with the extension exposes exactly list_dir, read_file, search and no built-in tool
|
||||
OK real pi with a writable root exposes exactly the three reads plus write_file and edit_file, and writes nothing at start
|
||||
OK real pi with a web key exposes the three reads plus web_fetch and web_search, and no write tool without a writable root
|
||||
OK real pi with a git root exposes the reads, writes and the four git verbs, commits nothing at start, and never shows the token
|
||||
OK real pi with protocol vault adds reserve_id to the git verbs
|
||||
OK real pi with a setspark key exposes the reads and the eight record verbs, no counters, and never shows the key
|
||||
OK real pi refuses a git key on a read-only root (fail closed)
|
||||
OK real pi with the pilot flags (--no-tools) exposes no tool at all
|
||||
OK real pi exits non-zero without MOSAIC_DISCORD_TOOLS: no session, no tools (fail closed)
|
||||
OK a failing nested test fails the run under a parent runner's NODE_TEST_CONTEXT
|
||||
OK node --test packages/discord/tests/ (ℹ pass 178)
|
||||
OK scripts/discord.sh --help exits 0
|
||||
OK scripts/discord.sh check without a binding exits 4
|
||||
OK scripts/discord.sh recover without a binding exits 4
|
||||
OK scripts/discord.sh reload without a binding exits 4
|
||||
OK scripts/discord-service.sh without a command exits 4
|
||||
OK service unit renders with the repository path, a supervised run as the main process, exit 3 never retried, and reload as SIGHUP
|
||||
OK service install writes the rendered unit (0644) and leaves no temp file
|
||||
OK service install a second time reports unchanged
|
||||
OK systemd-analyze verify accepts the rendered unit
|
||||
OK service uninstall removes the unit file
|
||||
OK service install with an unknown flag exits 4
|
||||
OK service install with USER unset finishes and names the account for lingering
|
||||
|
||||
discord suite: 66 passed, 0 failed
|
||||
@@ -0,0 +1,21 @@
|
||||
OK initial ordinary-file install
|
||||
OK installed tree matches canonical source
|
||||
OK installed tree has no symlinks
|
||||
OK check detects installation drift
|
||||
OK sync refuses to overwrite installation drift
|
||||
OK check detects an extra destination file
|
||||
OK check detects an extra destination directory
|
||||
OK check rejects a destination symlink
|
||||
OK sync accepts a canonical source update
|
||||
OK updated installation matches canonical source
|
||||
scripts/test-extension-package.sh: line 14: 3959563 Killed "$@" > /dev/null 2>&1
|
||||
OK forced interruption kills the replacing process
|
||||
OK next invocation recovers old consistent installation
|
||||
OK interrupted replacement rolled back
|
||||
OK sync succeeds after interruption recovery
|
||||
OK unlocked stale lock file does not block
|
||||
OK active lock refuses a concurrent sync
|
||||
OK source symlink fails closed
|
||||
OK nested second entrypoint fails closed
|
||||
|
||||
extension package selftest: 18 passed, 0 failed
|
||||
@@ -0,0 +1,53 @@
|
||||
toolchain: node v26.8.1, python 3.12.8, jsonschema 4.26.0
|
||||
|
||||
OK syntax: scripts/foundation-inspect.mjs
|
||||
OK syntax: scripts/foundation/strict-json.mjs
|
||||
OK syntax: scripts/foundation/canonical.mjs
|
||||
OK syntax: scripts/foundation/resolve.mjs
|
||||
OK syntax: scripts/foundation/validate-record.mjs
|
||||
OK syntax: scripts/foundation/fixtures/build-fixtures.mjs
|
||||
OK syntax: scripts/foundation/canonical.test.mjs
|
||||
OK syntax: scripts/foundation/cli.test.mjs
|
||||
OK syntax: scripts/foundation/fixtures.test.mjs
|
||||
OK syntax: scripts/foundation/resolve.test.mjs
|
||||
OK syntax: scripts/foundation/strict-json.test.mjs
|
||||
OK syntax: scripts/foundation/verify-schema.py (ast only; no bytecode written)
|
||||
OK fixture generator runs
|
||||
OK checked-in fixtures/bundles equal a fresh generation
|
||||
OK checked-in fixtures/raw equal a fresh generation
|
||||
OK checked-in fixtures/index.json equal a fresh generation
|
||||
OK checked-in demo bundles equal a fresh generation
|
||||
OK a failing nested test fails the run under a parent runner's NODE_TEST_CONTEXT
|
||||
OK node --test scripts/foundation/ (ℹ pass 80)
|
||||
OK differential schema oracle: PASS: differential schema oracle (finite corpus; compatibility evidence, not equivalence proof)
|
||||
platform witness: strftime('%Y') for year 999 -> '999' (pinned checker refuses years 0001..0999)
|
||||
node v26.8.1; corpus 1568 records (38 pinned fixtures, 478 unique bundle records, 1052 typeCase/mutation/lexical cases)
|
||||
schema column: agree-valid 540, agree-invalid 991, DISAGREEMENTS 0; strict-only (parser-bound) cases: 27; unsupported-kind records not schema-assessed by the inspector: 10
|
||||
profile column (schema-valid records only): profile-valid 510, profile-invalid 30
|
||||
profile refusals asserted: 30 schema-agreed-valid records refused only by the strict typed-string profile (rule profile-pattern-mismatch), 12 declared by name; 73 named probes verified against declared schema/profile columns
|
||||
OK oracle: zero schema-column disagreements with the pinned checker
|
||||
OK oracle: strict-only profile refusals are counted and asserted
|
||||
OK demo: permitted read preview exits 0 (exit 0)
|
||||
OK demo: permitted file.change preview exits 0 (exit 0)
|
||||
OK demo: assignment.change proposal is unresolved (exit 3) (exit 3)
|
||||
OK demo: revoked registration is refused (exit 3) (exit 3)
|
||||
OK demo: message is not authority (exit 3) (exit 3)
|
||||
OK usage: no arguments exits 2 (exit 2)
|
||||
OK io: missing file exits 4 (exit 4)
|
||||
OK io: directory exits 4 (exit 4)
|
||||
OK io: symlink exits 4 (O_NOFOLLOW) (exit 4)
|
||||
OK bound: oversize fixture exits 2 (exit 2)
|
||||
OK profile: one final LF in a typed selection id is refused before admission (exit 2) (exit 2)
|
||||
OK profile: two final LFs fail the schema pattern itself (exit 2) (exit 2)
|
||||
OK profile: escaped newlines in free-form text stay allowed (exit 0) (exit 0)
|
||||
OK profile refusal is invalid-request/profile-pattern-mismatch with selection and operation withheld, value not echoed
|
||||
OK text output starts with the disclaimer
|
||||
OK json output is valid JSON with result allowed and exactly the charter §7 fields
|
||||
OK json golden matches byte-for-byte
|
||||
OK sandboxed bundle run (env -i, PATH=/nonexistent) produced the unresolved proposal
|
||||
OK sandbox inventory (path/type/size/mode/uid/gid/inode/mtime/sha256) unchanged by runs
|
||||
OK canary never printed (bundle run and credential-file run)
|
||||
OK a non-bundle JSON file is refused at the shape gate, not read into output
|
||||
OK no field of the non-bundle file is echoed
|
||||
|
||||
selftest: 44 passed, 0 failed
|
||||
@@ -0,0 +1,35 @@
|
||||
toolchain: node v26.8.1, git version 2.55.0
|
||||
|
||||
OK syntax: packages/queue/src/cli.mjs
|
||||
OK syntax: packages/queue/src/errors.mjs
|
||||
OK syntax: packages/queue/src/io.mjs
|
||||
OK syntax: packages/queue/src/lock.mjs
|
||||
OK syntax: packages/queue/src/queue.mjs
|
||||
OK syntax: packages/queue/src/review.mjs
|
||||
OK syntax: packages/queue/src/store.mjs
|
||||
OK syntax: packages/queue/tests/commit.test.mjs
|
||||
OK syntax: packages/queue/tests/data.test.mjs
|
||||
OK syntax: packages/queue/tests/dispatch.test.mjs
|
||||
OK syntax: packages/queue/tests/helpers.mjs
|
||||
OK syntax: packages/queue/tests/lock.test.mjs
|
||||
OK syntax: packages/queue/tests/migration.test.mjs
|
||||
OK syntax: packages/queue/tests/review.test.mjs
|
||||
OK syntax: packages/queue/tests/store.test.mjs
|
||||
OK syntax: packages/queue/tests/write.test.mjs
|
||||
OK syntax: packages/queue/tests/fixtures/fake-gitea.mjs
|
||||
OK syntax: packages/queue/tests/fixtures/kill-at.mjs
|
||||
OK syntax: packages/queue/tests/fixtures/lock-child.mjs
|
||||
OK syntax: packages/queue/tests/fixtures/mosaic-pre-a2.sh
|
||||
OK syntax: scripts/queue-commit.sh
|
||||
OK syntax: scripts/git-hooks/pre-commit
|
||||
OK syntax: scripts/mosaic
|
||||
OK queue-commit.sh, the guard and scripts/mosaic are executable
|
||||
OK packages/queue declares no dependencies
|
||||
ℹ tests 150
|
||||
ℹ pass 150
|
||||
ℹ fail 0
|
||||
OK node --test packages/queue/tests/
|
||||
OK scripts/mosaic queue help
|
||||
skip queue verify and render --check: this checkout (/mnt/storage/scratch/rocko-r72) is not the queue's canonical root (/mnt/storage/src/mosaic-stack)
|
||||
|
||||
queue suite: 27 passed, 0 failed
|
||||
@@ -0,0 +1,16 @@
|
||||
OK valid RELEASE resolves (exit 0)
|
||||
OK invalid RELEASE exits 1 (exit 1)
|
||||
OK missing RELEASE exits 1 (exit 1)
|
||||
OK valid RELEASE leaves image tag consistent with version
|
||||
OK status safe on empty state (exit 0)
|
||||
OK status created no pointer
|
||||
OK fault-injected activation refuses (exit 1)
|
||||
OK refused activation wrote no pointer
|
||||
OK refusal logged exactly once with valid fields
|
||||
OK healthy activation succeeds (exit 0)
|
||||
OK pointer written with valid fields
|
||||
OK repeat activation succeeds (log grows) (exit 0)
|
||||
OK log is append-only across activations
|
||||
OK rollback without previous refuses (exit 1)
|
||||
|
||||
selftest: 14 passed, 0 failed
|
||||
@@ -0,0 +1,101 @@
|
||||
OK valid task validates (exit 0)
|
||||
OK unknown task key exits 2 (exit 2)
|
||||
OK unsupported taskVersion exits 2 (exit 2)
|
||||
OK invalid task id exits 2 (exit 2)
|
||||
OK empty prompt exits 2 (exit 2)
|
||||
OK NUL in expectExact exits 2 (exit 2)
|
||||
OK out-of-range timeout exits 2 (exit 2)
|
||||
OK missing mission file exits 4 (exit 4)
|
||||
OK task with valid mission validates (exit 0)
|
||||
OK invalid mission exits 2 (exit 2)
|
||||
OK validate missing task exits 4 (exit 4)
|
||||
OK validation does not modify the task file
|
||||
OK prune dry-run exits 0 (exit 0)
|
||||
OK dry-run deleted nothing
|
||||
OK prune --keep=2 --yes removes oldest (exit 0)
|
||||
OK kept exactly 2 newest runs
|
||||
OK newest run kept, oldest pruned
|
||||
OK append-only receipt written (3 entries)
|
||||
OK sessions/workspaces untouched by prune
|
||||
OK prune with invalid keep exits 4 (exit 4)
|
||||
OK mock adapter: gate passes on matching mock response (exit 0)
|
||||
OK mock adapter: expect-mismatch recorded (exit 1)
|
||||
OK mismatch reason recorded
|
||||
OK unknown adapter fails closed (exit 1)
|
||||
OK mission task runs via mock adapter (exit 0)
|
||||
OK mission section injected into generated prompt
|
||||
OK retry of mission run succeeds (exit 0)
|
||||
OK retriedFrom lineage recorded
|
||||
OK mission section present after retry (relative path resolved)
|
||||
OK retry of missing run exits 4 (exit 4)
|
||||
OK skill install bundled ms-tools (exit 0)
|
||||
OK installed to skills-available
|
||||
OK double install refuses (exit 1)
|
||||
OK activate enables skill (exit 0)
|
||||
OK enabled dir populated
|
||||
OK uninstall while enabled refuses (exit 1)
|
||||
OK deactivate moves back to available (exit 0)
|
||||
OK uninstall removes from available (exit 0)
|
||||
OK seat with enabled skill launches
|
||||
OK skill path delivered to adapter
|
||||
OK shipped researcher contract resolves (ceiling + network)
|
||||
OK resolve-role refuses a non-role document (conductor policy) (exit 2)
|
||||
OK resolve-role refuses name/filename mismatch (exit 2)
|
||||
OK resolve-role refuses unknown network declaration (exit 2)
|
||||
OK resolve-role refuses duplicate role tool (exit 2)
|
||||
OK resolve-role refuses unsupported tool (exit 2)
|
||||
OK resolve-role refuses missing contract file (exit 4)
|
||||
OK version 1 role prints no contract line
|
||||
OK shipped version 2 roles resolve with their contracts (pm, cto, coder, reviewer)
|
||||
OK resolve-role accepts a minimal version 2 role (exit 0)
|
||||
OK resolve-role refuses an action outside the vocabulary (exit 2)
|
||||
OK resolve-role refuses a gated-only action in a role file (exit 2)
|
||||
OK resolve-role refuses a Vikunja verb no role may hold (exit 2)
|
||||
OK resolve-role refuses a version 2 role whose contract is missing (exit 2)
|
||||
OK resolve-role refuses a contract that is a symbolic link (exit 2)
|
||||
OK seat launches under role ceiling
|
||||
OK role ceiling narrows seat tools (read,write,bash -> read,bash)
|
||||
OK narrowing recorded loudly
|
||||
OK missing role contract refuses launch (exit 2)
|
||||
OK missing-contract refusal names the role
|
||||
OK empty ceiling intersection -> tool-free seat
|
||||
OK tool-free outcome recorded loudly
|
||||
OK overridden agents dir without seat definition refuses (exit 4)
|
||||
OK seat-resolution refusal names the seat
|
||||
OK policy: mission only -> mission tools
|
||||
OK policy: task only -> task tools
|
||||
OK policy: both -> intersection (task narrowed)
|
||||
OK policy: empty intersection -> tool-free
|
||||
OK invalid mission capabilities rejected (exit 2)
|
||||
mosaic-task: unsupported mission tool: "sudo" (supported: read, write, edit, bash, grep, find, ls)
|
||||
OK task run with user layer present (exit 0)
|
||||
OK user context dispatched into generated prompt
|
||||
OK workspace+tools task runs via mock (exit 0)
|
||||
OK workspace path + tools delivered to adapter
|
||||
OK persistent workspace created on host
|
||||
OK plain task still runs (no workspace/tools) (exit 0)
|
||||
OK workspace var present but empty when absent
|
||||
OK tools empty when absent
|
||||
OK unknown tool exits 2 (exit 2)
|
||||
OK workspace traversal exits 2 (exit 2)
|
||||
OK live hello task succeeds with exact marker
|
||||
OK result.json written in run dir
|
||||
OK result.json contents are correct
|
||||
OK wrong expectExact fails with exit 1 (reason: expect-mismatch)
|
||||
OK each run gets a distinct run dir (no clobber)
|
||||
OK list shows both runs
|
||||
OK fork base: teach succeeds (exit 0)
|
||||
OK fork child recalls ancestor context (exit 0)
|
||||
OK forked child recalled ancestor code word
|
||||
OK ancestor session untouched by fork
|
||||
OK child session dir has its own branch file
|
||||
OK onboard without name exits 4 (non-interactive) (exit 4)
|
||||
OK onboard --name renders profile (exit 0)
|
||||
OK profile written
|
||||
OK canon structure: required filled, optional placeholdered
|
||||
OK canon sections present
|
||||
OK user recall run succeeds
|
||||
OK recalled user name (response: Jason)
|
||||
OK no agent identity on headless run
|
||||
|
||||
selftest: 98 passed, 0 failed
|
||||
@@ -0,0 +1,7 @@
|
||||
baseline: pass
|
||||
bs-no-f: SURVIVED
|
||||
bs-x-only: SURVIVED
|
||||
ad-no-f: SURVIVED
|
||||
ad-x-only: SURVIVED
|
||||
bs-resolve-default: SURVIVED
|
||||
ad-unquoted-run: SURVIVED
|
||||
@@ -0,0 +1,13 @@
|
||||
diff --git a/adapters/claude/adapter.sh b/adapters/claude/adapter.sh
|
||||
index a0e04dae..40a43ddb 100644
|
||||
--- a/adapters/claude/adapter.sh
|
||||
+++ b/adapters/claude/adapter.sh
|
||||
@@ -33,7 +33,7 @@ if [ -n "${MOSAIC_CLAUDE_BIN:-}" ]; then
|
||||
/*) ;;
|
||||
*) echo "claude adapter: MOSAIC_CLAUDE_BIN must be an absolute path: $MOSAIC_CLAUDE_BIN" >&2; exit 2 ;;
|
||||
esac
|
||||
- [ -f "$MOSAIC_CLAUDE_BIN" ] && [ -x "$MOSAIC_CLAUDE_BIN" ] || { echo "claude adapter: MOSAIC_CLAUDE_BIN is not an executable file: $MOSAIC_CLAUDE_BIN" >&2; exit 2; }
|
||||
+ [ -e "$MOSAIC_CLAUDE_BIN" ] && [ -x "$MOSAIC_CLAUDE_BIN" ] || { echo "claude adapter: MOSAIC_CLAUDE_BIN is not an executable file: $MOSAIC_CLAUDE_BIN" >&2; exit 2; }
|
||||
CLAUDE=$MOSAIC_CLAUDE_BIN
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
✔ bus-service.sh pins the claude binary, refuses one the unit can't carry, and renders without one (776.728613ms)
|
||||
✔ claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable (119.517434ms)
|
||||
ℹ tests 2
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1066.686453
|
||||
@@ -0,0 +1,13 @@
|
||||
diff --git a/adapters/claude/adapter.sh b/adapters/claude/adapter.sh
|
||||
index a0e04dae..700291db 100644
|
||||
--- a/adapters/claude/adapter.sh
|
||||
+++ b/adapters/claude/adapter.sh
|
||||
@@ -73,7 +73,7 @@ fi
|
||||
ALLOWED=mcp__mosaic
|
||||
[ -z "${MOSAIC_TOOLS:-}" ] || ALLOWED="$MOSAIC_TOOLS,mcp__mosaic"
|
||||
PROMPT_CONTENT="$(cat "$MOSAIC_SYSTEM_PROMPT_FILE")"
|
||||
-"$CLAUDE" -p "$MOSAIC_REQUEST" \
|
||||
+$CLAUDE -p "$MOSAIC_REQUEST" \
|
||||
--output-format text \
|
||||
--system-prompt "$PROMPT_CONTENT" \
|
||||
--model "$MOSAIC_MODEL" \
|
||||
@@ -0,0 +1,10 @@
|
||||
✔ bus-service.sh pins the claude binary, refuses one the unit can't carry, and renders without one (966.484972ms)
|
||||
✔ claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable (310.409084ms)
|
||||
ℹ tests 2
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1429.026231
|
||||
@@ -0,0 +1,13 @@
|
||||
diff --git a/adapters/claude/adapter.sh b/adapters/claude/adapter.sh
|
||||
index a0e04dae..1b10f061 100644
|
||||
--- a/adapters/claude/adapter.sh
|
||||
+++ b/adapters/claude/adapter.sh
|
||||
@@ -33,7 +33,7 @@ if [ -n "${MOSAIC_CLAUDE_BIN:-}" ]; then
|
||||
/*) ;;
|
||||
*) echo "claude adapter: MOSAIC_CLAUDE_BIN must be an absolute path: $MOSAIC_CLAUDE_BIN" >&2; exit 2 ;;
|
||||
esac
|
||||
- [ -f "$MOSAIC_CLAUDE_BIN" ] && [ -x "$MOSAIC_CLAUDE_BIN" ] || { echo "claude adapter: MOSAIC_CLAUDE_BIN is not an executable file: $MOSAIC_CLAUDE_BIN" >&2; exit 2; }
|
||||
+ [ -x "$MOSAIC_CLAUDE_BIN" ] || { echo "claude adapter: MOSAIC_CLAUDE_BIN is not an executable file: $MOSAIC_CLAUDE_BIN" >&2; exit 2; }
|
||||
CLAUDE=$MOSAIC_CLAUDE_BIN
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
✔ bus-service.sh pins the claude binary, refuses one the unit can't carry, and renders without one (1052.739669ms)
|
||||
✔ claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable (316.749733ms)
|
||||
ℹ tests 2
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1389.331619
|
||||
@@ -0,0 +1,10 @@
|
||||
✔ bus-service.sh pins the claude binary, refuses one the unit can't carry, and renders without one (943.671471ms)
|
||||
✔ claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable (230.288669ms)
|
||||
ℹ tests 2
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1178.042132
|
||||
@@ -0,0 +1,13 @@
|
||||
diff --git a/scripts/bus-service.sh b/scripts/bus-service.sh
|
||||
index f641c479..8ec66216 100755
|
||||
--- a/scripts/bus-service.sh
|
||||
+++ b/scripts/bus-service.sh
|
||||
@@ -49,7 +49,7 @@ claude_line() {
|
||||
fi
|
||||
case "$bin" in /*) ;; *) die "claude path must be absolute: $bin" ;; esac
|
||||
case "$bin" in *[!A-Za-z0-9/._+-]*) die "claude path contains a character the unit cannot carry: $bin" ;; esac
|
||||
- [ -f "$bin" ] && [ -x "$bin" ] || die "claude path is not an executable file: $bin"
|
||||
+ [ -e "$bin" ] && [ -x "$bin" ] || die "claude path is not an executable file: $bin"
|
||||
echo "Environment=MOSAIC_CLAUDE_BIN=$bin"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
✔ bus-service.sh pins the claude binary, refuses one the unit can't carry, and renders without one (452.698199ms)
|
||||
✔ claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable (109.619729ms)
|
||||
ℹ tests 2
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 767.577742
|
||||
@@ -0,0 +1,13 @@
|
||||
diff --git a/scripts/bus-service.sh b/scripts/bus-service.sh
|
||||
index f641c479..3c9e47d1 100755
|
||||
--- a/scripts/bus-service.sh
|
||||
+++ b/scripts/bus-service.sh
|
||||
@@ -40,7 +40,7 @@ claude_line() {
|
||||
if [ "$CLAUDE_SET" = 1 ]; then
|
||||
bin="$CLAUDE_BIN"
|
||||
else
|
||||
- bin="$(command -v claude || true)"
|
||||
+ bin="$(command -v claude || true)"; [ -z "$bin" ] || bin="$(readlink -f "$bin")"
|
||||
if [ -z "$bin" ]; then
|
||||
echo "bus-service: no claude on PATH; MOSAIC_CLAUDE_BIN left unset (--claude PATH pins one)" >&2
|
||||
echo "# MOSAIC_CLAUDE_BIN unset: no claude on PATH at install time"
|
||||
@@ -0,0 +1,10 @@
|
||||
✔ bus-service.sh pins the claude binary, refuses one the unit can't carry, and renders without one (1006.856047ms)
|
||||
✔ claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable (376.512437ms)
|
||||
ℹ tests 2
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1415.823841
|
||||
@@ -0,0 +1,13 @@
|
||||
diff --git a/scripts/bus-service.sh b/scripts/bus-service.sh
|
||||
index f641c479..c0f5c4d4 100755
|
||||
--- a/scripts/bus-service.sh
|
||||
+++ b/scripts/bus-service.sh
|
||||
@@ -49,7 +49,7 @@ claude_line() {
|
||||
fi
|
||||
case "$bin" in /*) ;; *) die "claude path must be absolute: $bin" ;; esac
|
||||
case "$bin" in *[!A-Za-z0-9/._+-]*) die "claude path contains a character the unit cannot carry: $bin" ;; esac
|
||||
- [ -f "$bin" ] && [ -x "$bin" ] || die "claude path is not an executable file: $bin"
|
||||
+ [ -x "$bin" ] || die "claude path is not an executable file: $bin"
|
||||
echo "Environment=MOSAIC_CLAUDE_BIN=$bin"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
✔ bus-service.sh pins the claude binary, refuses one the unit can't carry, and renders without one (1051.885653ms)
|
||||
✔ claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable (119.000095ms)
|
||||
ℹ tests 2
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1598.588034
|
||||
@@ -0,0 +1,7 @@
|
||||
baseline: pass
|
||||
bs-no-f: killed (✖ bus-service.sh refuses a directory pin and keeps a symlink default unresolved;✖ failing tests:;)
|
||||
bs-x-only: killed (✖ bus-service.sh refuses a directory pin and keeps a symlink default unresolved;✖ failing tests:;)
|
||||
ad-no-f: killed (✖ claude adapter: a directory pin exits 2 before it runs; a pin with a space runs;✖ failing tests:;)
|
||||
ad-x-only: killed (✖ claude adapter: a directory pin exits 2 before it runs; a pin with a space runs;✖ failing tests:;)
|
||||
bs-resolve-default: killed (✖ bus-service.sh refuses a directory pin and keeps a symlink default unresolved;✖ failing tests:;)
|
||||
ad-unquoted-run: killed (✖ claude adapter: a directory pin exits 2 before it runs; a pin with a space runs;✖ failing tests:;)
|
||||
@@ -0,0 +1,13 @@
|
||||
diff --git a/adapters/claude/adapter.sh b/adapters/claude/adapter.sh
|
||||
index a0e04dae..40a43ddb 100644
|
||||
--- a/adapters/claude/adapter.sh
|
||||
+++ b/adapters/claude/adapter.sh
|
||||
@@ -33,7 +33,7 @@ if [ -n "${MOSAIC_CLAUDE_BIN:-}" ]; then
|
||||
/*) ;;
|
||||
*) echo "claude adapter: MOSAIC_CLAUDE_BIN must be an absolute path: $MOSAIC_CLAUDE_BIN" >&2; exit 2 ;;
|
||||
esac
|
||||
- [ -f "$MOSAIC_CLAUDE_BIN" ] && [ -x "$MOSAIC_CLAUDE_BIN" ] || { echo "claude adapter: MOSAIC_CLAUDE_BIN is not an executable file: $MOSAIC_CLAUDE_BIN" >&2; exit 2; }
|
||||
+ [ -e "$MOSAIC_CLAUDE_BIN" ] && [ -x "$MOSAIC_CLAUDE_BIN" ] || { echo "claude adapter: MOSAIC_CLAUDE_BIN is not an executable file: $MOSAIC_CLAUDE_BIN" >&2; exit 2; }
|
||||
CLAUDE=$MOSAIC_CLAUDE_BIN
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
✔ bus-service.sh pins the claude binary, refuses one the unit can't carry, and renders without one (812.758403ms)
|
||||
✔ bus-service.sh refuses a directory pin and keeps a symlink default unresolved (114.825073ms)
|
||||
✔ claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable (105.923033ms)
|
||||
✖ claude adapter: a directory pin exits 2 before it runs; a pin with a space runs (56.404674ms)
|
||||
ℹ tests 4
|
||||
ℹ suites 0
|
||||
ℹ pass 3
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1223.641818
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/harness/tests/claude-session.test.mjs:221:1
|
||||
✖ claude adapter: a directory pin exits 2 before it runs; a pin with a space runs (56.404674ms)
|
||||
AssertionError [ERR_ASSERTION]: /mnt/storage/scratch/rocko-r72/adapters/claude/adapter.sh: line 76: /mnt/storage/scratch/tmp/mosaic-harness-TaRYG3/claude-dir: Is a directory
|
||||
|
||||
|
||||
126 !== 2
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r72/packages/harness/tests/claude-session.test.mjs:251:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 126,
|
||||
expected: 2,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
diff --git a/adapters/claude/adapter.sh b/adapters/claude/adapter.sh
|
||||
index a0e04dae..700291db 100644
|
||||
--- a/adapters/claude/adapter.sh
|
||||
+++ b/adapters/claude/adapter.sh
|
||||
@@ -73,7 +73,7 @@ fi
|
||||
ALLOWED=mcp__mosaic
|
||||
[ -z "${MOSAIC_TOOLS:-}" ] || ALLOWED="$MOSAIC_TOOLS,mcp__mosaic"
|
||||
PROMPT_CONTENT="$(cat "$MOSAIC_SYSTEM_PROMPT_FILE")"
|
||||
-"$CLAUDE" -p "$MOSAIC_REQUEST" \
|
||||
+$CLAUDE -p "$MOSAIC_REQUEST" \
|
||||
--output-format text \
|
||||
--system-prompt "$PROMPT_CONTENT" \
|
||||
--model "$MOSAIC_MODEL" \
|
||||
@@ -0,0 +1,36 @@
|
||||
✔ bus-service.sh pins the claude binary, refuses one the unit can't carry, and renders without one (624.572705ms)
|
||||
✔ bus-service.sh refuses a directory pin and keeps a symlink default unresolved (157.138428ms)
|
||||
✔ claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable (228.077294ms)
|
||||
✖ claude adapter: a directory pin exits 2 before it runs; a pin with a space runs (53.77181ms)
|
||||
ℹ tests 4
|
||||
ℹ suites 0
|
||||
ℹ pass 3
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1092.980179
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/harness/tests/claude-session.test.mjs:221:1
|
||||
✖ claude adapter: a directory pin exits 2 before it runs; a pin with a space runs (53.77181ms)
|
||||
AssertionError [ERR_ASSERTION]: /mnt/storage/scratch/rocko-r72/adapters/claude/adapter.sh: line 76: /mnt/storage/scratch/tmp/mosaic-harness-0kAUdR/Claude: No such file or directory
|
||||
|
||||
|
||||
127 !== 0
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r72/packages/harness/tests/claude-session.test.mjs:258:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 127,
|
||||
expected: 0,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
diff --git a/adapters/claude/adapter.sh b/adapters/claude/adapter.sh
|
||||
index a0e04dae..1b10f061 100644
|
||||
--- a/adapters/claude/adapter.sh
|
||||
+++ b/adapters/claude/adapter.sh
|
||||
@@ -33,7 +33,7 @@ if [ -n "${MOSAIC_CLAUDE_BIN:-}" ]; then
|
||||
/*) ;;
|
||||
*) echo "claude adapter: MOSAIC_CLAUDE_BIN must be an absolute path: $MOSAIC_CLAUDE_BIN" >&2; exit 2 ;;
|
||||
esac
|
||||
- [ -f "$MOSAIC_CLAUDE_BIN" ] && [ -x "$MOSAIC_CLAUDE_BIN" ] || { echo "claude adapter: MOSAIC_CLAUDE_BIN is not an executable file: $MOSAIC_CLAUDE_BIN" >&2; exit 2; }
|
||||
+ [ -x "$MOSAIC_CLAUDE_BIN" ] || { echo "claude adapter: MOSAIC_CLAUDE_BIN is not an executable file: $MOSAIC_CLAUDE_BIN" >&2; exit 2; }
|
||||
CLAUDE=$MOSAIC_CLAUDE_BIN
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
✔ bus-service.sh pins the claude binary, refuses one the unit can't carry, and renders without one (1098.847282ms)
|
||||
✔ bus-service.sh refuses a directory pin and keeps a symlink default unresolved (127.567038ms)
|
||||
✔ claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable (271.776218ms)
|
||||
✖ claude adapter: a directory pin exits 2 before it runs; a pin with a space runs (103.350808ms)
|
||||
ℹ tests 4
|
||||
ℹ suites 0
|
||||
ℹ pass 3
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1656.594055
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/harness/tests/claude-session.test.mjs:221:1
|
||||
✖ claude adapter: a directory pin exits 2 before it runs; a pin with a space runs (103.350808ms)
|
||||
AssertionError [ERR_ASSERTION]: /mnt/storage/scratch/rocko-r72/adapters/claude/adapter.sh: line 76: /mnt/storage/scratch/tmp/mosaic-harness-Gqq6WT/claude-dir: Is a directory
|
||||
|
||||
|
||||
126 !== 2
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r72/packages/harness/tests/claude-session.test.mjs:251:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 126,
|
||||
expected: 2,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
✔ bus-service.sh pins the claude binary, refuses one the unit can't carry, and renders without one (975.231311ms)
|
||||
✔ bus-service.sh refuses a directory pin and keeps a symlink default unresolved (86.973344ms)
|
||||
✔ claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable (238.744224ms)
|
||||
✔ claude adapter: a directory pin exits 2 before it runs; a pin with a space runs (69.864826ms)
|
||||
ℹ tests 4
|
||||
ℹ suites 0
|
||||
ℹ pass 4
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1403.440301
|
||||
@@ -0,0 +1,13 @@
|
||||
diff --git a/scripts/bus-service.sh b/scripts/bus-service.sh
|
||||
index f641c479..8ec66216 100755
|
||||
--- a/scripts/bus-service.sh
|
||||
+++ b/scripts/bus-service.sh
|
||||
@@ -49,7 +49,7 @@ claude_line() {
|
||||
fi
|
||||
case "$bin" in /*) ;; *) die "claude path must be absolute: $bin" ;; esac
|
||||
case "$bin" in *[!A-Za-z0-9/._+-]*) die "claude path contains a character the unit cannot carry: $bin" ;; esac
|
||||
- [ -f "$bin" ] && [ -x "$bin" ] || die "claude path is not an executable file: $bin"
|
||||
+ [ -e "$bin" ] && [ -x "$bin" ] || die "claude path is not an executable file: $bin"
|
||||
echo "Environment=MOSAIC_CLAUDE_BIN=$bin"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
✔ bus-service.sh pins the claude binary, refuses one the unit can't carry, and renders without one (624.008311ms)
|
||||
✖ bus-service.sh refuses a directory pin and keeps a symlink default unresolved (29.247918ms)
|
||||
✔ claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable (248.164396ms)
|
||||
✔ claude adapter: a directory pin exits 2 before it runs; a pin with a space runs (56.412235ms)
|
||||
ℹ tests 4
|
||||
ℹ suites 0
|
||||
ℹ pass 3
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 923.50351
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/cli/tests/host.test.mjs:566:1
|
||||
✖ bus-service.sh refuses a directory pin and keeps a symlink default unresolved (29.247918ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
0 !== 1
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r72/packages/cli/tests/host.test.mjs:585:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 0,
|
||||
expected: 1,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
diff --git a/scripts/bus-service.sh b/scripts/bus-service.sh
|
||||
index f641c479..3c9e47d1 100755
|
||||
--- a/scripts/bus-service.sh
|
||||
+++ b/scripts/bus-service.sh
|
||||
@@ -40,7 +40,7 @@ claude_line() {
|
||||
if [ "$CLAUDE_SET" = 1 ]; then
|
||||
bin="$CLAUDE_BIN"
|
||||
else
|
||||
- bin="$(command -v claude || true)"
|
||||
+ bin="$(command -v claude || true)"; [ -z "$bin" ] || bin="$(readlink -f "$bin")"
|
||||
if [ -z "$bin" ]; then
|
||||
echo "bus-service: no claude on PATH; MOSAIC_CLAUDE_BIN left unset (--claude PATH pins one)" >&2
|
||||
echo "# MOSAIC_CLAUDE_BIN unset: no claude on PATH at install time"
|
||||
@@ -0,0 +1,37 @@
|
||||
✔ bus-service.sh pins the claude binary, refuses one the unit can't carry, and renders without one (826.39241ms)
|
||||
✖ bus-service.sh refuses a directory pin and keeps a symlink default unresolved (225.528412ms)
|
||||
✔ claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable (108.00737ms)
|
||||
✔ claude adapter: a directory pin exits 2 before it runs; a pin with a space runs (37.548293ms)
|
||||
ℹ tests 4
|
||||
ℹ suites 0
|
||||
ℹ pass 3
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1359.702788
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/cli/tests/host.test.mjs:566:1
|
||||
✖ bus-service.sh refuses a directory pin and keeps a symlink default unresolved (225.528412ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
+ actual - expected
|
||||
|
||||
+ '/mnt/storage/scratch/tmp/mosaic-cli-ePhmQ9/versions/claude-9.9.9'
|
||||
- '/mnt/storage/scratch/tmp/mosaic-cli-ePhmQ9/link-bin/claude'
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r72/packages/cli/tests/host.test.mjs:611:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: '/mnt/storage/scratch/tmp/mosaic-cli-ePhmQ9/versions/claude-9.9.9',
|
||||
expected: '/mnt/storage/scratch/tmp/mosaic-cli-ePhmQ9/link-bin/claude',
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
diff --git a/scripts/bus-service.sh b/scripts/bus-service.sh
|
||||
index f641c479..c0f5c4d4 100755
|
||||
--- a/scripts/bus-service.sh
|
||||
+++ b/scripts/bus-service.sh
|
||||
@@ -49,7 +49,7 @@ claude_line() {
|
||||
fi
|
||||
case "$bin" in /*) ;; *) die "claude path must be absolute: $bin" ;; esac
|
||||
case "$bin" in *[!A-Za-z0-9/._+-]*) die "claude path contains a character the unit cannot carry: $bin" ;; esac
|
||||
- [ -f "$bin" ] && [ -x "$bin" ] || die "claude path is not an executable file: $bin"
|
||||
+ [ -x "$bin" ] || die "claude path is not an executable file: $bin"
|
||||
echo "Environment=MOSAIC_CLAUDE_BIN=$bin"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
✔ bus-service.sh pins the claude binary, refuses one the unit can't carry, and renders without one (763.740714ms)
|
||||
✖ bus-service.sh refuses a directory pin and keeps a symlink default unresolved (33.151932ms)
|
||||
✔ claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable (270.747243ms)
|
||||
✔ claude adapter: a directory pin exits 2 before it runs; a pin with a space runs (45.638074ms)
|
||||
ℹ tests 4
|
||||
ℹ suites 0
|
||||
ℹ pass 3
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1238.504414
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/cli/tests/host.test.mjs:566:1
|
||||
✖ bus-service.sh refuses a directory pin and keeps a symlink default unresolved (33.151932ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
0 !== 1
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/rocko-r72/packages/cli/tests/host.test.mjs:585:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 0,
|
||||
expected: 1,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
b1c1aa79de3438504f38f92b51af8aaff065f496039d516dcb9609e8ef5ccf73 ./base.txt
|
||||
074d3dc8d21ad5130143cbd39b371295fe345184c5d826ec322ac4bdcd042a56 ./BUILD.md
|
||||
917bb1be18d7a7261901044178567b0c7b6b4e097e6883ebe5765286308fff23 ./build.patch
|
||||
e6531a5311f17ea147700e417dfdbd766a9c38acf3c3b44755267c285b78e006 ./candidate-manifest.sha256
|
||||
68b2ea64112704a190be5dc42264b2500fbcd0fe00bab01a761957d3f97ceb54 ./files.txt
|
||||
88adfa55efb6da9ea575b2074ed788f69b5cfc73b637dad8f3943c48e7c1f83d ./mutants.sh
|
||||
691348f31e44be6f0fc5bab7e06c64888953c607db85cb267a75c92345ed5f38 ./out/gate/cli.log
|
||||
fa23dbda2669e02a15422fd3bf306796641dd8fdd565213a85c82504153c84e2 ./out/gate/end.txt
|
||||
c329c85886bcd30613cf9ca494f4fe8f00817f850e49e569c412030dbdfdf986 ./out/gate/harness.log
|
||||
d06fc2614bb75bc7ff5a2c9ada5ac2c5177c3f850c4aaabe7fa089383e476731 ./out/gate/start.txt
|
||||
4561294ef708fb023f56b47d50f818d23224dfb5b38d278295b22b6f395809c8 ./out/gate/summary.txt
|
||||
f91fc95a173339137f981e24fbf630acfde957e32c3cd71e28304532083c6a77 ./out/gate/test-auth.log
|
||||
e1206366f07f3d9029530dcdcb55c0282d3f052adc60fc7fd51642d5d4ec3600 ./out/gate/test-conductor.log
|
||||
52d211444489ea729dafc3c9745d4474d9dfd50f41055cbad792424197f04073 ./out/gate/test-config.log
|
||||
7d5016ded1994048642f8b9ae845e52e8af4a069ba05c056c8f580a4589bacbe ./out/gate/test-discord.log
|
||||
b9cdb6e354bd14d0fa795fc0409d1683e1d8ce380b0417053fee662e38e91773 ./out/gate/test-extension-package.log
|
||||
83dfaa21c4e4ad941088efab3f69e87ebd2f6bd3cc72ede938e21dc06da8a34f ./out/gate/test-foundation.log
|
||||
1d0336ab459e089658ccff8c84ac53b0ffbab1a2bba2066750ece3909c876f41 ./out/gate/test-queue.log
|
||||
fa832794ee35025fb4559d58d01a270f6bff2eb65e863e9075b797f47fa68545 ./out/gate/test-release.log
|
||||
ccea37f4ffde1f160dcd1a1864988083a645d974e892065c956b338d0f8c853a ./out/gate/test-task.log
|
||||
7bf6bff528b53468e1341ca374159616593640f2a825e15e0bc1e22ec8ad5520 ./out/mutants-base/ad-no-f.diff
|
||||
d055ceef2310a6c9f12ad995e490b789b255f6b92d70c3f43db27828d50ec4e9 ./out/mutants-base/ad-no-f.log
|
||||
634196d7d864fd749ba8d5ebc1509e3f95085826613fed42ef830232218b1aa8 ./out/mutants-base/ad-unquoted-run.diff
|
||||
8ef4cecdf963642d82e5a3975293a8accea2cfb0b6f6e3471ce67220b98d43ed ./out/mutants-base/ad-unquoted-run.log
|
||||
340cbba44bd8a7858a07bf558c38439144073c1f8b7c8f7fdda2f8faa8e313ed ./out/mutants-base/ad-x-only.diff
|
||||
dd99890494e316b4265805ace7e1676f1d9585f6e7bef0bee337a4c55bdfb1c2 ./out/mutants-base/ad-x-only.log
|
||||
330147faa56b457ccc0af2e3bc94bb82b339c89fb761d3332697eedc631caa10 ./out/mutants-base/baseline.log
|
||||
0dd50a28ce2991879c83d85099e88ebb050be226a303fbbe8df7a6f1ca086646 ./out/mutants-base/bs-no-f.diff
|
||||
badfd557f34625bb7fd59273012c05b878507bfaa50bfbf3d24373dee2eaae8c ./out/mutants-base/bs-no-f.log
|
||||
0dcd53ab5db4652c0e4c0c7ffd84b91fd2570d9694deea3bb463294d9463d7bd ./out/mutants-base/bs-resolve-default.diff
|
||||
77548036af5235f493d957eccb31920d14becd4023abffaaae5842dcc0a38729 ./out/mutants-base/bs-resolve-default.log
|
||||
2d20403ddada87d232bdec3e1c834e2d181094f10bdc76d59b450c4d1cd8da70 ./out/mutants-base/bs-x-only.diff
|
||||
fdb4801844f159eac9c23176a4df97fe14dd04af39bd0bf8a2f5fbeb46596c6e ./out/mutants-base/bs-x-only.log
|
||||
bf2d9d276c7bcb6be4eff8eb8c7a6202e0da97df465895cf02a77e1bbd28dae4 ./out/mutants-base.txt
|
||||
7bf6bff528b53468e1341ca374159616593640f2a825e15e0bc1e22ec8ad5520 ./out/mutants-candidate/ad-no-f.diff
|
||||
6edd0a941faf86fa14e0d4a2c673f3c3ce42cef2dad60bc36181c5e83867d92e ./out/mutants-candidate/ad-no-f.log
|
||||
634196d7d864fd749ba8d5ebc1509e3f95085826613fed42ef830232218b1aa8 ./out/mutants-candidate/ad-unquoted-run.diff
|
||||
db9c14962b7feda199eed4d47f9c951b55fadf30fbd9f2a3cc585d2d21c2f962 ./out/mutants-candidate/ad-unquoted-run.log
|
||||
340cbba44bd8a7858a07bf558c38439144073c1f8b7c8f7fdda2f8faa8e313ed ./out/mutants-candidate/ad-x-only.diff
|
||||
fabdd03dafe4dc80a279902ec87b1d6e53cb1c327f762d82d40809f08a712026 ./out/mutants-candidate/ad-x-only.log
|
||||
5a6abe15c51ee48130de09f9032ca12fc42abac7bc96cc77acf6a3ff96219cc8 ./out/mutants-candidate/baseline.log
|
||||
0dd50a28ce2991879c83d85099e88ebb050be226a303fbbe8df7a6f1ca086646 ./out/mutants-candidate/bs-no-f.diff
|
||||
35ffa313386bbee6487abc2a6939010544ecab3e6d6a8ff86ef827b79c284759 ./out/mutants-candidate/bs-no-f.log
|
||||
0dcd53ab5db4652c0e4c0c7ffd84b91fd2570d9694deea3bb463294d9463d7bd ./out/mutants-candidate/bs-resolve-default.diff
|
||||
688b0a4eb377bc7b481202f8eccbfa6f70465ba552f7a63970ab861b0788a0ca ./out/mutants-candidate/bs-resolve-default.log
|
||||
2d20403ddada87d232bdec3e1c834e2d181094f10bdc76d59b450c4d1cd8da70 ./out/mutants-candidate/bs-x-only.diff
|
||||
5351195eae6351bad35226fb230cf49aef7d867de7a93db69f07595d0cee28c3 ./out/mutants-candidate/bs-x-only.log
|
||||
a4d82296596fac6986a3fb717a9da164f8c345412d8aa5f1d3ddb1dd33f03660 ./out/mutants-candidate.txt
|
||||
@@ -683,3 +683,5 @@ are never rewritten or removed; corrections are new entries.
|
||||
- 2026-10-11T22:54:17Z, Sage (lead): landed row 75 (#1569) as 743c01e3 after Filbert's approval 27430 and my gate rerun (webui 50, nine scripts/test-*.sh, all green); row 75 done and row 77 (#1571, N1-N5) added at revs 517-519 in f0c37f75, which also carried Filbert's rev 518 (row 74 approve, 27433); #1569 closed with comment 27434. Unit not installed or started.
|
||||
2026-10-11T22:55:02Z | filbert | row 74 (#1568) round 1 review, WebUI preview behind sign-in proxy, manifest 67515db5 | approve, comment 27433, queue rev 518 (in f0c37f75); N1 duplicate Host with loopback first skips sign-in (edge proxies 400 it), N2 five test-gap mutant survivors of 18, N3-N4 minor; suites webui 49, control-board 124, cli 112 green
|
||||
2026-10-11T23:04:39Z | dewey | row 67 (#1560) round 1 review, decision read docs and tests, manifest 8959e615 | approve, comment 27452, queue rev 522 in 01ef77b0; 11 mutants of mine, 11/11 killed on the candidate, 7 survive on base 970ef729; N1 test 4 doesn't assert its new decisions are listed; gate all green with Docker except the known discord flake #1553 (177/1 in the full run, 178/0 alone)
|
||||
2026-10-11T23:05:19Z | rocko | row 72 (#1566) round 1 candidate, Claude pin tests (directory pin, symlink default, pin with a space) | in-review requested; packet agents/rocko/work/queue-72 uncommitted; 6/6 mutants killed on candidate, 6/6 survive on base a0080da8; cli 113, harness 58, nine scripts/test-*.sh green
|
||||
- 2026-10-11T23:06:07Z, Sage (lead): row 72 (#1566) round 1. I posted the review request as jarvis for Rocko, comment 27454 (revs 527-528), and committed Rocko's packet (candidate e6531a53) with their revs 524-526 and their BUILD-LOG and SESSIONS appends. Reviewer: Filbert. Also row 74 goes to round 2 for Filbert's and Darkwing's sign-in findings (notes revs 521, 523); and 166cba45, my queue-commit with subject 'x', was rewritten locally with the same tree as ebd90554 before any push.
|
||||
|
||||
Reference in New Issue
Block a user