Surface map
The two consoles, what each one owns, who uses them and how they are built.
Two separate applications on one design system, deliberately not merged.
| Customer console | Infra console | |
|---|---|---|
| Host | console.workspaces.build | ops.workspaces.build |
| Audience | Customer developers, operators, finance | Platform SRE and support |
| Scope | One organization's own data | The whole fleet, all organizations |
| Auth | OIDC, customer identity, RBAC | Platform SSO, hardware key required |
| Access to session contents | Full — it is their data | None without break-glass |
They are separate applications because the access model is fundamentally different. A single application with a role flag that unlocks cross-tenant data is one bug away from a cross-tenant leak.
Customer console
Overview spend today, active sessions, start-latency percentiles, recent failures Sessions live list, filters, inspect, terminal, desktop view, kill Runs history, output, timing, failures Templates list, build, publish, warm-pool pinning Storage volumes, snapshots, recordings, lifecycle rules Policies egress rules, CLI allowlist, tool allowlist, secrets Tools catalog, MCP server registration, confirmations queue End users list, usage per customer, quotas and caps per customer Usage & billing cost explorer, forecast, invoices, credits, spend caps Settings projects, API keys, webhooks, members and roles, SSO, residency Audit searchable, exportable
Detail: customer console.
Infra console
Fleet nodes by class and zone, health, drains, capacity headroom Pools depth vs target, hit ratio, refill latency, waste Placement decisions/s, failures by reason, "why did this cold start" Sessions cross-tenant list, metadata only, force-terminate Regions per-region health, egress volume, storage saturation Metering ingest lag, node WAL depth, dedupe rate, reconciliation results Images template build queue, scan results, distribution status Incidents active alerts, status-page control, SLO burn rate Organizations support view: plan, quotas, recent errors — never session contents Break-glass two-person approved, time-boxed, audited access to a session
Detail: infra console.
Platform operators can see that a session exists, its tier, its state, its resource use and its placement. They cannot see its filesystem, its logs, its screen or its network payloads. Reaching those requires break-glass: two-person approval, a stated reason, a time box, and an immutable audit entry the customer can read.
Shared design decisions
Live by default. Session lists, run output, pool depth and spend all stream. Polling UIs for a system whose whole value is sub-second starts would be an odd choice.
Every view is an API call you could have made. The console is a client of the public API, with no private endpoints. If something is visible in the console it is reachable programmatically — which keeps the API honest and the console from drifting ahead of it.
Cost is always present. Every session row carries its cost to date. Every list has a total. Spend is the number customers most often have to leave a dashboard to find, and that is a design failure worth fixing by default.
Destructive actions require typing the object name. Killing a session, deleting a volume, revoking a key. The confirmation dialog that only needs a click is the one people click through.
Dark mode is the default. The primary audience spends its day in terminals.
Technology
| Layer | Choice | Why |
|---|---|---|
| Framework | Astro with React islands | Mostly static shell, interactivity only where needed |
| Streaming | SSE for lists and metrics, WebSocket for terminals, WebRTC for desktop | Matches the API's own transports |
| Charts | Observable Plot | Small, declarative, good at dense time series |
| Terminal | xterm.js over the PTY WebSocket | |
| Desktop view | WebRTC, same signalling as the API | |
| State | TanStack Query with an SSE invalidation channel | Cache plus push, rather than polling |
| Design system | Shared package consumed by both consoles | One set of components, two applications |
Mobile
The customer console is responsive down to a phone for the read paths that matter when something is wrong: spend, active sessions, recent failures, incident status, and killing a runaway session.
Terminals, desktop views and template builds are desktop-only. A touch keyboard driving a remote PTY is not a feature worth shipping.