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]>
108 lines
4.0 KiB
Markdown
108 lines
4.0 KiB
Markdown
# Control board MVP — plan
|
|
|
|
Tracking: Gitea issue #1503 (https://git.mosaicstack.dev/mosaicstack/stack/issues/1503)
|
|
|
|
## Why
|
|
|
|
Jason is building blind. He has many agent sessions running across projects
|
|
and no single place to see what they are doing or who is waiting on him.
|
|
This plan replaces the registry line as the next thing to build. Registry
|
|
increment 3 stays parked; it does not resume by inertia. Decision record:
|
|
`MOSAIC-STACK-D-001` (Jason, 2026-09-12).
|
|
|
|
## What "done" looks like for the MVP
|
|
|
|
One web page lists my running agent sessions across projects, shows each
|
|
one's current status, and flags which ones are waiting on me.
|
|
|
|
Acceptance:
|
|
|
|
- Jason opens one page and sees every live pi agent, grouped by project.
|
|
- Each agent shows a state in plain words (working, waiting, error,
|
|
offline, idle, unknown).
|
|
- A "waiting on you" section sits at the top of the page.
|
|
- The page refreshes itself. Jason does not have to reload it by hand.
|
|
- Every state on the page comes from a status file written by the scanner,
|
|
not from a guess made in the page itself.
|
|
|
|
## Three steps
|
|
|
|
### Step 1 (today): plan, ticket, scanner
|
|
|
|
- Write this plan and open the Gitea ticket.
|
|
- Build the status scanner script with tests. Running it writes one status
|
|
file per agent under `<dataRoot>/board/`.
|
|
- This step does not touch any page or launcher. It only produces files.
|
|
|
|
### Step 2: the web page
|
|
|
|
- Build a page that reads the status files the scanner writes and shows
|
|
them grouped by project, with the waiting-on-you section on top.
|
|
- The page refreshes itself on a short timer. The small local server behind
|
|
it may re-run the scanner on each refresh so the files stay fresh. No
|
|
separate daemon is needed for this step.
|
|
|
|
### Step 3: daily use and fixes
|
|
|
|
- Jason uses the page every day for real work.
|
|
- He says what is wrong or missing.
|
|
- Fix that one thing, then repeat. No new scope beyond what he actually hits.
|
|
|
|
## How the scanner decides state
|
|
|
|
The scanner reads the newest pi session log for each agent, plus whether
|
|
the agent's tmux session is still alive. It does not guess; it only reports
|
|
what the log and tmux say.
|
|
|
|
| State | Plain-words meaning |
|
|
|---------|----------------------|
|
|
| working | The agent is in the middle of a turn: thinking or running a tool. |
|
|
| waiting | The agent finished its turn. It is your move now. |
|
|
| error | The agent's last turn ended in an error, was aborted, or was cut off. Go look at it. |
|
|
| offline | There is no live tmux session for this agent right now. |
|
|
| idle | The agent is live but has not had a conversation yet. |
|
|
| unknown | The scanner could not ask tmux (missing or not answering). It does not assume the agent is alive. |
|
|
|
|
Two kinds of agents are scanned today:
|
|
|
|
- Repo agents: session logs live under `.pi/state/<agent>/sessions` in a
|
|
project checkout, on the default tmux socket.
|
|
- Fleet agents: session logs live under
|
|
`~/.mosaic/fleet/agents/<agent>/.pi/agent/sessions`, on the tmux socket
|
|
named `mosaic-fleet`.
|
|
|
|
## Where files go
|
|
|
|
- One file per agent: `<dataRoot>/board/sessions/<project>/<agent>.json`
|
|
- One summary file for the whole board: `<dataRoot>/board/index.json`
|
|
- `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.
|
|
|
|
Board files are derived. They can be deleted and rebuilt at any time by
|
|
running the scanner again. They are NOT run records and they are not
|
|
evidence under the repository's write-once rules.
|
|
|
|
## Command
|
|
|
|
```
|
|
node packages/control-board/src/cli.mjs scan --print
|
|
```
|
|
|
|
Tests:
|
|
|
|
```
|
|
node --test packages/control-board/tests/
|
|
```
|
|
|
|
## Boundaries
|
|
|
|
- No changes to any launcher script.
|
|
- 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`.
|
|
- This plan does not authorize push or merge beyond whatever the existing
|
|
refactor-branch plan already allows.
|