First step-3 refinement from Jason's daily use. Liveness now lists the panes of the agent's tmux session and counts it alive only if a pane runs pi, so killed pi sessions whose tmux session still exists show offline instead of waiting. A "Seen" button on waiting and error rows stores the row's lastActivity in <dataRoot>/board/seen.json (clicks only, never rewritten by a scan, fail closed if corrupt) and drops the row from "Waiting on you" until the agent writes anything newer; "Unsee" reverses it. New POST /api/seen route: JSON only, 4 KB limit, 400 on bad input. Tests: control-board 63/63 (30 new), registry 69/69. Review APPROVED; receipt docs/plans/reviews/2026-09-12_control-board-step3-seen-marks.md. Co-Authored-By: Claude Fable 5.1 <[email protected]>
70 lines
3.4 KiB
Markdown
70 lines
3.4 KiB
Markdown
# Control board step 3, first refinement: real liveness and "Seen" marks
|
|
|
|
Date: 2026-09-12. Recorded by jarvis (Claude Code, coordinator). Tracking: #1503.
|
|
Plan: `docs/plans/2026-09-12_control-board-mvp.md` (Step 3 log).
|
|
|
|
## What Jason reported
|
|
|
|
After using the page: "most of the sessions are actually just in a complete
|
|
state rather than waiting on me". Also, he had terminated the darkwing and
|
|
dewey pi sessions, and both still showed "waiting".
|
|
|
|
## Cause
|
|
|
|
1. Liveness only asked tmux whether a session by that name existed. Both
|
|
tmux sessions still existed (now running bash and Claude), so the scanner
|
|
read the old pi session log as live status.
|
|
2. Pi records that the agent finished a reply, not whether that reply was a
|
|
question or a completion report. Both landed in "waiting".
|
|
|
|
## What was built
|
|
|
|
- `tmuxIsAlive` now lists the panes of the named tmux session and reports
|
|
alive only if one runs `pi`. A session that exists but runs something else
|
|
is offline. The tmux check is injectable for tests.
|
|
- "Seen" marks: `<dataRoot>/board/seen.json` maps `project/agent` to the
|
|
`lastActivity` timestamp Jason marked. A marked row keeps its state but
|
|
leaves "Waiting on you" until the agent writes anything newer, which
|
|
changes the timestamp and clears the mark by itself. "Unsee" clears it by
|
|
hand. The file is written only by clicks (atomic, mode 0600); a scan reads
|
|
it and never rewrites it; a corrupt file refuses the scan (fail closed).
|
|
- Server: `POST /api/seen` with a JSON body; requires
|
|
`Content-Type: application/json` (so a page from another site cannot post
|
|
it without a CORS preflight, which this server does not answer); body limit
|
|
4096 bytes; 400 on bad input; 500 if the rescan fails. Other methods 405.
|
|
- Page: Seen / Unsee button beside the state badge, "seen" tag, footer count.
|
|
CLI `scan --print` shows `s` for seen rows and a seen count.
|
|
|
|
## Tests
|
|
|
|
`node --test packages/control-board/tests/`: 63 pass, 0 fail (30 new, written
|
|
by a Claude Sonnet helper against the spec; no src change was needed).
|
|
`node --test packages/mosaic/tests/`: 69 pass, 0 fail, unchanged.
|
|
|
|
## Live check
|
|
|
|
Real tmux, full fleet, Chrome via DevTools on port 7332. Before: 18 rows
|
|
waiting on Jason including darkwing and dewey. After the liveness fix: 16,
|
|
both now offline (their tmux sessions run bash). Clicking Seen on zane wrote
|
|
`{"fleet/zane": "<timestamp>"}` (mode 600), the row left "Waiting on you"
|
|
and showed a seen tag with Unsee in its project table; the API reported
|
|
15 waiting and 1 seen. Unsee emptied the file and restored 16. Console: no
|
|
messages. Screenshot `/tmp/control-board-seen.png` (not committed). The
|
|
board was left with no marks.
|
|
|
|
## Independent review
|
|
|
|
Reviewer: code-review agent (Claude Sonnet), read-only. It checked the pi
|
|
runtime source to confirm a live pi pane reports `pi` as its command (pi sets
|
|
its process title, and tool subprocesses do not take over the pane), traced
|
|
the CORS argument for the POST route, the escaping in the new markup, the
|
|
single-response paths in the server, and the stale-mark fail-safe. Verdict:
|
|
APPROVED with one finding: the README quoted the tmux command without the
|
|
`-s -t '=<session>'` flags the code uses. Fixed in README and plan page.
|
|
|
|
## Boundaries kept
|
|
|
|
Loopback only, no auth, no daemon, no launcher changes, no new root files,
|
|
no run records touched. `seen.json` is Jason's input, not derived data, and
|
|
is the only board file a scan does not regenerate.
|