Session Dash Panel Design¶
Auto-generated single-page control panel that tracks agent session task progress and result statistics from LoopX public-safe projections.
Problem¶
Operators want a compact, copyable web view of what the fleet is doing right now: which sessions (agent runtimes) exist, how many goals each owns, and what state each goal is in. The existing React dashboard covers this interactively, but it requires a Node build, a dev server, and browser tooling. A loopback single-page panel is a lighter surface for quick local inspection: run one command from the project directory and keep the tab open while the agents work.
The panel is intentionally human-focused. LoopX's internal control machinery (decision frames, work-lane contracts, quota slot math, truth contracts, source-warning diagnostics, lease/write-scope bookkeeping) is not rendered: it is noise to an operator and belongs to the control plane, not the watch surface. The page shows only the signal that answers "how is the work going?":
- Overview — sessions, goals, active / needs-you / blocked / done buckets, open todos, and run counts (the result statistics).
- Sessions — one card per session, with its state, role, goal count, and the goals it owns.
- Per goal — status badge, todo progress bar (done vs open agent/user), what it is waiting on, latest run time/classification, and next action.
Decision¶
Add a live single-page panel (loopx dash) that serves the fleet snapshot
from existing public-safe projections:
- Collect the same inputs the dashboard already consumes: the status contract
(
attention_queue.items[]),run_history.goals[], the todo index, the agent-management projection (sessions + theirgoal_ids), and the usage summary. - Fold them through a read-only fleet projection
(
build_session_dash_projection, schemasession_dash_projection_v1) that groups goals under sessions and computes the overview buckets. - Render a single HTML page with a small no-dependency renderer, reusing the
patterns in
loopx/presentation/renderers/goal_channel_html.py. - Serve it from a loopback HTTP server (
loopx/dash_server.py) that also exposes a/panelfragment and/status.jsonprojection; the page auto-refreshes in place by polling/panel. - Keep
loopx dash generatefor a one-shot static HTML snapshot, with the existing public/private boundary scan enforced before success.
The React dashboard stays the interactive surface; the loopback panel is the fast watch surface. They share the same projections and data contract, so the panel cannot drift into a second source of truth.
Repository Placement¶
| Concern | Location | Reason |
|---|---|---|
| Renderer | loopx/presentation/renderers/session_dash_html.py |
Pure renderer over already-built payloads, per the presentation surface layout. |
| Projection assembly | loopx/presentation/projections/session_dash.py |
Intermediate public-safe read model (fleet snapshot). Reuse existing builders when possible; do not duplicate contract parsing. |
| Generation command | loopx/cli_commands/dash.py + loopx/dash_server.py |
Operator-facing CLI entry (loopx dash serves, dash generate exports); reads status/quota/todos exactly like serve-status does. |
| Static export | Reuse the boundary scan + loopx dash generate |
Existing public/private scanner; manifest/revision receipt stays with the static-site pipeline when needed. |
| Docs | docs/product/surfaces/ + dashboard README |
Same documentation home as other presentation surfaces. |
| Validation | examples/session-dash-panel-smoke.py |
Public-safe fixture smoke, no live state required. |
This is a presentation surface, not a new capability: it does not own state, quota, gates, or authority. Per the capability placement guide, it stays in the presentation layer and reuses existing control-plane contracts.
Data Contract (Inputs)¶
The projection consumes only public-safe projections:
loopx statusJSON, schema_version 2:attention_queue.items[](per-goal waiting_on / recommended_action),run_history.goals[](goal status, lifecycle phase, latest runs),todo_index.items[](per-goal role/status),agent_management_projection.agents[](sessions: state, role,goal_ids, next action, last activity), andusage_summary.totals(runs 24h/7d).- Public-safe evidence pointers only; never raw transcripts, logs, credentials, or local paths.
Raw-looking keys found in inputs are recorded as boundary warnings without
copying values, matching goal_channel_projection behavior.
Projection Shape¶
schema_version: session_dash_projection_v1, mode: read_only:
overview— session/goal/run counts,goals_by_statusbuckets (active / needs_user / blocked / done / other), open agent/user todos, done todos, runs 24h/7d.sessions[]— one entry per agent runtime:session_id,role,state,next_action,last_activity_at,goal_count, andgoals[].goals[]—goal_id,display_name,domain,status,status_bucket,waiting_on, open/done todo counts, latest run time + classification, andnext_action.unassigned_goals[]— goals no session declares, so nothing silently disappears from the operator's view.focus_goal_id— when--goal-idis passed, the snapshot narrows to sessions containing that goal.
Page Layout (Single Page)¶
The single page renders these sections in order:
- Header: panel title, generated-at time, read-only marker; a focus pill
when
--goal-idis set. - Overview strip: sessions, goals, active, needs-you, blocked, done, open todos, runs (24h).
- Session cards: per session, its state badge, role, goal count, last activity, and next action; below it, a goal table with status badges, todo progress bars, waiting reason, latest run, and next action.
- Goals without a session (when present): same goal table for goals no session claims.
All data is rendered from the projections above; the page contains no write controls and no browser write authority.
Command Surface¶
The primary entry point is a live server: run loopx dash inside a project
checkout and open the printed loopback URL in a browser. The single page
tracks the fleet's session task progress/status and refreshes itself in place
(default every 10s) by re-fetching the /panel fragment, so the operator can
keep the tab open while the agents work.
loopx dash # serve the fleet panel at http://127.0.0.1:8767/
loopx dash --goal-id <id> # narrow the panel to one goal
loopx dash --port 9000 --refresh-seconds 5
Routes:
GET /— full single-page panel with the in-place auto-refresh script.GET /panel— fresh<main>fragment for the refresh script.GET /status.json— the compact session dash projection as JSON.GET /healthz— health probe.
A one-shot static snapshot remains available:
- Without
--out, print the HTML to stdout (or use--format jsonfor the projection + html payload). - With
--out, write the file and run the public boundary scan before reporting success. - The command is read-only: it never mutates todos, quota, gates, or registry.
- The server binds loopback only (
127.0.0.1); it exposes no write routes.
Public/Private Boundary¶
- Inputs are restricted to the status contract and public-safe projections.
- The renderer escapes all text and never inlines raw payload values.
- Static export reuses the existing boundary scanner (absolute local paths, private keys, credentials, tokens) before success.
- A negative fixture proves the generated page rejects private material; the smoke asserts the boundary, not the exact prose.
Validation¶
examples/session-dash-panel-smoke.py (Python, no browser required):
- Builds a public-safe fleet fixture (two goals, one session owning a second goal with finished todos).
- Renders the page and asserts read-only markers, the overview + session
panels, session -> goal grouping, progress bars, escaped output, the live
refresh script, and the
/panelfragment shape. - Asserts internal machinery (decision frame, work lane, truth contract, source warnings, leases) is absent from the page.
- Injects synthetic private markers (
GH_FAKE_*style) and asserts they stay out of the rendered page / static export.
Out Of Scope (For Now)¶
- Browser write controls: the dashboard remains the only surface that may submit reward/control-plane drafts, and only through explicit loopback capability gates.
- New capability or provider: none. This is a renderer + CLI presentation surface over existing contracts.
- Goal-level drill-down inside the fleet panel: the per-goal channel details remain on the React dashboard; the loopback panel is the at-a-glance watch surface.