Skip to content

Web Desktop Workbench

coo1white edited this page Jun 8, 2026 · 2 revisions

Web / Desktop Workbench (v0.1.30)

A read-only, localhost-only human console that renders a run's five operator surfaces over existing capability payloads — a THIRD front door, not a new brain. Shipped in v0.1.30. Repo doc: docs/web-desktop-workbench.7.md.

CW v0.1.30 adds the Web / Desktop Workbench: a human-facing console that renders a run's five operator surfaces — run graph, blackboard, worker logs, candidate compare, audit timeline — plus a cross-run entry point over the v0.1.28 Run Registry. Before v0.1.30, CW had no web/HTTP/UI surface at all: the CLI rendered for human speed, the MCP server (JSON-RPC over stdio) rendered for machine context. The Workbench adds human inspection at a glance — and adds NOTHING else.

Design Mantra

A third front door, not a new brain.
The data IS the files.
No hidden dashboard database.
Localhost only, read only, GET only.
Byte-for-byte equal to its --json payload.
Fail closed when source state is unreadable.

The Borrowed Idea: Mechanism vs Policy (one mechanism, three renderings)

The kernel and the durable .cw/ state are the MECHANISM. The CLI, the MCP surface, and the Workbench are three renderings — three policies — over that one mechanism. The per-run .cw/runs/<id>/state.json is the SINGLE source of truth; the v0.1.28 Run Registry is a DERIVED, rebuildable index over runs across repos; the Workbench is a STATELESS, READ-ONLY RENDERER over both.

.cw/ durable state  ->  capability core entry  ->  canonical --json payload  ->  Workbench panel (verbatim)

Every panel embeds, VERBATIM, the canonical --json payload of ONE already-declared capability, assembled by calling the SAME capability core entries the CLI and MCP route through (the v0.1.27 parity contract). A workbench.view panel is byte-for-byte equal to its underlying cw <cmd> --json payload, and that equality is parity-gated. The Workbench can show nothing the CLI or MCP cannot.

1. A third front door, not a new brain

The Workbench computes, decides, and stores nothing the CLI/MCP cannot already produce. The kernel imports the Workbench never; the Workbench imports the kernel. It is OPTIONAL, like Bun is an optional execution backend: the committed dist/ and a plain node runtime keep working with the Workbench (and its static UI assets under ui/workbench/) absent.

2. No hidden dashboard database

CW's README promises there is "no hidden dashboard database." The Workbench upholds that promise by holding ZERO authoritative state: it persists nothing — no Workbench store, cache, or schema; every response is re-derived on demand from disk, and refresh re-reads .cw/; delete the host process and nothing is lost — the data IS the files. It forks no run/state schema. The view models in src/types.ts (WorkbenchRunView, WorkbenchPanel, WorkbenchServeDescriptor) are DERIVED projections that embed existing payloads, never copies of them.

3. The five panels

Each panel renders existing operator vocabulary, with the same names and semantics as the CLI (least astonishment). For run <id>:

  1. RUN GRAPHcw graph <id> --json plus cw multi-agent graph <id> [--view compact|critical-path] --json. Backend ids/attestations (v0.1.29) ride on the nodes; the critical path, failures, missing evidence, and policy violations are never collapsed.
  2. BLACKBOARDcw coordinator summary <id>, cw blackboard summarize <id> --json, cw blackboard graph <id>: topics, messages, contexts, artifacts, snapshots, decisions, conflicts, and adopted/missing evidence.
  3. WORKER LOGScw worker summary <id> --json: manifests, outputs, scoped results, failures, and the recorded execution backend + sandbox attestation.
  4. CANDIDATE COMPAREcw candidate summary <id> --json plus cw multi-agent reasoning <id> --json: scores, selection, rejection reasons, and the v0.1.26 evidence-adoption reasoning chain (why adopted).
  5. AUDIT TIMELINEcw audit summary <id>, cw audit multi-agent <id> --json, cw audit policy <id> --json, cw audit judge <id> --json: trust-audit events, role policy decisions, provenance, judge/chair rationale, and policy violations.

Cross-run entry lists/searches runs via the Run Registry (cw registry show --json + cw run list|search --json); drilling into a run opens its five panels.

4. Explicit, inspectable, fail closed

When a source capability is unreadable (a run with no blackboard yet, or unresolvable state), the panel is rendered absent with the honest error — exactly what the CLI would report — and the view is resolved: false. It never fabricates a view when source state is unreadable. The same valid/stale/absent/missing freshness the runtime already records (Run Registry, evidence-adoption reasoning chain, state-explosion summaries) flows through verbatim.

5. Trust boundary — least-privilege, local by default

The host binds the loopback interface 127.0.0.1 ONLY — never a public address. It is READ-ONLY: every route is GET; any write verb is refused 405. It rejects non-localhost Host headers (a DNS-rebinding defense) with 403, refuses path traversal out of ui/workbench/ with 403, serves nothing beyond the current user's .cw/ scope and the Run Registry's registered repos, and fails closed on anything it cannot read. The console offers no actions. If a future release adds one (resume, rerun, dispatch), it MUST route through an existing declared capability core entry — never a parallel code path — so it cannot drift from the CLI/MCP and is covered by the parity gate.

Surfaces

cw workbench view <run-id> [--json]                          # five-panel WorkbenchRunView for one run
cw workbench serve [--port N] [--scope repo|home] [--once|--json]

cw workbench serve with --once/--json prints the serve descriptor (bind host/port, scope, routes) and exits without starting a server; the default starts the localhost host (like schedule daemon). The MCP tools cw_workbench_view and cw_workbench_serve mirror these: cw_workbench_view returns the same view as the CLI --json; cw_workbench_serve returns the descriptor only — an MCP stdio host cannot start a blocking server. That single side-effect difference is the declared, documented payload divergence recorded in src/capability-registry.ts; the descriptor payload itself is identical across surfaces.

The read-only HTTP routes the host serves:

GET /                  # static UI shell (dependency-light; absent -> JSON-only fallback)
GET /ui/*              # static UI assets, read from disk
GET /api/index         # registry show + run list/search (cross-run entry)
GET /api/serve         # the serve descriptor
GET /api/run/:runId    # the five-panel WorkbenchRunView

Why It Matters

A human can now inspect a run at a glance — graph, blackboard, logs, candidate compare, audit timeline — without that convenience minting a second source of truth. Because every panel is byte-for-byte its --json payload and the host is stateless, the README's "no hidden dashboard database" promise holds: the data is still the files, the CLI and MCP stay authoritative, and the localhost/read-only/GET-only boundary keeps an inspection console from becoming an attack surface or a config-drift trap. The Workbench changes no run-state schema and requires no migration; removing it leaves the SDK fully functional.

See Also

Clone this wiki locally