Status: Design pre-work only. This document introduces no code, no schema
change, and no plan-of-record decision. It is the deliverable proposed by
corpus-audit-2026-07-06.md §9.5 (the first UX/UI senior-lens review) as
WP-UX0, dependency-ordered before WP-U5 in the Phase-4 UI track. Per
CD-8 no scaffolding happens until Gate A is signed and WP-S7 reads GO;
accordingly this file contains ASCII wireframes only — no React/TS/CSS.
As built (note added 2026-08-15). The CD-8 hold was overridden by the owner on 2026-07-11 and the SPA now exists, so this document has stopped being a proposal and become the reference the implementation is checked against. It is not rewritten to match the code — a design intent that silently re-forms around whatever shipped can never catch a divergence — so read the wireframes as the target and this box as the delta.
What landed as designed: the token gate (
App.tsxrendersTokenScreenand nothing else until a token is in memory, and a 401 from inside the shell clears it); the four v1.0 views (LiveView,SessionsView,DagView,CostView, plus aSessionCostAnalysisdrill-down); the always-visible uncertainty legend in the persistent chrome, generated from the status vocabulary itself so a new state cannot appear on screen without appearing in the legend;unknownas a first-class rendered state, kept distinct from a null persisted status; and solid-versus-dashed edge provenance in the DAG, whose inline legend names all five sources includinglegacy_explore. §4’s honesty language is the part of this document that survived contact with code most intact.What is not yet true: “<30s at-a-glance” has never been measured. It is written here as a design target and is quoted as a Phase-4 exit gate, but no one has timed a human answering a question with this UI — the gate is neither passed nor failed, it is untested, and it should not be reported as met. Relative-time labels also still freeze on an idle tab (impl-review M-10, acknowledged in
CostView.tsx), which quietly undercuts the “live” half of the status board’s promise. The delegation-savings figure exists per session; an aggregate savings number of the kind §2’s Q4 flow implies was not verified to exist.
Why this exists (the gap it fills). Across the ~70-file corpus there were
zero wireframes, zero user flows, zero information architecture, and zero visual
language (corpus-audit §9.5). The project’s actual UX thinking survived only in a
git-excluded *.docx and was catalogued as lost content LOST-6
(corpus-audit §4.3): EXPANDED §15 — the 7-screen UX model + the honest-uncertainty
principle + PERF-01. This document recovers LOST-6 faithfully from
due-diligence/agenthropic_ideen_doklad_gap_holistic_implementation_EXPANDED.docx
and turns it into buildable design pre-work for the four v1.0 views.
Sources cited throughout:
'unknown' missing from the agents.status CHECK
constraint; the UI depends on it existing (§4, §5).implementation-plan.md §D3) — the five daily questions, verbatim (§2).development-plan.md — the Phase-4 WP list WP-U5…U9 and their Done-when.phase0-probe.md — empirical scale reality (sparse-DAG numbers, §3, §4).Extracted from the EXPANDED docx via textutil -convert txt. Reproduced faithfully;
the docx prose is bilingual, so the “Must answer” column is translated to English
without altering meaning.
| Screen | Purpose | Must answer |
|---|---|---|
| Home / Sessions | Current and recent runs | What is running now? What is broken? What is expensive? |
| Session detail | One session flight recorder | Which agents took part, and in what order? |
| Agent tree | Hierarchy visualization | Which agent started whom? Where is the bottleneck? |
| Event stream | Forensic timeline | What exactly happened, and when? |
| Cost panel | Token/cost intelligence | Who spends tokens, and on which model? |
| Alerts | Operational attention | What requires intervention? |
| Settings | Safe local config | What are the security, retention and alert settings? |
UX should not hide uncertainty. If a parent/child relation is inferred with low confidence, the UI must mark it. If a cost is estimated because pricing is missing, the UI must show it. Better honest uncertainty than confident nonsense.
Reinforced by two other recovered items:
SubagentStop before SubagentStart → raw stored; normalized anomaly flagged;
UI shows an uncertain edge.The §15 model predates two later decisions and must be reconciled, not copied:
development-plan.md — v1.0 =
DAG + cost cockpit answering the five daily questions, no alerts). So the
§15 Alerts screen is out of v1.0.WP-U8) — the moat (DESIGN §2.1) — which the §15 model has no screen
for. This document adds it as a first-class v1.0 view and marks it as a
deliberate extension of the recovered model.| §15 screen | v1.0 fate | v1.0 view (WP) |
|---|---|---|
| Home / Sessions | v1.0 | (a) Live status board — WP-U6 |
| Agent tree | v1.0 | (b) Session-scoped subagent tree — WP-U7 |
| (new — not in §15) | v1.0 | (c) Global persistent DAG — WP-U8 |
| Cost panel | v1.0 | (d) Cost / Sankey / delegation-savings — WP-U9 |
| Session detail | thin in v1.0 | folds into (b) as an agent drill-down panel |
| Event stream | post-1.0 | forensic drill-down only in v1.0 |
| Alerts | post-1.0 | cut from v1.0 per best-path §6.1 |
| Settings | minimal / post-1.0 | token gate + range toggles only in v1.0 |
The SPA is a single loopback-only, token-gated, SSE-live surface (DESIGN §8;
WP-U5). It renders nothing until it has proven possession of the mandatory
DASHBOARD_TOKEN. Every view is a read-only projection over data already in
SQLite — the session tree and the global DAG are queries over the persisted
orchestration_edges table, never a client-side walk of the event log
(DESIGN §6; WP-U3/WP-U8 Done-when).
agenthropic SPA (127.0.0.1 · DASHBOARD_TOKEN gate · SSE live · host = mac-mini-m4)
│
│ Persistent chrome on every view:
│ • SSE connection indicator (● live / ○ reconnecting — WP-U5 "resilient")
│ • host_id / instance label (per-instance is a moat invariant — DESIGN §2.1)
│ • ALWAYS-VISIBLE uncertainty legend (see §4) ← honest-uncertainty, LOST-6
│ • time-range toggle (today / this week / all)
│
├─ (a) LIVE STATUS BOARD ............. WP-U6 [v1.0 · DEFAULT/HOME] §15 "Home/Sessions"
│ working / unknown / done · <30s at-a-glance
│ └─(row click)─▶ (b) Session subagent tree
│
├─ (b) SESSION SUBAGENT TREE ......... WP-U7 [v1.0] §15 "Agent tree"+"Session detail"
│ one session, parent→child, D3 force+tree, live
│ ├─(node click)─▶ Agent drill-down panel (tokens, status, raw events) ← §15 "Session detail" (thin)
│ └─(link)─▶ (d) Cost view filtered to this session
│
├─ (c) GLOBAL PERSISTENT DAG ......... WP-U8 [v1.0 · THE MOAT] (added — not in §15)
│ spans every session for this instance · per-instance · persisted edges
│ └─(node click)─▶ (b) Session tree for that session
│
├─ (d) COST / SANKEY / SAVINGS ....... WP-U9 [v1.0] §15 "Cost panel"
│ token flow + $ + delegation-savings
│ └─(flow/row click)─▶ (b) Session tree / agent that spent it
│
├┄ Event stream (forensic) .......... [post-1.0] §15 "Event stream"
│ v1.0 exposes it only as the agent drill-down in (b)
├┄ Alerts ........................... [post-1.0 — cut, best-path §6.1] §15 "Alerts"
└┄ Settings ......................... [minimal/post-1.0] §15 "Settings"
Navigation invariant: the four v1.0 views form a hub-and-spoke around the status board (the home/default). Every deep view has a one-click path back to the board and cross-links to the cost view — so no daily question ever needs more than two clicks from cold start (§2).
The five daily questions are the v1.0 exit gate (best-path §6.1; Phase-4 exit in
development-plan.md: all five answerable + time-to-understand a session <30s).
Recorded verbatim as D3 in implementation-plan.md:
Q1 What is the subagent tree of this session, and which branch is still running? Q2 Which agent/subagent burned the most tokens (and roughly what did it cost)? Q3 Did any session get stuck / error without me noticing? Q4 What did today/this week cost, and how much did Haiku/Sonnet routing save? Q5 Show me last night’s sessions — persisted, after a restart.
Each flow below states: entry screen · above-the-fold answer · click budget · how the <30s target is met.
Home board ──click a RUNNING row──▶ (b) Session subagent tree
orchestration_edges (already persisted) so first-paint needs no
reconstruction (WP-U3/WP-U7).Home board ──click [Cost] tab──▶ (d) Cost/Sankey ──read "TOP BURNERS" list──▶ answer
(alt) (b) tree ──"cost for this session"──▶ (d) filtered
$); the widest Sankey band is the same agent, read
visually.$ is
tokens × dated price (no client math).(open app) ──▶ (a) Live status board [ default view — 0 clicks ]
▲ unknown (watchdog) and ✕ error agent. If the band is empty, nothing is
stuck — answered at a glance.WP-U6 is measured against — “a newly-stuck agent
flips to unknown live via SSE within the window.” The whole board is designed so
the abnormal states draw the eye first (§4).Home board ──click [Cost] tab──▶ (d) Cost/Sankey ──read KPI header──▶ answer
Σ max(0, top-tier-equiv − actual) (WP-C5), computed server-side.Home board ──scroll to RECENT / set range = "today"──▶ persisted session list
$.sessions/agents rows, not a
live-only in-memory buffer — so it is identical before and after a server restart
(the explicit point of Q5; WP-U6 reads the same persisted tables).Flow-to-view coverage matrix
| Question | Primary view | Secondary |
|---|---|---|
| Q1 tree + running branch | (b) Session tree | (a) status colors |
| Q2 biggest burner | (d) Cost/Sankey | (b) per-session |
| Q3 stuck/error | (a) Status board (default) | — |
| Q4 today/week cost + savings | (d) Cost/Sankey | — |
| Q5 last night, persisted | (a) Status board list | SQLite WAL |
All four wireframes bake in the honest-uncertainty language of §4. Each carries a
data: footer stating the source-of-truth invariant it must honor. Legend:
● working · ▲ UNKNOWN · ✓ done · ✕ error — — solid = observed edge · ┄ dashed =
inferred edge.
WP-U6 — the <30s at-a-glance┌────────────────────────────────────────────────────────────────────────────┐
│ agenthropic ● live(SSE) host: mac-mini-m4 [ Status ] Tree DAG Cost │
│ Legend: ● working ▲ UNKNOWN ✓ done ✕ error — observed ┄ inferred ~ est. $ │
├────────────────────────────────────────────────────────────────────────────┤
│ ⚠ ATTENTION (sorted first — answers Q3 at a glance) │
│ ▲ 9f3a "refactor-auth" agent Explore#3 UNKNOWN no Stop · 4m12s ▸ │
│ ✕ 12bd "docs-sweep" agent main ERROR exit 1 ▸ │
│ ────────────────────────────────────────────────────────────────────────── │
│ ● RUNNING │
│ ● a071 "build-plan" 3 agents working ▸ tree │
│ ● 55e2 "kiko-digest" main only │
│ ────────────────────────────────────────────────────────────────────────── │
│ ✓ RECENT — persisted · survives restart (answers Q5) [ range: today ▾ ] │
│ ✓ 7c10 "snake-skins" 12 agents done 02:14 $0.0431 │
│ ✓ 3ff9 "tetris-ci" main only done 01:02 <$0.01 │
│ ✓ e5a8 "body-psy" main only done 00:41 $0.0088 │
└────────────────────────────────────────────────────────────────────────────┘
data: reads persisted agents.status (incl. 'unknown' — OPEN-2 §5) + SSE deltas;
no render-time inference. $ = ground-truth tokens × dated price.
Empty/first-run state (no sessions yet — §9.5 gap #5): the board shows a single neutral panel “No sessions recorded yet on this host. Run a Claude Code session; it will appear here.” — never a blank screen or a fake row.
WP-U7┌────────────────────────────────────────────────────────────────────────────┐
│ Session 9f3a "refactor-auth" started 14:02 ● live [ → cost: sess ] │
│ Legend: — observed edge ┄ inferred edge(~conf) ▲ unknown ● working │
├────────────────────────────────────────────────────────────────────────────┤
│ │
│ ● main (Opus) │
│ ├── ● Explore#1 (Sonnet) 1.2M tok $0.41 │
│ ├── ▲ Explore#3 (Sonnet) 0.4M tok $0.14 UNKNOWN · no Stop [details] │ ← amber node
│ │ └┄┄~ Grep#7 (Haiku) 12k tok <$0.01 ┄ inferred edge ~78% [why?] │ ← dashed depth-2
│ └── ✓ Workflow wf_22 │
│ ├── ✓ agent-a1 0.8M tok $0.27 │
│ └── ✓ agent-b4 0.6M tok $0.19 │
│ │
│ ┌── Common case — 72% of sessions (phase0-probe: 84/117 have 0 subagents)─┐│
│ │ ✓ main (Opus) 4.1M tok $1.38 — no subagents spawned ││
│ └────────────────────────────────────────────────────────────────────────┘│
└────────────────────────────────────────────────────────────────────────────┘
data: tree = query over persisted orchestration_edges (WP-U3), NOT a client
walk of the event log. Edge style comes from a persisted edge-provenance
field (§4/§5). Tokens copied verbatim from JSONL; $ = tokens × dated price.
[why?] on an inferred edge opens the raw drill-down (R-10 mitigation): it shows
what the edge was derived from (derived_from_event_id) and the confidence score.
The common 72% case is drawn deliberately (§9.5 gap #2 — design the sparse/empty
state, not just the dense showcase).
WP-U8 — the moat┌────────────────────────────────────────────────────────────────────────────┐
│ Global orchestration DAG — host mac-mini-m4 · ALL sessions [ range: 7d ▾ ]│
│ Legend: — observed ┄ inferred ● working ▲ unknown ✓ done 1 node=1 agent │
├────────────────────────────────────────────────────────────────────────────┤
│ a071 ─● main ─┬─● Explore │
│ └─✓ Workflow ─┬─✓ agent (all edges persisted) │
│ └─✓ agent │
│ 9f3a ─● main ─┬─● Explore │
│ └─▲ Explore ┄┄~ Grep ┄ inferred ~78% │
│ 7c10 ─✓ main ─… (12 agents, collapsed for perf) [ expand ] │ ← virtualization
│ ────────────────────────────────────────────────────────────────────────── │
│ ▸ 84 / 117 sessions have NO subagents — shown as flat roots [ show ] │ ← sparse case
└────────────────────────────────────────────────────────────────────────────┘
data: query over orchestration_edges WHERE host_id = … with NO session filter
(WP-U8). Per-instance: one node = one real agent run, NEVER type-aggregated
(contrast hoangsonww's 3–4-layer type diagram — DESIGN §6).
perf: NFR-PERF-01 (500+ events / 50+ agents) → collapse + virtualize + filter;
R-06 "UI graph performance collapse" mitigation. First-paint = collapsed.
Because 72% of sessions are flat, the default frame collapses subagent-free sessions into a roster and expands only the graph-bearing ones — the graph is the exception, not the rule (phase0-probe §Q, §9.5 gap #2).
WP-U9┌────────────────────────────────────────────────────────────────────────────┐
│ Cost / Sankey / delegation-savings [ today ▾ ] [ this week ] │
├────────────────────────────────────────────────────────────────────────────┤
│ Today $2.4187 This week $18.66 Delegation saved $6.12 │ ← Q4 KPIs, above fold
│ every $ = ground-truth tokens × dated price · never inferred │
│ ────────────────────────────────────────────────────────────────────────── │
│ TOKEN FLOW (band width ∝ tokens) TOP BURNERS (answers Q2) │
│ Opus ████████████████ 6.1M $1.41 1. main / 9f3a 6.1M $1.41 │
│ Sonnet ████████ 3.0M $0.62 2. wf_22 / a071 2.2M $0.54 │
│ Haiku ██ 0.4M $0.0312 3. Explore#1 1.2M $0.41 │
│ new-model-x ▒▒ 0.2M ~est ⚠ price unknown 4. Grep#7 12k <$0.01 │ ← estimated chip
│ ────────────────────────────────────────────────────────────────────────── │
│ Delegation savings = Σ max(0, top-tier-equiv − actual) = $6.12 (Q4, WP-C5) │
│ (Haiku/Sonnet re-priced at Opus rates; tied to the routing decision) │
└────────────────────────────────────────────────────────────────────────────┘
data: CostEngine = token_usage (ground truth, verbatim from JSONL) × model_pricing
(dated, versioned). An unpriced model in a FIXTURE = red build (WP-C6);
at RUNTIME a brand-new model shows "~est ⚠" with tokens still displayed —
NEVER a silent $0 (honest-uncertainty, LOST-6). <$0.01 shown, never $0.00.
This is the direct build-out of LOST-6’s honest-uncertainty principle and §9.5’s gap #1: “inferred/estimated is always visible, never silent” is a design system, not a footnote. Three dimensions must always be visibly distinguished; a fourth row records the invariants they must not violate.
| Dimension | Ground-truth / observed encoding | Uncertain encoding | Rule |
|---|---|---|---|
| Edge provenance (tree §b, DAG §c) | solid line —, full opacity, no badge |
dashed line ┄ + ~conf% chip + [why?] drill-down |
An edge from the hard join (Agent/Workflow spawn → child sessionId → parent ref, phase0-probe §Q) is observed; an edge from the self-referential parent index / orphan-reparent heuristic is inferred. Never render an inferred edge identically to an observed one. |
Cost (cost §d, tree/DAG node $) |
plain figure, e.g. $0.0431 |
~est ⚠ chip; tokens still shown; <$0.01 for non-zero sub-cent |
If a model/bucket has no priced row at runtime, mark the cost estimated — never a silent $0.00. Tokens are ground truth and are always shown even when the price can’t be resolved. |
| Agent status (all views) | ● working (blue) · ✓ done (green) · ✕ error (red) · waiting (grey) |
▲ unknown (amber hazard) — the watchdog state |
unknown = a missing SubagentStop inside the watchdog window (WP-IN12), never a permanent “working.” It sorts to the top of the board and draws the eye first — it is exactly the “stuck without me noticing” case of Q3. |
| Tokens (invariant, not a badge) | ground truth, no decoration | absent count → — / pending, never 0 |
Tokens are read from JSONL, never inferred (DESIGN §4). A genuinely-absent count is shown as pending, not zeroed. |
Cross-cutting rules:
[why?] → the derived_from_event_id and confidence; an
estimated cost exposes which bucket lacked a price; an unknown node exposes the
last observed event and the watchdog deadline.SubagentStop-before-SubagentStart
contradiction renders the edge as uncertain, it does not drop or fabricate it.The visual language cannot be built from the current schema — the distinctions it draws must exist as data before the UI can render them. Per §9.5 gap #1 these belong before Phase 4, not inside it. UX0 does not decide them (owned elsewhere); it flags the dependency:
'unknown' must be added to the agents.status CHECK constraint — this is
OPEN-2 (corpus-audit §4.2): the reference DDL allows
('working','waiting','completed','error') but WP-IN12’s watchdog assigns
'unknown', and the status board (§3a) and every node badge (§4) depend on that
value existing and persisting. Owned by WP-D4’s migration DDL; flagged here as a
hard UI dependency. Also open: the documented unknown → revert rule
(concept-analysis-v2 §7 q5) — the UI must know whether unknown can flip back to
working/done when a late Stop arrives.orchestration_edges — the observed-vs-inferred
distinction (§4, dimension 1) requires a persisted marker (a confidence and/or
derived_from/derived_from_event_id column). §9.5 states this feeds back into
the schema; it must be present when WP-D7 defines the table, or the inferred/
observed rendering has no column to read.These three are the concrete “invisible design debt” §9.5 warns Phase 4 would
otherwise start with: without them, the <30s target and the honest-uncertainty
principle have no data to stand on.
Consistent with design pre-work (not a decision):
WP-U5/WP-U6 implementation
choice.WP-U5) — named as a
requirement, not specified here.Design pre-work for WP-UX0. Recovers LOST-6 (corpus-audit §4.3 / EXPANDED §15) and
implements the recommendation of corpus-audit §9.5. No code, no schema change, no
plan-of-record decision — ASCII wireframes only, per CD-8. Feeds §5’s three
dependencies back to WP-D4/WP-D7 and the plan of record for decision by their
owners; introduces WP-UX0 as design-only, dependency-ordered before WP-U5.