# 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 `/board/sessions//.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.