# Row 70 round 1 (#1564): docs for `mosaic` on PATH Sage, 2026-10-15. Three doc files and one test. Reviewer: Filbert. - Brief: `docs/plans/2026-10-11_mosaic-on-path-docs.md`, pinned at blob d56345b76ffd (rev 1314; first pinned at f04bcaddb529, rev 1306). I updated it in 4c1b11d93 before building, because rows 85 (#1579) and 130 (#1625) changed the facts after it was written on 10-11. The update paragraph sits under "Problem"; "What ships" now names the stack-copy wrapper and the human/queue split. After the first gate I amended it again in 06e964026: the acceptance list now allows this row to narrow the pre-A2 fixture check, and no other test or source change. - Base: 48b893871 (`base.txt`), which has rows 49 and 123 in it. The patch is the same diff I first built on 4c1b11d93; it applies cleanly on 48b893871 and no commit between them touches a manifest path. - Candidate: `build.patch`, `candidate-manifest.sha256` (4 files), manifest file sha256 `1126314bd522de838aad03689bed41f6b12a33c2d7f30b2eff1b38653f559ae0`. The first build (3 files, `c8649f2e…`) failed the gate; see "Test change". ## What changed | File | Change | |------|--------| | `scripts/mosaic` | header comment lines 10-11 replaced by seven comment lines; no code line moved or changed | | `docs/TOOLS.md` | seat-launch paragraph: "Not the npm-global `mosaic` CLI; run by path." replaced; links "Stack copies" in the same file | | `packages/seat/README.md` | "Commands" first paragraph replaced; links packages/cli/README.md "One pinned copy" | | `packages/queue/tests/dispatch.test.mjs` | the pre-A2 fixture check skips comment lines; see "Test change" | Each place now says: 1. `scripts/mosaic` is the repository wrapper, run by path from the checkout. 2. A host may put `mosaic` on PATH as a wrapper around a pinned copy's `scripts/mosaic` (`scripts/stack-copy.sh wrapper`). The seat README also names `mosaic-old` as the estate CLI it replaced on Jason's host. 3. On a pinned host the human commands go through `mosaic` on PATH. The header also says `--tester`, and that the checkout exits 3 for them. 4. Queue commands stay on `scripts/mosaic queue` in the canonical checkout, because a copy refuses them. ## Evidence for the claims - Point 4: from the canonical checkout, a read-only `bash ~/.local/share/mosaic-stack/copies/2f57e3c5…/scripts/mosaic queue show 70` printed `queue: this queue code (…/copies/2f57e3c5…/packages/queue/src/store.mjs) is not under the canonical root /mnt/storage/src/mosaic-stack` and exited 2. The refusal is `packages/queue/src/store.mjs:85`. - Point 3: packages/cli/README.md "One pinned copy" (row 130 text) and docs/TOOLS.md "Pinned stack update", which this row links rather than restates. - Point 2: docs/TOOLS.md "Stack copies" and `scripts/stack-copy.sh` lines 67-71, which keep the lease line to `mosaic-old` and exec the copy's `scripts/mosaic`. - The two anchors resolve: `#stack-copies-scriptsstack-copysh` is the slug of TOOLS.md "## Stack copies (`scripts/stack-copy.sh`)", and `#one-pinned-copy-row-85-1579` is the anchor TOOLS.md already uses for the CLI README section. ## Checks - `bash -n scripts/mosaic` passes. `git diff --check` is clean. The added lines have no em dash, curly quote or control character. - Gate, second run on 48b893871: `gate-run.log` and `gate/`. 24 suites, 0 failed. 14 package suites passed 1611 tests (cli 195, seat 132, bus 191). The 10 script suites passed, queue 156/0 with the test change. No flake of #258, #261, #262 or #263 in either run. ## Test change My first build claimed here that `dispatch.test.mjs` compares behaviour, not header text. That was wrong. Its test "the pre-A2 fixture is the script A2 changed" checks that every line of `packages/queue/tests/fixtures/mosaic-pre-a2.sh` still appears, in order, in `scripts/mosaic`. The fixture carries the two old header lines ("Not the npm-global `mosaic` CLI ... only reachable as scripts/mosaic"), so the first gate stopped at script-queue with 155/1 (log kept as `gate-r1-run.log`). Keeping those lines isn't an option: "only reachable as scripts/mosaic" is false on a pinned host, which is the point of this row. Editing the fixture would make it no longer the pre-A2 script. So the check now compares lines that don't start with `# `. The shebang (`#!`) stays in. The pin protects what the script runs, and a header rewrite can't change that. Evidence, single file in the candidate tree: `dispatch.test.mjs` 4/0. Three mutants on `scripts/mosaic`, each run against the pre-A2 test, each fails it (fail 1): drop `set -euo pipefail`, drop the `REPO=` line, drop the shebang. ## Out of scope The Q81 script, packaging for other hosts, and the queue's canonical-root refusal, as the brief says.