# lda.chat Workflow Console A local React console for inspecting workflow JSON-RPC servers. Connects to a loopback `wf-rpc-server` through a Hono proxy, displays capability and draft workspace reads, and keeps raw protocol evidence inspectable. ## Quick Start ```powershell # Terminal 1: workflow JSON-RPC server uv run wf-rpc-server --config wf.config.json --host 127.0.0.1 --port 8765 # Terminal 2: development (Vite + Hono) pnpm --dir web install pnpm --dir web dev ``` Open `http://127.0.0.1:5173/console/discover` in the browser. Paste the target URL: ```text http://127.0.0.1:8765/rpc ``` Click **Connect**. The console will: 1. Validate the target is a loopback address 2. Call `workflow.health` on the upstream server 3. Display the read-only capability catalog and preserve the connection while navigating the console routes 4. Show raw protocol evidence for each connection and workspace read ## Workflow Console Routes The root route and `/console` redirect to `/console/discover`. The routed workspace currently exposes: - `/console/discover` for searchable, source-filtered capability discovery and input/output contract inspection - `/console/drafts` for the persisted draft workspace index - `/console/drafts/:workspaceId` for the draft authoring workbench: a desktop capability palette, graph canvas, and context inspector with real draft mutations, revision/status diagnostics, and bounded raw-draft evidence - `/console/artifacts` and `/console/artifacts/:artifactId/:version` for the existing read-only artifact explorer - `/console/deployments` and `/console/deployments/:deploymentId` for deployment inspection - `/console/runs` and `/console/runs/:runId` for run, interrupt, and trace inspection Enter a loopback RPC URL in **Workflow JSON-RPC URL** and click **Connect**. The health exchange establishes the target for the routed shell; subsequent read-only route calls go through the Hono `/api/rpc` boundary. The target and the operation-evidence ledger persist across console route navigation. The draft workbench keeps the graph as the primary touch surface on mobile and opens the capability palette and context inspector as independently scrolling, accessible full-height sheets. Forms remain mounted while sheets are closed so dirty values and selection survive palette/inspector close and reopen cycles. ## Capability Playground The Discover route includes a generated **Try capability** form for direct capability smoke tests. Run the local services with loopback defaults: ```powershell # Terminal 1: workflow JSON-RPC server uv run wf-rpc-server --config wf.config.json --host 127.0.0.1 --port 8765 # Terminal 2: web console pnpm --dir web dev ``` Connect to `http://127.0.0.1:8765/rpc`, select `wf.std.concat`, acknowledge the side-effect warning, and submit `items: ["hello", "world"]` with `separator: " "`. A direct capability call executes immediately against the target. It is not a workflow run and creates no graph, state, route, run, or trace records. The acknowledgement is an accidental-action guard, not authentication or authorization; capabilities may still have side effects. `wf.source.read_resource` is a useful form-generation check. Its local JSON Schema `$ref` resolves into `logical_source`, `uri`, and the defaulted `kind` field instead of an unresolved reference blob. A node-spec direct call can still finish with a `runtime_error` when it requires workflow platform context. That completed receipt is truthful runtime behavior, not a failed form implementation; use a workflow deployment with the required platform context for the successful path. The evidence ledger retains the target, equivalent CLI, and bounded request and response values. It keeps at most 100 records, traverses to depth 8, retains at most 100 collection entries, limits strings to 4096 characters, and limits each retained request or response to 32 KiB serialized. Sensitive keys such as `authorization`, `cookie`, `token`, `secret`, `password`, and `api_key` are redacted before evidence enters the console state. ## Production Build ```powershell pnpm --dir web build pnpm --dir web start ``` A single Hono process serves the built React application and API routes from `http://127.0.0.1:8787`. ### LAN Presentation Rehearsal Build once, then bind the production Hono server to the laptop's LAN interfaces: ```powershell pnpm --dir web build $env:WEB_HOST = "0.0.0.0" pnpm --dir web start ``` Open `http://:8787/presenter` on the phone and `http://:8787/present` on the audience display. Either route can **Start session** or **Join session**. Starting shows a six-character code, QR target, and opposite-route join link; the other device can scan the QR, open the link, or enter the code. Navigation is bidirectional, and the presenter route can end the session for every paired device. Rooms are short-lived and in memory. After a temporary disconnect or reload, the client reconnects and applies the latest server snapshot; that snapshot wins over navigation performed locally while offline. A server restart or room expiry requires a new session. This mode is for a **trusted LAN only**. The join code is not authentication, the built server does not provide TLS, and this runbook makes no public-internet security claim. Keep `wf-rpc-server` on loopback at port `8765`: browser workflow operations continue through the Hono boundary on port `8787`, so the workflow RPC server does not need a LAN binding. ## Commands | Command | Description | |---------|-------------| | `pnpm --dir web install` | Install all workspace dependencies | | `pnpm --dir web dev` | Start Vite + Hono development servers | | `pnpm --dir web test` | Run all test suites | | `pnpm --dir web typecheck` | Run TypeScript type checking | | `pnpm --dir web build` | Build the React console for production | | `pnpm --dir web start` | Start the production Hono server | | `pnpm --dir web test:workflow-console:e2e` | Build and run real-server desktop/mobile console acceptance tests | | `pnpm --dir web --filter @lda/workflow-rpc contract:write` | Regenerate TypeScript wire names and raw types from the checked workflow manifest | | `pnpm --dir web --filter @lda/workflow-rpc contract:check` | Fail when the generated TypeScript contract has drifted | | `pnpm --dir web --filter @lda/console test:presentation-sync:e2e:install` | Install the Chromium binary required by the browser smoke test | | `pnpm --dir web --filter @lda/console test:presentation-sync:e2e` | Run isolated two-context presentation synchronization smoke tests against a built server | Run the E2E install command once after `pnpm install` on each clean development or CI machine. Playwright keeps the matching Chromium binary in its browser cache for subsequent smoke runs. ## Architecture ```text web/ apps/ console/ React + Vite frontend server/ Hono local server (API + static serving) packages/ rpc/ Effect-based JSON-RPC client, schemas, and errors presentation-sync/ Bounded presentation room wire contract ``` The browser communicates with Hono at `/api/connect` and `/api/rpc`. Hono validates targets against loopback policy, executes typed JSON-RPC calls through Effect, and returns plain JSON DTOs to the browser. ## Product And Design Context The console app carries two design-context files: - [`apps/console/PRODUCT.md`](apps/console/PRODUCT.md) captures the strategic product contract: users, purpose, personality, anti-references, and design principles. - [`apps/console/DESIGN.md`](apps/console/DESIGN.md) captures the current visual system: tokens, typography, components, elevation, and do/don't rules. This structure comes from the local Impeccable design workflow. `PRODUCT.md` uses its product-register format, and `DESIGN.md` follows the DESIGN.md convention: YAML frontmatter for machine-readable tokens, followed by six fixed sections (`Overview`, `Colors`, `Typography`, `Elevation`, `Components`, and `Do's and Don'ts`). Future UI work should read these files before changing visual direction. ## Workflow Console After connecting, the console opens a route-based workspace rather than one combined explorer screen. - **Discover** searches the capability catalog and inspects typed capability contracts. - **Drafts** lists persisted draft workspaces and opens the authoring workbench for capability insertion, step edits, route edits, validation, diagnostics, revision, and raw protocol evidence. - **Selected-step editing** exposes Setup, Inputs, and Outputs tabs for a selected capability step. Inputs replace the ordered capability input bindings, while Outputs replace output-to-state bindings; the controller sends the complete canonical row list for each save. Persisted malformed rows remain visible as repair rows and block save or clear until repaired. - **Workflow contracts** project Input, State, Output, and Outcomes into the draft graph without creating fake executable nodes. Their focused inspectors edit the canonical schemas, entry step, final output bindings, and outcomes. Pickers use the revision-scoped authoring inventory to show compatible workflow, selected-step, and applicable runtime-context paths. **Advanced** remains available for a deliberate custom path when the inventory cannot describe a valid binding. End nodes, control-flow nodes, subgraphs, and foreach/join authoring forms remain future typed-step work. - **Artifacts**, **Deployments**, and **Runs** provide focused lifecycle lists and detail routes, including artifact graphs, deployment validation, run interrupts, and trace evidence. - **Evidence** records JSON-RPC request and response receipts with equivalent CLI text across the workspace. - **Pagination** is available for cursor-backed artifact and run collections. ## Security - Only loopback targets are accepted (`127.0.0.1`, `localhost`, `[::1]`) - Upstream redirects are rejected - Request bodies are limited to 256 KiB - Response bodies are limited to 4 MiB - The server binds to `127.0.0.1` by default - Browser capability calls are enabled automatically only when `WEB_HOST` is loopback - A non-loopback bind requires the explicit override `WEB_ENABLE_CAPABILITY_CALLS=1` before the Try capability surface can call upstream capabilities - TLS-terminating proxies can allow exact browser origins with the comma-separated `WEB_TRUSTED_ORIGINS` setting. Forwarded headers are not trusted implicitly. The non-loopback override is an explicit risk acceptance for a trusted environment, not authentication, TLS, tenant isolation, or a public-internet security boundary. It can let LAN clients execute side-effecting capabilities against the configured workflow target: ```powershell pnpm --dir web build $env:WEB_HOST = "0.0.0.0" $env:WEB_ENABLE_CAPABILITY_CALLS = "1" $env:WEB_TRUSTED_ORIGINS = "https://workflow-console.example" pnpm --dir web start ``` ## Smoke Test With the Python server running, verify in the browser: 1. The initial page makes no upstream request 2. Connect succeeds against `http://127.0.0.1:8765/rpc` 3. Capability discovery returns catalog entries and supports qualified-name inspection 4. Raw health and capability exchanges are selectable in the evidence inspector 5. Equivalent CLI text is visible 6. Select **Try capability**, acknowledge the immediate-call warning, and submit `wf.std.concat` with `items: ["hello", "world"]` and `separator: " "`; verify `hello world`, the target-bearing evidence receipt, and no workflow run or trace record 7. Select `wf.source.read_resource`; verify `logical_source`, `uri`, and the defaulted `kind` field render, then verify a completed `runtime_error` receipt when it is called without platform context 8. Create a draft, add and edit a capability step, set a route, validate, and reload its direct draft URL while checking graph and evidence state 9. `http://example.com:8765/rpc` is rejected without upstream fetch 10. Stopping the Python server produces the unreachable state while preserving the entered URL 11. Persisted draft workspaces populate and a selected draft shows its graph, diagnostics, and revision 12. Artifact, deployment, and run routes populate independently 13. Selecting an artifact shows its plan graph and detail panel 14. Selecting a run shows trace frames and interrupt details 15. Clicking a trace frame shows resolved input and output ### LDA Report Workflow Smoke ```powershell # Terminal 1: start the workflow server with the report example uv run wf-rpc-server --config examples/lda_report_workflow/wf.config.json --host 127.0.0.1 --port 8765 # Terminal 2: start the console dev server pnpm --dir web dev ``` Connect to `http://127.0.0.1:8765/rpc`. The smoke passes when capability discovery, draft inspection, lifecycle routes, graph visualization, trace frames, and raw evidence are visible. ## lda Report Workflow Demo Start the prepared workflow RPC server from the repository root: ```powershell uv run wf-rpc-server --config examples/lda_report_workflow/wf.config.json --host 127.0.0.1 --port 8765 ``` Start the web console: ```powershell pnpm --dir web dev ``` Open `http://127.0.0.1:5173/`, connect to `http://127.0.0.1:8765/rpc`, then use the `lda report workflow demo` panel. The panel expects `lda_report_case_study.default` to already exist in the connected store. If it is missing, the panel displays the exact product CLI setup commands. ### Demo Timeline Modes - **Live** executes the prepared deployment through public JSON-RPC calls. - **Replay** uses the committed `lda-report-success-v1` recording and does not contact the workflow server during playback. `Start presentation` begins autoplay. `Pause` stops before the next operation, and `Next` applies exactly one operation or recorded event. Playback always stops at `issue_review`; approval remains a human action in both modes. Replay is visibly labeled and does not create real issues. ### Presentation Mode The console exposes `/present`, a 720p no-scroll defense compositor for the prepared `lda_report_workflow` story. It renders a 13-scene, multi-beat storyboard with an adaptive aspect-ratio canvas, stable stage regions, discussion branches, one editorial canvas, persistent scene-aware assistant surfaces, and keyboard navigation. The companion `/presenter` route is a speech and Q&A reader. It uses the same `#scene//` and `#discuss/` hashes, shows target and cumulative timing, keeps optional detail/evidence/Q&A collapsed, and links to the corresponding audience slide in a new tab. It performs no workflow RPC, replay, or live-target operations. Its shared pairing controller synchronizes canonical navigation hashes with `/present` through Hono without duplicating storyboard semantics. Use ArrowLeft and ArrowRight to move between notes; covered checkboxes remain local to the page. Must-say notes support authored inline Markdown emphasis for rapid scanning, and the stable Previous/Next bar remains available at narrow viewport widths. The final presentation beats frame the evaluation as bounded evidence, make claim boundaries and future work explicit, and end on the canonical defense discussion index rather than a benchmark or generic conclusion. Scenes 7 and 8 use the canonical prepared-authoring recording as their only execution evidence. Scene 7 is a single full-screen chat-entry beat: its prefilled request is submitted locally, then reveals the first deterministic user, assistant, and Discover tool group. It is deterministic replay, not a live LLM chat, and does not start a workflow run. Scene 8 breaks the prepared authoring into six beats with a persistent prepared-agent assistant pane on the left and a dominant phase canvas on the right. The adaptive split starts near 26/74 and keeps the matching prepared tool group synchronized with each factual source, graph, repair, artifact, or deployment view. Neither scene calls workflow authoring RPC operations — they consume deterministic prepared data. Scenes 9 through 11 use the canonical replay by default when no live target is available. When the resolved target is healthy, the same prepared run flow can execute through the public JSON-RPC operations and record live evidence using the same DemoRunFacts projection. Raw protocol payloads are available through the evidence receipt and inspector. Scenes 7–11 share one compact footer demo rail. Scene 7 remains a local scripted conversation, with its chat composer as the main surface, while the rail owns `Run prepared workflow`, replay fallback, retry, running, paused, resuming, and completed labels. With a healthy target, the rail starts the live chain through the existing `/api/rpc` proxy; when health fails, it keeps `Play replay walkthrough` as an explicit fallback. The presentation does not silently replace a live failure with recorded evidence. For local live rehearsal, run both services: ```powershell pnpm --dir web dev uv run wf-rpc-server --config examples/lda_report_workflow/wf.config.json --host 127.0.0.1 --port 8765 ``` The browser runs on `5173`, the console server proxy runs on `8787`, and the workflow RPC server listens on `8765/rpc`. The presentation chat surface is source-owned and follows the AI Elements conversation/message/tool/prompt-action model. It currently renders the prepared timeline agent and approval flow; a future AI SDK driver should target `AgentMessagePart` / `TimelineAgent`-compatible events instead of replacing the presentation timeline. The key deep-link-addressable defense states include: - `/present#scene/agent-handoff/request` — Scene 7, prepared authoring request - `/present#scene/prepared-lifecycle/discover` — Scene 8, discover phase - `/present#scene/prepared-lifecycle/draft` — Scene 8, draft phase - `/present#scene/prepared-lifecycle/deployment` — Scene 8, deployment phase - `/present#scene/run-from-deployment/operation` — Scene 9, run operation - `/present#scene/run-from-deployment/graph` — Scene 9, workflow graph - `/present#scene/typed-human-boundary/approval` — Scene 10, typed approval - `/present#scene/resume-output-evidence/resume` — Scene 11, resume proof Legacy aliases from the earlier 12-scene plan (such as `workflow-demo` and `interrupt-evidence`) are replaced by the IDs above and no longer resolve. Scene 11 is factual by design. It projects the reviewed/live run into visible workflow input, interrupt payload, resume decision, output, and trace facts. Empty trace frame objects are shown as captured empty objects; absent fields are called out as not captured rather than replaced by generic placeholders. ```powershell pnpm --dir web dev # open http://127.0.0.1:5173/present ``` #### Navigation - **ArrowRight / Space**: advance to the next beat within a scene, then to the next scene - **ArrowLeft**: rewind to the previous beat or scene - **Escape**: close overlays in priority order (node spotlight, evidence, discussion) - **P**: toggle presenter controls #### Hash Format - Main scenes: `#scene//` - Discussion branches: `#discuss/` Invalid hashes fall back to the first scene and beat. #### Chat Modes Chat is composed per-beat with four modes: `hidden`, `full`, `rail`, and `dock`. When `dock` is active, a floating button in the lower-left corner expands the chat to `rail`. #### Presentation Canvas The presentation uses one warm Editorial Canvas across all scenes. Dark surfaces are local to product evidence such as chat, graphs, traces, and terminal-style operation blocks; they are not whole-stage themes. #### Discussion Branches Five discussion branches exist under the positioning scene. Opening a branch from the main scene saves the originating beat as the return location. Direct hash links to `#discuss/` return to the parent scene's first beat. #### Replay-First Startup Replay is the default mode. The demo timeline auto-starts in replay using the committed `lda-report-success-v1` recording. No RPC server is required. #### Editorial Canvas The presentation renders on an adaptive editorial canvas that derives its aspect ratio from the browser viewport. The canvas fills the available viewport while clamping its aspect ratio between 4:3 and 16:9. It intentionally avoids `transform: scale(...)`: React Flow figures, popovers, and floating UI measure DOM geometry, so the stage must expose real element positions instead of scaled coordinates. No URL query parameters or local-storage settings control the ratio. Scene 6 uses a recursive Interactive Figure with expand/collapse and breadcrumb navigation. Key Scene 6 deep links: - `/present#scene/architecture/client` — root architecture overview - `/present#scene/architecture/runtime/focus/runtime-providers` — one level deep - `/present#scene/architecture/runtime/focus/runtime-providers/configured-providers` — two levels deep #### Figure Controls - **Enter / click**: expand a child figure - **Escape**: pop one focus level - **Tab / arrows**: move focus between figure nodes without advancing the presentation - **Breadcrumbs**: jump to any ancestor focus level #### Evidence Presentation Evidence availability never resizes the primary presentation region. Each beat may request an evidence presentation state (`hidden`, `receipt`, or `inspector`), and a global override can be set through the presentation tool. The state is cleared on scene navigation (next, previous, jump) but preserved through discussion transitions. - **Receipt**: a compact bottom-row button showing the count and label of available evidence records. Clicking opens the inspector. - **Inspector**: a centered modal dialog with `Interpreted` and `Raw` tabs, a record selector, and focus trapping. `Escape` closes the inspector. #### Constraints This plan deliberately defers: - AI Elements / Vercel AI chat primitives - Live LLM driver integration - Public-internet presentation hosting, TLS, and authentication - Final visual polish and motion choreography ### Constrained Demo Agent `/present` includes a prepared agent recipe for the thesis readiness report. The recipe is deterministic: it emits standard chat message parts, workflow tool calls, and presentation tool actions without requiring a model provider key. The current prepared recipe can: - identify the `lda_report_case_study.default` workflow deployment; - show tool calls for run start, resume, and trace read; - focus the `review_issues` interrupt node through a presentation tool action; - open evidence linked to the run trace. This is intentionally not a general autonomous planner. A future server-side Vercel AI SDK driver can feed the same message-part interface. ### Authoring Story (Scenes 7 and 8) Scenes 7 and 8 are the prepared authoring story. They use deterministic data from the committed `projectPreparedAuthoring()` recording and never call workflow authoring RPC operations. - **Scene 7 (Agent Request)**: a single full-screen deterministic chat entry that pre-fills the report-authoring request. Send is local presentation state and reveals the first prepared Discover tool group. This is not a live LLM chat or workflow run. - **Scene 8 (Prepared Workflow Lifecycle)**: a six-beat lifecycle (discover, draft, diagnose, repair, artifact, deployment) with a compact phase rail and one dominant factual product projection per beat. A persistent prepared assistant pane stays visible on the left while the phase canvas remains dominant on the right; the starting split is approximately 26/74 and adapts to the available width. Its active tool group follows the current beat. There is no lower chat dock, detached trace modal, or second transcript. One staged message box remains visible in every phase. Discover starts empty with useful placeholders; Draft and Artifact use the exact next authoring prompts. Sending an edited Draft advances through Diagnose and Repair and preserves that text as the projected user turn; sending an edited Artifact does the same for Deployment. Deployment Send records only `Run request prepared for the next execution slice.` and makes no run or RPC request. The authoring scenes consume deterministic prepared data and never call workflow authoring RPCs. Scene 8 ends at the truthful run-request handoff; Scenes 9–11 own run activation, typed approval, resume, output, and trace evidence. No Scene 8 message submission starts a workflow run. ### Demo Climax (Scenes 7–11) Scenes 7 through 11 are the demo climax. They keep a continuity rail visible while the prepared replay moves from persisted workflow run, to typed human interrupt, to resume/output/evidence. The rail and outcome panel are presentation-only projections over the committed replay; they do not add live backend dependencies.