Dashboard
castellan dashboard is the ratatui operator UI over the in-tree multiplexer — agents, pressure, pane topology, and the evolution archive in one view.
What / why
Live stigmergy control tower: field heat from deposits, plan_verify / bio / cost chips, dual-bus honesty — without embedding a PTY grid (Enter still hands off to herd attach). Headless observers use the same ObservabilitySnapshot via castellan statusline refresh or ~/.config/castellan/statusline.json.
Launch
castellan multiplexer ensure
castellan dashboard
Defaults:
| Setting | Default | Override |
|---|---|---|
| Socket | ~/.config/castellan/castellan.sock | --socket <PATH> |
| Episodes | .castellan/episodes | --episodes <PATH> |
| Archive | .castellan/topology_archive.json | --archive <PATH> |
Anatomy
The dashboard renders four coordinated views over one DashboardState, refreshed on demand:
| Pane | Shows | Source |
|---|---|---|
| Agent list | Pane id, agent name, status (idle/working/blocked/done/unknown) | agent.list over the multiplexer socket |
| Pressure strip | Episode vitals and live deposit heat (live_pressure) | Episodes + EventBus deposit / wake intensity |
| Genome ticker | Active genome id, generation, lineage depth | .castellan/topology_archive.json |
| Footer chips | socket/events/panes, plan_verify, bio, Φ, cost | Dual-bus honesty + castellan-events |
| Live events | Recent Castellan events (last_events, cap 16) | Socket EventBus — castellan run / ACP via events.emit when healthy |
| Attach | External PTY for selected pane | Enter → herd attach (no in-TUI multi-pane grid) |
Keybindings
| Key | Action |
|---|---|
j / k or ↓ / ↑ | Select agent up/down |
Enter | Attach to selected pane (Ctrl+Q to detach) |
v | Toggle vitals strip |
r | Refresh agents + layout snapshot |
q / Esc | Quit |
Recipes
Daily-driver stack:
castellan multiplexer ensure
castellan dashboard
Point at a named session (multi-project):
castellan herd session list
castellan dashboard --socket ~/.config/castellan/<session>.sock
Headless history (telemetry DB, no TUI):
castellan dashboard --history --limit 20
# same as:
castellan telemetry --limit 20
Headless live snapshot (no ratatui):
castellan statusline refresh --json | jq '{schema_version, bus, live_pressure, plan_verify, bio}'
Read a previously written file:
jq '{schema_version, connected, agents, vitals}' ~/.config/castellan/statusline.json
Headless observability
TUI and statusline refresh write the same ObservabilitySnapshot — schema in Statusline. MCP castellan_multiplexer_status adds freshness (stale, age_secs).
Honest gap: Full multiplexer chrome in the ratatui dashboard is still deferred; the current surface is agents, pressure, and pane tree.
Failure paths
| Symptom | Cause | Fix |
|---|---|---|
| “connection refused” on launch | No multiplexer server running | castellan multiplexer ensure before castellan dashboard |
| Agent list empty | No panes spawned yet | Start an agent pane first (castellan herd attach or spawn via socket API) |
| Vitals strip blank | No episode has run yet | castellan run --goal "..." --plugin gridworld at least once |
last_events empty while a run is active | Mux socket unhealthy, or run used --no-mux / private-only path | castellan multiplexer ensure; confirm doctor mux_default mentions socket EventBus; drop --no-mux |
| Genome ticker blank | Archive missing or empty | castellan evolve --episodes 10 to populate .castellan/topology_archive.json |
| Attach hangs on Ctrl+Q | Terminal emulator swallowing the escape sequence | Detach with q from the agent list view instead |
CI smoke
Dashboard client code is tested against a mock Unix socket:
cargo test -p castellan-dashboard --test integration
Included in ./scripts/verify.sh.