Add mosaic launch <seat> with seat registration for the control board (#1504)
New package packages/seat and wrapper scripts/mosaic. `launch <seat>` writes <dataRoot>/seats/<layout>/<seat>/registration.json and then execs the seat's launch.sh unchanged; `seat task <seat> <text>` edits the task only. The board reads registrations, matches by sessions directory, and lets a registered task, project or workspace override the derived value with a source tag. The four repository launch scripts register themselves unless already registered or run with --check. Fleet launchers untouched; one-liner on the plan page. Review found the record path keyed by seat name alone (repo and fleet "darkwing" would collide); fixed by keying on layout. Also: the Pi pin refusal now names installed and required versions. Tests: seat 15, control-board 89, launch scripts 5, registry 69, config 24. Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
@@ -220,3 +220,4 @@ are never rewritten or removed; corrections are new entries.
|
||||
- 2026-09-12 — jarvis (Claude Code, coordinator) — Control board step 3, fourth refinement (#1503): Jason asked for "N of N" in the project header; now "shown of total" while a checkbox hides rows, plain total otherwise. Page-only change plus one static test (66/66); sonnet review APPROVED (no findings); live check in Chrome at all four edges.
|
||||
- 2026-09-12 — jarvis (Claude Code, coordinator) — Control board step 3, mid-tool-call rule (#1503), asked by the professor session on Jason's behalf: scanner already honoured the rule via stopReason; added a content-level toolCall check, 3 fixture tests + 3 table cases (69/69); live check on orch-01/rev-code-01 (working) and velma (waiting); sonnet review APPROVED (no findings; thinking-block nuance already recorded).
|
||||
- 2026-09-12 — jarvis (Claude Code, coordinator) — Control board step 3, Gate A fix (#1503), asked by the professor session on Jason's behalf: per-row Task (first user message), Active project (nearest git checkout above the workspace) and Workspace (live tmux pane path, else session cwd), "unknown" when not derivable; missing launcher signals logged on the plan page. Fixture test per field (79/79); live check on a scratch server; sonnet review APPROVED (no findings).
|
||||
- 2026-09-12 — darkwing (Claude Code, coordinator; formerly jarvis) — Seat registration (#1504), Jason's go on the professor session's brief: new `packages/seat` and `scripts/mosaic` (`launch <seat>` registers then execs the launch script unchanged; `seat task` edits the task); board reads `<dataRoot>/seats/<layout>/<seat>/registration.json` and lets registered task/project/workspace override derived values with a source tag; the four repo launch scripts register themselves; fleet one-liner written for orch-01. Tests: seat 15, board 79 → 89, launch scripts 5, registry 69, config 24. Sonnet review found a seat-name collision across layouts; fixed by keying on layout, second pass APPROVED. Live check on a scratch server against a temp data root. Also found Jason's launch refused on the Pi pin (node_modules 0.84.4 vs pin 0.85.1 since 557aba0f); `npm ci` fixed it, the refusal now names both versions; the pin stays unless Jason decides otherwise.
|
||||
|
||||
@@ -130,6 +130,23 @@ Push is never automatic.
|
||||
| `scripts/test-auth.sh` | Auth checkpoint selftests (no Docker) | 13 cases |
|
||||
| `scripts/gitea-api.sh <METHOD> <path> [body]` | Gitea API helper | Token never on argv/stdout |
|
||||
|
||||
## Seat launch with registration (`scripts/mosaic`)
|
||||
|
||||
```bash
|
||||
scripts/mosaic launch <seat|seat-dir> [--task TEXT] [--project NAME] [--workspace PATH] [--harness NAME] [--repo PATH] [--config PATH] [-- args...]
|
||||
scripts/mosaic seat task <seat> <text> [--layout repo|fleet|unknown] [--config PATH]
|
||||
```
|
||||
|
||||
Runs a seat's `launch.sh` unchanged (arguments after `--` pass through) and
|
||||
leaves one registration record at `<dataRoot>/seats/<layout>/<seat>/registration.json`
|
||||
that the control board reads: seat, project, task, workspace, tmux session,
|
||||
harness, start time, pid. Rewritten on every launch. `seat task` changes the
|
||||
task field only. The four repository seats (`agents/*/launch.sh`) register
|
||||
themselves through this path unless called with `--check`. Not the
|
||||
npm-global `mosaic` CLI; run by path. Exit codes: the launch script's own
|
||||
once it runs; before that 1 could not start, 2 invalid config or seat, 4
|
||||
usage. Details and the record's fields: `packages/seat/README.md`.
|
||||
|
||||
## Tools (host-side)
|
||||
|
||||
Host-side helpers under `tools/`, outside the `scripts/` command surface.
|
||||
|
||||
@@ -114,6 +114,10 @@ Two kinds of agents are scanned today:
|
||||
|
||||
- One file per agent: `<dataRoot>/board/sessions/<project>/<agent>.json`
|
||||
- One summary file for the whole board: `<dataRoot>/board/index.json`
|
||||
- One registration per seat started through `mosaic launch`:
|
||||
`<dataRoot>/seats/<layout>/<seat>/registration.json` (#1504). Written by the
|
||||
launcher, read by the board, rewritten on relaunch. Not under `board/`
|
||||
because the board never writes it.
|
||||
- `dataRoot` comes from `~/.config/mosaic-dev/config.json`. If that config
|
||||
is missing or broken, the scanner refuses to run. It does not guess a
|
||||
fallback location.
|
||||
@@ -144,12 +148,18 @@ node --test packages/control-board/tests/
|
||||
|
||||
## Boundaries
|
||||
|
||||
- No changes to any launcher script.
|
||||
- No changes to any launcher script. Corrected 2026-09-12 by Jason's go on
|
||||
the `mosaic launch` brief (#1504): the four repository launch scripts
|
||||
(`agents/{darkwing,dewey,filbert,rocko}/launch.sh`) gained a guard that
|
||||
re-enters them through `scripts/mosaic launch` for registration. The
|
||||
fleet launchers under `~/.mosaic` are still untouched; their one-line
|
||||
change is written in the Step 3 log for orch-01 to apply.
|
||||
- No new files at the repository root.
|
||||
- No secrets read, stored, or printed.
|
||||
- No daemon yet. In step 1 the scanner is run by hand. In step 2 the page
|
||||
may trigger it on refresh; nothing runs it on a schedule.
|
||||
- No changes to `packages/mosaic`.
|
||||
- No changes to `packages/mosaic`. Still true: seat registration went into
|
||||
a new package, `packages/seat`, not the hardened registry.
|
||||
- This plan does not authorize push or merge beyond whatever the existing
|
||||
refactor-branch plan already allows.
|
||||
|
||||
@@ -210,3 +220,73 @@ used" hold above: the selection is made, on evidence from today's use. It does
|
||||
not start WebUI build work. Sequence stays: seat registration via
|
||||
`mosaic launch` (in progress), then reply-from-board, then the WebUI on the
|
||||
Console design absorbs the board as its first screen.
|
||||
|
||||
**2026-09-12 — Seat registration: `mosaic launch <seat>` (#1504).** Gate A
|
||||
passed on Jason's go, relayed by the professor session with a brief. New
|
||||
package `packages/seat` and wrapper `scripts/mosaic`:
|
||||
|
||||
- `scripts/mosaic launch <seat|seat-dir> [--task ..] [-- args]` resolves
|
||||
`agents/<seat>/launch.sh` (repo layout) or a seat directory (fleet layout,
|
||||
`<seatDir>/.pi`), writes `<dataRoot>/seats/<layout>/<seat>/registration.json`, then
|
||||
replaces itself with the launch script (`process.execve`), so the pid, the
|
||||
terminal, the exit code and the tmux foreground command are the script's
|
||||
own. The record: seat, project, task, workspace, tmux, harness, startedAt,
|
||||
pid, plus sessionsDir (the board matches on it, not on the name, because
|
||||
"darkwing" exists in both layouts), seatDir, launchScript, layout,
|
||||
updatedAt, version. Rewritten on every launch.
|
||||
- `scripts/mosaic seat task <seat> <text>` changes the task only; refuses
|
||||
when the seat was never launched this way.
|
||||
- Scanner: registrations are read on every scan; a registered task, project
|
||||
or workspace wins and `taskSource`, `activeProjectSource`,
|
||||
`workspaceSource` read `registration`; empty or null registered fields
|
||||
leave the derived value; rows without a registration are unchanged. A
|
||||
malformed record is listed in `registrationErrors` and skipped. Page: a
|
||||
small "registered" tag next to the value and a Registered line in the
|
||||
detail (start, harness, pid, tmux, layout).
|
||||
- The four repository launch scripts (`agents/{darkwing,dewey,filbert,
|
||||
rocko}/launch.sh`) gained a five-line guard: unless
|
||||
`MOSAIC_LAUNCH_REGISTERED` is set or `--check` is among the arguments,
|
||||
re-enter through `scripts/mosaic launch --harness pi|claude-code`. So the
|
||||
plain `agents/darkwing/launch.sh` registers too. rocko registers but is
|
||||
still not on the board: it has no pi session log to scan. Gap, not a bug.
|
||||
- Fleet launchers under `~/.mosaic` are not edited from this repository.
|
||||
One-line change for orch-01 to apply in
|
||||
`~/.mosaic/fleet/bin/launch-seat.sh`, after `SEAT_DIR=` is set (the
|
||||
per-seat `launch.sh` files are shims and need nothing):
|
||||
`[[ -n "${MOSAIC_LAUNCH_REGISTERED:-}" || "$CHECK" -eq 1 ]] || exec /mnt/storage/src/mosaic-stack/scripts/mosaic launch --harness pi "$SEAT_DIR" -- "$@"`
|
||||
Fleet records carry project and workspace null (roster has no project
|
||||
field; all fleet seats run in `~/.mosaic`), so those rows keep their
|
||||
derived values until `--project`/`--workspace` are passed or the roster
|
||||
gains a field.
|
||||
- Sonnet review found one defect before commit: the record path was keyed
|
||||
by seat name alone, so the repo and fleet "darkwing" would have overwritten
|
||||
each other. Fixed by keying on layout and seat
|
||||
(`seats/<layout>/<seat>/`); `seat task` refuses a bare name registered in
|
||||
more than one layout unless `--layout` is given. Second review pass
|
||||
approved. The reviewer also noted `process.execve` is marked experimental
|
||||
in Node; recorded, accepted (Node 24+ is the floor and the API is the only
|
||||
way to keep the seat's pid).
|
||||
- Name clash noted: the npm-global `mosaic` CLI (estate tooling) has no
|
||||
`launch` or `seat` command; the repository wrapper is run by path.
|
||||
|
||||
Tests: seat package 15 (record write via a fake launch.sh, args and exit
|
||||
passthrough, relaunch rewrite, `--task`, tmux null, tmuxContext with a fake
|
||||
exec, task update and its refusals, malformed records, samePath through a
|
||||
symlink, recursion guard); control board 79 → 89 (override precedence,
|
||||
empty registration, no registration parity, loadRegistrations errors,
|
||||
matchRegistration by realpath and the same-name-different-layout case, scan
|
||||
on disk, server round trip, page source checks); the two launch-script
|
||||
suites now run each real `launch.sh` in a fixture that is its own data root
|
||||
and assert the record and the `MOSAIC_LAUNCH_REGISTERED` value Pi/Claude
|
||||
saw (5/5); registry 69/69; config 24/24. Live check: the real
|
||||
`agents/darkwing/launch.sh` run through the launcher against a temporary
|
||||
data root, then a scratch board on 7332 reading that root: the darkwing
|
||||
row shows the registered task, "registered" on task and project, and the
|
||||
Registered detail line.
|
||||
|
||||
Found on the way: Jason's own launch refused with "local Pi must match
|
||||
package.json (0.85.1)". Commit 557aba0f (#1499) moved the pin without an
|
||||
`npm ci` in this checkout (node_modules held 0.84.4; the global pi was
|
||||
already 0.85.1, which hid it). Fixed by `npm ci`; the refusal now names
|
||||
both versions. Jason questioned the pin itself; it is canon (AGENTS.md
|
||||
"Version pin") and stays unless he decides otherwise.
|
||||
|
||||
+21
-7
@@ -22,13 +22,27 @@ First step-3 refinement landed 2026-09-12: liveness follows the tmux pane
|
||||
"Waiting on you" until the agent writes again
|
||||
(`docs/plans/reviews/2026-09-12_control-board-step3-seen-marks.md`).
|
||||
|
||||
Next action: step 3 of #1503 — daily use. Jason opens the page while he works
|
||||
and reports what is wrong, missing or confusing; each report becomes a small
|
||||
fix on this package with a test, committed and pushed to `refactor`. Close
|
||||
#1503 when Jason says the page answers "who is waiting on me" without him
|
||||
opening a terminal. Out of scope until he asks: auth, hooks/plugins, comms,
|
||||
memory, launcher changes, non-Pi harnesses, new root files. The registry line
|
||||
(increment 3, headless identity-env leak) stays parked; #1500 is closed.
|
||||
Gate A (task, active project, workspace per row) passed on 2026-09-12 and
|
||||
Jason's go on the professor session's brief opened #1504: seat registration.
|
||||
`scripts/mosaic launch <seat>` runs a seat's launch script unchanged and
|
||||
leaves one record at `<dataRoot>/seats/<layout>/<seat>/registration.json` that the
|
||||
board reads instead of guessing; `scripts/mosaic seat task <seat> <text>`
|
||||
changes the task. The four repository launch scripts register themselves.
|
||||
Package: `packages/seat`. Fleet launchers under `~/.mosaic` are not edited
|
||||
from this repository; the one-line change for them is in the plan page.
|
||||
|
||||
Next action: step 3 of #1503 continues — daily use with #1504 landed. Jason
|
||||
launches his seats through the new path (or the launch scripts, which now
|
||||
register), sets tasks with `seat task`, and reports what is wrong, missing
|
||||
or confusing; each report becomes a small fix with a test, committed and
|
||||
pushed to `refactor`. The sequence Jason set stays: seat registration (done),
|
||||
then reply-from-board, then the WebUI on Dewey's Console design absorbs the
|
||||
board as its first screen. Close #1503 when Jason says the page answers "who
|
||||
is waiting on me" without him opening a terminal. Out of scope until he
|
||||
asks: auth or provider registry, roster schema changes, hooks/plugins, comms,
|
||||
memory, multiple sessions per seat, stopping seats, new root files. The
|
||||
registry line (increment 3, headless identity-env leak) stays parked; #1500
|
||||
is closed.
|
||||
|
||||
## Completed checkpoint: #1500 increment 2 (historical)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user