docs: lead decision 91, row 68 build log, pin and coder grant brief (#1561)
Decision 91 amends 89: the bus pins ~/.local/bin/claude through MOSAIC_CLAUDE_BIN, so the package upgrade is no longer needed for the first PM launch. The brief covers two Rocko rows: tests for row 68's surviving mutants, and dropping the coder's dead task.reassign grant. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -1919,3 +1919,26 @@ which stay with him. Each item names who decided it and what happened.
|
||||
reviewer who isn't assigned can't comment on the task through the
|
||||
bus. If slice 1 acceptance needs that, it is a new verb or a
|
||||
change to `task.update.assigned`, decided then.
|
||||
91. **The bus pins the user's Claude Code binary; this amends 89
|
||||
(2026-10-11).** Decision 89 left the bus on `/usr/bin/claude` and made
|
||||
the fix Jason's package upgrade. Row 68 (#1561, 11dae0c7) took the
|
||||
other path: `bus-service.sh install --claude PATH` writes
|
||||
`Environment=MOSAIC_CLAUDE_BIN=PATH` into the unit, and the claude
|
||||
adapter runs that binary when it is set.
|
||||
- Installed 2026-10-11T21:42:39Z with
|
||||
`--claude /home/jwoltje/.local/bin/claude` (a symlink, now to
|
||||
2.1.296). The unit's only change was that line and its comments;
|
||||
`daemon-reload` only, no restart.
|
||||
- Probe at 21:43:03Z, the adapter under `env -i` with the unit's PATH
|
||||
and claude-opus-5-5: the pinned binary answered "OK", rc 0;
|
||||
`/usr/bin/claude` still gets "2.1.280 or newer is required", rc 1.
|
||||
- Jason's sudo upgrade is no longer needed for the first PM launch.
|
||||
The pacman package stays installed and untouched. The running bus
|
||||
(PID 1242258, up since 13:19:28 CDT) keeps its old environment until
|
||||
Mos's watched Q18 `--pm` restart; Sage doesn't restart it.
|
||||
- The tradeoff: the symlink follows the user's auto-updates, so a bad
|
||||
Claude Code release reaches the bus at its next restart without a
|
||||
review. Decision 89 valued the root-owned package for that reason.
|
||||
No version floor check runs at start; one would catch a
|
||||
downgrade, not a bad upgrade. Re-pinning to a versioned path is one
|
||||
`install --claude` away if a release breaks it.
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
# Follow-ups after row 68 and lead decision 90 (2026-10-11)
|
||||
|
||||
Status: written by Sage, lead. It follows `docs/plans/BRIEF-TEMPLATE.md`.
|
||||
Two rows, both small, both Rocko's.
|
||||
|
||||
## Claude pin tests: a directory pin, a symlink default, a pin with a space
|
||||
|
||||
### Problem
|
||||
|
||||
Row 68 (#1561, commit 11dae0c7) pins the bus's Claude Code binary with
|
||||
`MOSAIC_CLAUDE_BIN`. Filbert (comment 27349) and Dewey (comment 27350)
|
||||
approved it and named mutants no test kills:
|
||||
|
||||
- `bs-no-f`, `ad-no-f`, `bs-x-only` and `ad-x-only`. The `[ -f … ]` check
|
||||
in `scripts/bus-service.sh` (`claude_line`) and in
|
||||
`adapters/claude/adapter.sh` can go and every test still passes. A
|
||||
directory is `-x`, so the unit would carry a directory pin, and the
|
||||
adapter would fail at exec (exit 126, "Is a directory") instead of
|
||||
exiting 2 with its own message.
|
||||
- `bs-resolve-default`. Resolving the default `command -v claude` with
|
||||
`readlink -f` passes, because the test's `claude` on `PATH` is a plain
|
||||
file. On Jason's host `~/.local/bin/claude` is a symlink, and the pin is
|
||||
meant to keep the symlink so updates follow.
|
||||
- `ad-unquoted-run`. The adapter runs `"$CLAUDE"`. Unquoted, a pin with a
|
||||
space breaks. `bus-service.sh` refuses a space, but the adapter takes a
|
||||
hand-set pin. Nothing in the adapter checks the pin's characters.
|
||||
|
||||
`bs-status-no-env` and `bs-sed-unanchored` stay untested; both reviewers
|
||||
asked for no test.
|
||||
|
||||
### Owner and reviewer
|
||||
|
||||
Owner: Rocko. Reviewer: Filbert. Rocko has no Gitea token; Sage runs the
|
||||
review request as jarvis.
|
||||
|
||||
### Files owned
|
||||
|
||||
- `packages/cli/tests/host.test.mjs`
|
||||
- `packages/harness/tests/claude-session.test.mjs`
|
||||
- `agents/rocko/work/queue-<row>/`
|
||||
|
||||
### What ships
|
||||
|
||||
- A `render --claude DIR` test and a default test where the `claude` on
|
||||
`PATH` is a directory: both refuse with "not an executable file" and
|
||||
print nothing on stdout.
|
||||
- A default test where the `claude` on `PATH` is a symlink to an
|
||||
executable: the unit's `MOSAIC_CLAUDE_BIN` is the symlink path, not its
|
||||
target.
|
||||
- An adapter test with `MOSAIC_CLAUDE_BIN` a directory (exits 2 before
|
||||
anything runs) and one with a stand-in under a directory whose name has
|
||||
a space (runs).
|
||||
- The packet reruns the six named mutants against the candidate and lists
|
||||
each killed.
|
||||
|
||||
### Out of scope
|
||||
|
||||
Any change to `bus-service.sh`, `adapter.sh`, the launcher or the seat
|
||||
session code. If a test shows the code is wrong, stop and tell Sage.
|
||||
|
||||
### Gate
|
||||
|
||||
Filbert approves on the row's issue naming the candidate manifest. The
|
||||
cli and harness node suites and every `scripts/test-*.sh` green on Sage's
|
||||
gate rerun.
|
||||
|
||||
## Coder role: drop the task.reassign grant the broker always refuses
|
||||
|
||||
### Problem
|
||||
|
||||
`roles/coder.json` lists `task.reassign` under `crossRole`. The task verbs
|
||||
refuse every pm-only verb to any other role (`packages/tasks/src/verbs.mjs`,
|
||||
`PM_VERBS`, `field-writer`), so a coder's resolved decision to reassign
|
||||
always ends in `field-writer`. Lead decision 90 kept assignee pm-only and
|
||||
named this a dead grant for its own row. A grant that can never succeed
|
||||
misleads anyone reading the role file and wastes a decision round.
|
||||
|
||||
### Owner and reviewer
|
||||
|
||||
Owner: Rocko. Reviewer: Dewey. Sage runs the review request as jarvis.
|
||||
|
||||
### Files owned
|
||||
|
||||
- `roles/coder.json`, the `crossRole` list only
|
||||
- any test that lists the coder's grants, and a bus test for the
|
||||
classification
|
||||
- `agents/rocko/work/queue-<row>/`
|
||||
|
||||
### What ships
|
||||
|
||||
- `task.reassign` removed from the coder's `crossRole`; `task.scope.change`
|
||||
stays.
|
||||
- A test that the broker now classes a coder's `task.reassign` as
|
||||
`gated`, not `cross-role` (`packages/bus/src/broker.mjs`,
|
||||
`#classification`: an action in neither list is gated). The verb
|
||||
still refuses with `field-writer` if it ever runs.
|
||||
- The packet lists every place that read the old grant (role resolution,
|
||||
tests, docs), with what each now says. It also says plainly what a
|
||||
coder's `task.reassign` does end to end after the change. A gated
|
||||
request asks a human for a decision that can only end in
|
||||
`field-writer`. Refusing it before any decision opens is a broker
|
||||
change and would be its own row. The packet names it; it doesn't make it.
|
||||
|
||||
### Out of scope
|
||||
|
||||
Any other role's grants, the `PM_VERBS` set, `broker.mjs` and the slice 1
|
||||
field table.
|
||||
Who may reassign doesn't change; only the grant that never worked goes.
|
||||
|
||||
### Gate
|
||||
|
||||
Dewey approves on the row's issue naming the candidate manifest. The
|
||||
tasks, bus, business and harness node suites and every `scripts/test-*.sh` green
|
||||
on Sage's gate rerun.
|
||||
Reference in New Issue
Block a user