Add control board status scanner and MVP plan (#1503)

Step 1 of the control board MVP (decision MOSAIC-STACK-D-001): a plan page,
Gitea #1503, and packages/control-board, which reads each agent's newest pi
session log plus tmux liveness and writes one status file per agent under
<dataRoot>/board/. 23/23 tests; independent review approved after three
fixes (length stopReason as error, unknown liveness state, secrets-boundary
test). CURRENT.md now points at step 2, the page.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
2026-09-12 07:26:03 -05:00
co-authored by Claude Fable 5.1
parent 1993039c76
commit b9f59a5903
10 changed files with 1003 additions and 15 deletions
@@ -0,0 +1,50 @@
# Control board MVP step 1: implementation and review receipt
Date: 2026-09-12. Recorded by jarvis (Claude Code, coordinator). Tracking: #1503.
Plan: `docs/plans/2026-09-12_control-board-mvp.md`. Decision: MOSAIC-STACK-D-001.
## What was built
`packages/control-board/` (ESM, no dependencies, node >= 24): `src/scan.mjs`
reads each agent's newest pi session log plus tmux liveness and writes one
status file per agent under `<dataRoot>/board/sessions/<project>/<agent>.json`
and a summary `index.json`. `src/cli.mjs` wraps it (`scan --print`). Config is
read fail-closed from `~/.config/mosaic-dev/config.json`. Board files are
derived and rewritable; they are not run records.
## Tests
`node --test packages/control-board/tests/` — 23 tests, 23 pass, 0 fail.
`node --test packages/mosaic/tests/` still 69/69 (untouched, checked for drift).
## Live run
`node packages/control-board/src/cli.mjs scan --print` on this host: 42 sessions
(4 repo agents, 38 fleet agents); 15 waiting, 3 error (all three are pi
usage-limit 429 errors on 2026-09-11), 24 offline, 0 working, 0 idle, 0 unknown;
18 flagged waiting on Jason. Spot checks: `arena-100` offline matched
`tmux -L mosaic-fleet has-session` refusing; the error rows matched the raw
`stopReason: "error"` entries.
## Independent review
Reviewer: in-session code-review agent (Claude Sonnet), read-only, with access to
the installed pi runtime for stopReason verification. First verdict: CHANGES
REQUIRED with three findings, all fixed in the same pass:
1. pi emits `stopReason: "length"` when a response is cut off; it fell through to
"working". Now mapped to "error".
2. A tmux check that could not run (`null`) was treated as alive. Now reported as
a distinct "unknown" state, never counted as waiting on you.
3. No test pinned the rule that the scanner only walks inside the given sessions
directory (fleet auth symlinks sit beside it). Added a sibling-secrets test.
Second verdict: APPROVED. The reviewer also noted one imprecision in my change
summary (a lastError test I described as new in the fix round had been added just
before the round); recorded here for honesty.
## Boundaries kept
No launcher changes, no new root files, no secrets read or printed, no changes to
`packages/mosaic`, no daemon, no web page yet. Next action (CURRENT.md): step 2,
the page.