docs: define console product design contract
This commit is contained in:
@@ -73,7 +73,7 @@ Implementation order:
|
||||
Design:
|
||||
[`React presentation mode`](superpowers/specs/2026-07-03-react-presentation-mode-design.md).
|
||||
Implementation:
|
||||
[`React presentation mode plan`](superpowers/plans/2026-07-03-react-presentation-mode.md).
|
||||
[`React presentation mode plan`](historical/superpowers/plans/2026-07-03-react-presentation-mode.md).
|
||||
8. Add a constrained demo agent that invokes one prepared recipe macro.
|
||||
9. Add a static slide/appendix shell only after presentation mode is clear.
|
||||
Astro remains an option, not the default next surface.
|
||||
|
||||
@@ -64,6 +64,23 @@ 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.
|
||||
|
||||
## Lifecycle Explorer
|
||||
|
||||
After connecting, the console displays the lifecycle explorer with three
|
||||
|
||||
@@ -0,0 +1,270 @@
|
||||
---
|
||||
name: "lda.chat Workflow Console"
|
||||
description: "A product console and defense presentation surface for inspecting workflow lifecycle evidence."
|
||||
colors:
|
||||
paper: "#faf8f5"
|
||||
ink: "#1a1a1a"
|
||||
slate: "#5a5a5a"
|
||||
surface: "#f0ede8"
|
||||
border: "#d4d0cb"
|
||||
signal-green: "#2d8a4e"
|
||||
amber: "#b8860b"
|
||||
red: "#c0392b"
|
||||
presentation-bg: "oklch(0.12 0.025 250)"
|
||||
presentation-panel: "oklch(0.18 0.025 250)"
|
||||
presentation-line: "oklch(0.36 0.04 250)"
|
||||
presentation-accent: "oklch(0.7 0.16 195)"
|
||||
presentation-interrupt: "oklch(0.76 0.18 70)"
|
||||
typography:
|
||||
display:
|
||||
fontFamily: "Barlow Condensed, sans-serif"
|
||||
fontWeight: 700
|
||||
lineHeight: 1
|
||||
letterSpacing: "0.02em"
|
||||
body:
|
||||
fontFamily: "Source Sans 3, sans-serif"
|
||||
fontWeight: 400
|
||||
lineHeight: 1.5
|
||||
mono:
|
||||
fontFamily: "IBM Plex Mono, monospace"
|
||||
fontWeight: 400
|
||||
lineHeight: 1.4
|
||||
rounded:
|
||||
control: "3px"
|
||||
surface: "4px"
|
||||
graph-node: "6px"
|
||||
presentation-panel: "0.85rem"
|
||||
spacing:
|
||||
xs: "0.35rem"
|
||||
sm: "0.5rem"
|
||||
md: "0.75rem"
|
||||
lg: "1rem"
|
||||
xl: "1.25rem"
|
||||
components:
|
||||
button-primary:
|
||||
backgroundColor: "{colors.ink}"
|
||||
textColor: "{colors.paper}"
|
||||
rounded: "{rounded.control}"
|
||||
padding: "0.5rem 1.25rem"
|
||||
input-text:
|
||||
backgroundColor: "#ffffff"
|
||||
textColor: "{colors.ink}"
|
||||
rounded: "{rounded.control}"
|
||||
padding: "0.5rem 0.75rem"
|
||||
console-surface:
|
||||
backgroundColor: "{colors.surface}"
|
||||
textColor: "{colors.ink}"
|
||||
rounded: "{rounded.surface}"
|
||||
padding: "1rem"
|
||||
presentation-panel:
|
||||
backgroundColor: "{colors.presentation-panel}"
|
||||
textColor: "oklch(0.96 0.01 250)"
|
||||
rounded: "{rounded.presentation-panel}"
|
||||
padding: "1rem"
|
||||
---
|
||||
|
||||
# Design System: lda.chat Workflow Console
|
||||
|
||||
## 1. Overview
|
||||
|
||||
**Creative North Star: "The Evidence Theater"**
|
||||
|
||||
The console has two related visual modes. `/console` is a product tool: compact,
|
||||
legible, and deliberately familiar. It should help an operator connect to a
|
||||
workflow server, inspect records, and verify evidence without decoding raw JSON
|
||||
first. `/present` is a defense surface: cinematic enough to keep attention, but
|
||||
still grounded in real workflow operations, graph state, interrupt contracts,
|
||||
and trace evidence.
|
||||
|
||||
This design system is transitional. The current implementation already has a
|
||||
usable technical-console vocabulary and a separate dark presentation vocabulary,
|
||||
but those token sets are not yet fully unified. Future visual work should
|
||||
normalize the shared primitives before adding more styling.
|
||||
|
||||
The chat surface is not the core identity. Chat may frame a prepared operation
|
||||
or narrate a workflow, but it must not become a hand-rolled generic chatbot. If
|
||||
chat grows, use a mature assistant UI pattern and adapt it to the workflow
|
||||
substrate.
|
||||
|
||||
**Key Characteristics:**
|
||||
|
||||
- Product console: readable, restrained, technical, evidence-first.
|
||||
- Presentation route: cinematic, large-type, staged, graph-forward.
|
||||
- Visual proof beats decorative flourish.
|
||||
- Familiar product controls beat invented affordances.
|
||||
- Chat stays professional and secondary.
|
||||
|
||||
## 2. Colors
|
||||
|
||||
The current palette is split between paper-console neutrals and a dark
|
||||
presentation stage. Keep that split for now, but do not add a third unrelated
|
||||
palette.
|
||||
|
||||
### Primary
|
||||
|
||||
- **Ink Black**: the console action and text anchor. Use for primary buttons,
|
||||
code panels, and high-emphasis text.
|
||||
- **Presentation Cyan**: the presentation accent. Use for active beat rail
|
||||
items, selected graph nodes, and staged highlight moments only.
|
||||
|
||||
### Secondary
|
||||
|
||||
- **Signal Green**: success, connection, loaded/current status, and positive
|
||||
validation.
|
||||
- **Interrupt Amber**: typed human boundary, review state, and interrupt graph
|
||||
emphasis.
|
||||
- **Failure Red**: destructive or failed states only.
|
||||
|
||||
### Neutral
|
||||
|
||||
- **Warm Paper**: the current `/console` page background.
|
||||
- **Stone Surface**: console sections, panels, and stable content blocks.
|
||||
- **Soft Border**: console dividers, panel edges, and table rules.
|
||||
- **Slate Text**: secondary labels, metadata, durations, and muted state text.
|
||||
- **Night Stage**: the `/present` background and presentation canvas.
|
||||
|
||||
### Named Rules
|
||||
|
||||
**The One Evidence Accent Rule.** On any given screen, only one non-neutral color
|
||||
should carry the user's attention. Green, amber, cyan, and red must not compete.
|
||||
|
||||
**The Palette Debt Rule.** Presentation OKLCH colors and console hex colors are
|
||||
allowed today because they reflect existing code. New work should consolidate
|
||||
them into named tokens instead of adding more one-off values.
|
||||
|
||||
## 3. Typography
|
||||
|
||||
**Display Font:** Barlow Condensed, sans-serif
|
||||
**Body Font:** Source Sans 3, sans-serif
|
||||
**Label/Mono Font:** IBM Plex Mono, monospace
|
||||
|
||||
**Character:** Condensed headings make the product feel operational and
|
||||
technical without becoming terminal-only. Source Sans carries readable body
|
||||
content. IBM Plex Mono is reserved for paths, commands, JSON, IDs, and evidence.
|
||||
|
||||
### Hierarchy
|
||||
|
||||
- **Display** (700, large route/beat headings, tight line-height): presentation
|
||||
stage titles and major defense beats.
|
||||
- **Headline** (700, uppercase, `1.25rem` to `1.75rem`): console section titles
|
||||
and lifecycle panels.
|
||||
- **Title** (600-700, uppercase, compact): card, graph node, and table group
|
||||
labels.
|
||||
- **Body** (400, `1rem`, `1.5` line-height): explanatory copy, status text, and
|
||||
panel descriptions. Keep prose under 75ch where possible.
|
||||
- **Label** (600, small, `0.05em` tracking): form labels, table headers, and
|
||||
compact metadata.
|
||||
- **Mono** (`0.74rem` to `0.85rem`): commands, IDs, JSON, paths, run IDs, and
|
||||
equivalent CLI snippets.
|
||||
|
||||
### Named Rules
|
||||
|
||||
**The Mono Is Evidence Rule.** Monospace means something inspectable: a command,
|
||||
path, ID, JSON body, or protocol field. Do not use mono as decoration.
|
||||
|
||||
**The Chat Restraint Rule.** Chat labels and messages should use the product
|
||||
type system. Do not introduce playful display type inside the chat frame.
|
||||
|
||||
## 4. Elevation
|
||||
|
||||
The console is mostly flat and uses tonal layers, borders, and code panels for
|
||||
depth. The workflow graph has a small mechanical shadow on nodes. Presentation
|
||||
mode uses overlays and fixed drawers rather than heavy shadows.
|
||||
|
||||
### Shadow Vocabulary
|
||||
|
||||
- **Graph Node Lift** (`0 3px 0 rgba(26, 26, 26, 0.12)`): use only for graph
|
||||
nodes where the block needs a tangible, diagram-like presence.
|
||||
- **Overlay Depth**: currently expressed through fixed positioning, darker
|
||||
surface color, and border contrast rather than a drop shadow.
|
||||
|
||||
### Named Rules
|
||||
|
||||
**The Flat By Default Rule.** Surfaces are separated with tone and borders.
|
||||
Shadows are reserved for graph nodes or true overlays.
|
||||
|
||||
## 5. Components
|
||||
|
||||
### Buttons
|
||||
|
||||
- **Shape:** compact technical controls (`3px` radius).
|
||||
- **Primary:** ink background, paper text, uppercase Barlow Condensed, `0.5rem`
|
||||
by `1.25rem` padding.
|
||||
- **Hover / Focus:** hover lightens toward slate; focus must remain explicit and
|
||||
visible. Do not rely on color alone.
|
||||
- **Presentation buttons:** may use darker panels and cyan selected states, but
|
||||
should keep predictable button affordances.
|
||||
|
||||
### Chips
|
||||
|
||||
- **Style:** the current system does not have a mature chip primitive. Use
|
||||
simple bordered labels or buttons until a component library lands.
|
||||
- **State:** selected/current states should use the single active accent for the
|
||||
screen.
|
||||
|
||||
### Cards / Containers
|
||||
|
||||
- **Corner Style:** console panels use restrained corners (`4px`). Presentation
|
||||
panels use larger stage corners (`0.85rem`).
|
||||
- **Background:** console panels use Stone Surface; presentation panels use dark
|
||||
Night Stage layers.
|
||||
- **Shadow Strategy:** flat by default; see Elevation.
|
||||
- **Border:** one-pixel structural borders are the default separator.
|
||||
- **Internal Padding:** `1rem` for normal panels; tighter `0.6rem` to `0.75rem`
|
||||
for list and timeline items.
|
||||
|
||||
### Inputs / Fields
|
||||
|
||||
- **Style:** white field, ink text, mono type for URLs and command-like values,
|
||||
`3px` radius, one-pixel border.
|
||||
- **Focus:** explicit green outline, not subtle glow.
|
||||
- **Error / Disabled:** disabled controls lower opacity and preserve shape.
|
||||
Errors must include text; red alone is not enough.
|
||||
|
||||
### Navigation
|
||||
|
||||
- **Console navigation:** use familiar tabs/buttons for focus modes. Active
|
||||
state must be visible through class, text, or control state.
|
||||
- **Presentation navigation:** beat rail is horizontal, keyboard-addressable,
|
||||
and should remain usable at 720p. Hash links identify beats.
|
||||
|
||||
### Workflow Graph
|
||||
|
||||
Workflow graph nodes are the signature component. They should feel like product
|
||||
evidence, not decorative bubbles. Nodes use uppercase headings, mono references,
|
||||
structural borders, and direct click targets. Interrupt nodes may use amber
|
||||
border emphasis because the typed human boundary is conceptually important.
|
||||
|
||||
### Operation Block
|
||||
|
||||
Operation blocks show the tool call as a product event: equivalent CLI, raw
|
||||
response, and interpreted response. The block should make the workflow substrate
|
||||
legible without hiding raw evidence.
|
||||
|
||||
## 6. Do's and Don'ts
|
||||
|
||||
### Do:
|
||||
|
||||
- **Do** make the workflow graph, operation block, evidence drawer, lifecycle
|
||||
explorer, typed interrupt/resume panel, and trace the main visual surfaces.
|
||||
- **Do** keep `/console` familiar and product-like: readable tables, standard
|
||||
buttons, clear labels, predictable focus states.
|
||||
- **Do** let `/present` be cinematic with staged panels, larger text, and graph
|
||||
zooms, as long as each moment maps back to real evidence.
|
||||
- **Do** use mature component and chat primitives when the interaction is
|
||||
standard.
|
||||
- **Do** respect reduced motion and keep keyboard navigation reliable.
|
||||
- **Do** use big text and few items during presentation beats.
|
||||
|
||||
### Don't:
|
||||
|
||||
- **Don't** make the console look like a generic AI chatbot.
|
||||
- **Don't** hand-roll chat components as the foundation for the product.
|
||||
- **Don't** let chat dominate presentation mode; it can slide in, collapse, or
|
||||
move off-screen.
|
||||
- **Don't** use funny display fonts, doodle shapes, novelty bubbles, or unclear
|
||||
controls in the professional chat surface.
|
||||
- **Don't** add decorative motion that does not explain state or guide attention.
|
||||
- **Don't** overclaim a bundled autonomous AI-agent brain through UI copy.
|
||||
- **Don't** add more one-off colors before normalizing the console and
|
||||
presentation token sets.
|
||||
@@ -0,0 +1,107 @@
|
||||
# Product
|
||||
|
||||
## Register
|
||||
|
||||
product
|
||||
|
||||
## Users
|
||||
|
||||
The primary users are the thesis author during defense preparation, demo
|
||||
operators during a live presentation, and technical reviewers who need to see
|
||||
how `lda.chat` works without reading raw workflow JSON. Secondary users are
|
||||
future developers and agents using the console to inspect workflow lifecycle
|
||||
records, source capabilities, runs, traces, and interrupt/resume boundaries.
|
||||
|
||||
Users are usually under time pressure: a defense, demo, review session, or
|
||||
debugging pass. The interface should help them move quickly from a high-level
|
||||
story to concrete evidence without forcing them to decode raw protocol payloads
|
||||
first.
|
||||
|
||||
## Product Purpose
|
||||
|
||||
The console is the product-facing visual surface for `lda.chat`. It exists to
|
||||
show that the workflow substrate is inspectable, operable, and explainable: an
|
||||
operator can connect to a workflow server, inspect lifecycle records, view graph
|
||||
structure, start or resume prepared workflows, and inspect raw/evaluated
|
||||
evidence.
|
||||
|
||||
Presentation mode is not a generic slide deck. It is a cinematic product demo
|
||||
surface for explaining the thesis: external planners propose actions, the
|
||||
workflow substrate owns typed lifecycle state and deterministic execution, and
|
||||
the resulting runs remain auditable through traces and evidence records.
|
||||
|
||||
Chat is a framing device, not the core product. It may introduce or narrate a
|
||||
prepared workflow, but the main surfaces are the workflow graph, operation
|
||||
blocks, evidence drawer, lifecycle explorer, typed interrupt/resume panel, and
|
||||
run trace.
|
||||
|
||||
Success means a viewer can answer three questions quickly:
|
||||
|
||||
- What does `lda.chat` own that an external AI agent does not own?
|
||||
- How does a workflow move from authoring to deployment to execution?
|
||||
- Where is the proof that a specific run happened and can be inspected?
|
||||
|
||||
## Brand Personality
|
||||
|
||||
The product should feel precise, competent, and cinematic.
|
||||
|
||||
The console should feel like a real technical product: calm, readable, and
|
||||
trustworthy. The presentation route may be more theatrical: large text, clear
|
||||
beats, animated panels, graph zooms, and staged evidence reveals. The showmanship
|
||||
must support understanding, not cover missing substance.
|
||||
|
||||
The desired feel is closer to a polished developer tool plus a live product
|
||||
walkthrough than a generic AI chat app.
|
||||
|
||||
## Anti-references
|
||||
|
||||
Do not make the console look like a generic AI chatbot. Avoid hand-rolled chat
|
||||
components as the design foundation; if chat becomes important, adopt or adapt a
|
||||
mature open-source assistant UI pattern instead of inventing message bubbles,
|
||||
tool-call affordances, and composer behavior from scratch.
|
||||
|
||||
Do not let chat dominate presentation mode. Chat can slide in, collapse, or move
|
||||
off-screen, but the workflow graph and evidence views carry the thesis.
|
||||
|
||||
Do not use playful or decorative styling inside the professional chat surface:
|
||||
no funny display fonts, doodle shapes, novelty bubbles, or unclear controls.
|
||||
|
||||
Do not build a sleep-inducing slide deck that only lists architecture claims.
|
||||
The presentation should tell a story through staged transitions and concrete
|
||||
workflow evidence.
|
||||
|
||||
Do not overclaim the presence of a bundled autonomous AI-agent brain. The product
|
||||
surface may demonstrate a prepared or scripted agent-like interaction, but the
|
||||
core contribution remains the workflow substrate.
|
||||
|
||||
## Design Principles
|
||||
|
||||
1. **Evidence first.** Every impressive visual should have a path back to a
|
||||
workflow record, operation, run trace, or captured protocol response.
|
||||
2. **Graph over transcript.** Use chat sparingly; prefer graph, lifecycle,
|
||||
operation, and evidence views for explaining the system.
|
||||
3. **Cinematic, not cluttered.** Use large text, few items, and staged motion for
|
||||
presentation mode. Avoid dense panels unless the viewer deliberately opens
|
||||
them.
|
||||
4. **Professional where users operate.** The `/console` surface should prioritize
|
||||
familiar product patterns, predictable components, readable tables, and clear
|
||||
failure states.
|
||||
5. **Agent-facing, not agent-theater.** Show how external agents or scripted demo
|
||||
flows operate `wf`; do not imply that the UI itself proves a new planning
|
||||
algorithm.
|
||||
6. **Adopt standard primitives.** Prefer proven component libraries and mature
|
||||
chat UI patterns over custom controls when the interaction is standard.
|
||||
|
||||
## Accessibility & Inclusion
|
||||
|
||||
Target WCAG 2.2 AA for normal product UI. Presentation mode should remain usable
|
||||
on a 720p projector or screen, with large text, high contrast, and no dependency
|
||||
on color alone to distinguish models, stages, or outcomes.
|
||||
|
||||
Motion should respect `prefers-reduced-motion`. Presentation animations may be
|
||||
cinematic, but they must not block comprehension, hide important content, or make
|
||||
manual navigation difficult.
|
||||
|
||||
Keyboard navigation matters for defense use: arrow keys should move beats,
|
||||
Escape should close overlays, and clickable graph nodes or drawers should remain
|
||||
reachable through standard focus behavior.
|
||||
@@ -19,8 +19,8 @@ export const NodeSpotlight = ({ nodeId, close }: NodeSpotlightProps) => {
|
||||
const node = presentationNodes.find((candidate) => candidate.id === nodeId);
|
||||
if (!node) return null;
|
||||
|
||||
return (
|
||||
<aside className="node-spotlight" role="dialog" aria-modal="true" aria-label={node.label}>
|
||||
return (
|
||||
<aside className="node-spotlight" role="dialog" aria-modal="true" aria-label={node.label}>
|
||||
<button type="button" onClick={close}>Close</button>
|
||||
<p>NodeUse</p>
|
||||
<h2>{node.label}</h2>
|
||||
|
||||
@@ -45,4 +45,14 @@ describe("PresentationRoute", () => {
|
||||
|
||||
expect(await screen.findByText(/workflow.runs.start/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows resume and trace operation blocks for later beats", async () => {
|
||||
render(<PresentationRoute />);
|
||||
|
||||
await userEvent.click(screen.getByRole("button", { name: /resume output/i }));
|
||||
expect(await screen.findByText(/workflow.runs.resume/i)).toBeInTheDocument();
|
||||
|
||||
await userEvent.click(screen.getByRole("button", { name: /trace evidence/i }));
|
||||
expect(await screen.findByText(/workflow.runs.trace/i)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -9,6 +9,7 @@ import { StageCaption } from "./StageCaption.js";
|
||||
import { WorkflowGraphStage } from "./WorkflowGraphStage.js";
|
||||
import type { PresentationState } from "./presentation-state.js";
|
||||
import type { DemoTimelineController } from "../demo/useDemoTimeline.js";
|
||||
import type { DemoEventStage } from "../demo/timeline/models.js";
|
||||
|
||||
type PresentationStageProps = {
|
||||
readonly state: PresentationState;
|
||||
@@ -21,6 +22,13 @@ type PresentationStageProps = {
|
||||
readonly closeOverlay: () => void;
|
||||
};
|
||||
|
||||
const operationStageByBeat: Partial<Record<BeatId, DemoEventStage>> = {
|
||||
"tool-call-start": "run_start",
|
||||
"interrupt-approval": "interrupt",
|
||||
"resume-output": "run_resume",
|
||||
"trace-evidence": "trace_read",
|
||||
};
|
||||
|
||||
export const PresentationStage = ({
|
||||
state,
|
||||
demo,
|
||||
@@ -32,11 +40,11 @@ export const PresentationStage = ({
|
||||
closeOverlay,
|
||||
}: PresentationStageProps) => {
|
||||
const beat = presentationBeats.find((candidate) => candidate.id === state.beat) ?? presentationBeats[0]!;
|
||||
const operationStage = operationStageByBeat[state.beat] ?? null;
|
||||
|
||||
const operationEvent =
|
||||
demo.state.events.find((event) => event.stage === "run_start") ??
|
||||
demo.state.events.find((event) => event.operation !== null) ??
|
||||
null;
|
||||
const operationEvent = operationStage
|
||||
? demo.state.events.find((event) => event.stage === operationStage) ?? null
|
||||
: null;
|
||||
|
||||
return (
|
||||
<div className="presentation-stage" data-beat={state.beat}>
|
||||
|
||||
Reference in New Issue
Block a user