Files
stack/docs/design/README.md
T
jason.woltjeandClaude Opus 5.5 811e7ba562 docs(design): handoff package for implementing the design
Jason accepted the draft 1 direction on 2026-10-10; the refined Relay
mark stays as a placeholder. Adds IMPLEMENTING.md (gap map against
row 40 and the bus/CLI modules, strings, boundaries, acceptance,
proposed rows for Sage), tokens.json and generated tokens.css using the
webui's existing names, icons.svg, and tools/build-tokens.mjs and
tools/check-design.mjs. Coverage statuses corrected against the code
(digest implemented; mosaic stop is row 41; priority and agent state
not in the bus reads). No packages/ change.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-10 11:22:06 -05:00

218 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Mosaic Stack design, draft 1
- Status: draft 1, 2026-10-09. A design, not built software. Nothing
under `packages/` changed for it.
- 2026-10-10: Jason accepted the direction. The mark stays the refined
Relay as a placeholder until he revises it. The defaults below are
provisional. Implementers start from `IMPLEMENTING.md`.
- Asked for by Jason: branding, WebUI page designs, a TUI design, and
every feature included.
- Preview: `mosaic-stack-design.html` in this directory. It is one
self-contained page with four tabs (Brand, Console, Terminal, Coverage),
and it is also published as a private claude.ai artifact. Sample data
throughout: ids, times and counts are illustrative.
- "GUI" in the request is the WebUI. There is no separate desktop app in
this design. A desktop app is not in the PRD.
## Sources
- `docs/prd/mosaic-stack.md` (PRD 1.0) for requirements and limits.
- Jason's earlier rulings on the console: the d3 layout, Manrope with
JetBrains Mono, ten palettes in three modes, the Relay mark, blue
without a purple gradient.
- Slice 1 briefs and Dewey's `agents/dewey/work/wui/` notes for the web
routes that exist.
- `packages/conversation`, `packages/bus`, `packages/cli`,
`packages/control-board` and `packages/webui` for the exact strings,
keys and states shown. Haiku 5.5 subagents gathered these. I checked
the strings that the mockups quote.
## Brand
- **Mark: Relay, refined.** Two interlocking hooks that pass work from
one to the other. The refined version is drawn on a 16-unit grid so it
stays sharp at 16 and 24 px (`brand/relay-refined.svg`). The original
56-unit drawing is kept (`brand/relay-original.svg`) and holds up from
48 px. The Brand tab shows both at 16, 24, 32, 48 and 96 px.
- **Name.** "Mosaic Stack" in prose and the header. `mosaic` is the
command and the short in-app wordmark.
- **Type.** Manrope for the interface. JetBrains Mono for ids, commands,
refusal codes and anything a person might type or paste. Scale:
28/800 page title, 20/800 section, 16/700 question, 14/400 text (table
cells 13 to 14), 11/700 caps labels, mono 12.5. Tabular figures in
columns.
- **Colour.** Ten palettes, each in Light, Dim and Dark: Harbor (the
proposed default), Carmine, Atlantic, Terracotta, Aubergine, Mineral,
Cobalt, Rosewood, Graphite and Grove. Every palette defines the same
semantic tokens: canvas, surface, raised, line, border, text, muted,
action, onAction, accent, success, warning, danger and focus. No
gradients.
- **Icons.** Seventeen line icons on a 24-unit grid, 1.75 stroke, round
joins, no fills: one per console section plus search, copy, close and
terminal. An icon never carries state alone.
- **Voice: calm precision.** Name the thing, the state and the next
step. Keep the system's own words (refusal codes, event kinds, task
refs) exactly as the bus records them, in mono. The Brand tab gives
Say / Not pairs, for example "Vikunja last read 14:21:07 (12 s ago)",
not "Everything is up to date! 🎉".
- **Status vocabulary.** One set of words and marks for both surfaces:
- agent state: ● working, ◐ waiting (shows the Input needed text),
▲ error, ○ offline, – idle, ? unknown;
- decision class: routine (logged), within-role (logged), cross-role
(to the arbiter: delivery → pm, technical → cto), gated (to you),
BLOCKING (CLI inbox and Discord DM now; otherwise the 08:00 CT
digest);
- task markers: changed in Vikunja, not created by the stack,
conflict, missing: moved, not-found, no-access.
Colour is never the only signal.
## WebUI: the console
The d3 layout:
- a command bar with Ctrl+K;
- a left section list plus the project tree;
- a dense table in the middle;
- a right-hand inspector drawer.
The Board is home. Views are in-page routes in the preview (the
section list and Ctrl+K switch them).
| View | Purpose | Data source |
|---|---|---|
| `board` | Who is working, who is waiting, what needs you; seat table with Input needed and Seen | control board, bus |
| `inbox` | Decisions: For you / Routed to roles / Recent; inspector shows the authorization sentence and copy commands | bus decisions |
| `talk` | The PM conversation: controller or observer, receipts, take control | conversation terminal |
| `tasks` | Vikunja tasks with bucket, priority, requirement and markers; freshness line | sync bot reads |
| `agents` | Role holders, launch budget (Opus n of 4, Sonnet n of 4), credential metadata | bus role claims, business file |
| `trail` | Every event for one task or decision, with filter chips | event store |
| `queue` | Queue rows, read-only | `docs/plans/queue.json` |
| `runs` | Run records and release status | `<dataRoot>/runs`, `release.sh status` |
| `ledger` | Ledger counts and the queue check | `packages/ledger` |
| `business` | Business file: roles, arbiters, limits, authority map, variables | business file, `roles/*.json` |
| `library` | Skills and contracts in launch bundles | meta-harness |
| `settings` | Appearance, notifications, about (loopback, no sign-in) | system config, read-only |
| `onboarding` (Set up) | First-run checklist | bootstrap checks |
| anything else | Not found, with links back | — |
Every view has five designed states, selectable in the preview:
normal, loading, empty, error with stale data kept on screen, and
refusal (fail closed, naming the missing file or rule).
Keyboard: Ctrl+K palette, ↑/↓ through table rows, Enter opens the
inspector, Esc closes it and returns focus to the row.
Below 1100 px the inspector overlays the table. Below 760 px the
section list becomes a horizontal strip, the inspector becomes a
full-screen sheet, and the page header stops pinning.
## TUI: `mosaic`
A full-screen app over the existing verbs. The design assumes `mosaic`
with no arguments opens it; the verbs stay for scripts (open decision
below).
- **Sizes.** Designed at 120×36, and every screen must also fit 80×24.
Below 100 columns the nav shows keys only, tables drop their
lower-priority columns (in Inbox, RAISED BY and REACHES YOU), and
detail moves below the list. The compact screen shows Inbox at
80×24.
- **Screens.** Talk (controller and observer), Inbox, Decide (confirm),
Outcome unknown, Tasks, Agents, Trail, Help, 80×24 compact, NO_COLOR,
refused in an agent run, quit to the shell.
- **Nav keys.** `c` talk, `i` inbox, `t` tasks, `a` agents, `r` trail;
↑↓ or j/k move; Enter opens; `v` trail of the selection; `:` command
line (`:decide`, `:trail`, `:q`); `?` help; `q` quit; Tab moves between
the nav and the composer.
- **Composer.** It keeps the conversation terminal's keys: Enter sends,
Ctrl-J newline, Ctrl-T take control, Ctrl-G interrupt, Ctrl-O
reconnect, PgUp/PgDn scroll. Header: `<state> | controller|observer |
unknown events: N`.
- **Deciding.** In Inbox, a digit chooses an option. The app then prints
the CLI's own lines: `your choice: 1 (Push now); this authorizes the
action`, then `resolve <short> with <k>? [y/N]`. Only `y` resolves.
- **Outcome unknown.** It shows the CLI's text: "outcome unknown: the broker may
have recorded it. Check mosaic inbox or mosaic trail <id> before trying
again". No retry key.
- **Inside an agent run.** The app refuses to open and exits 3 with
`refused: this runs only from a human shell, outside any agent run
(found CLAUDECODE, CLAUDE_CODE_ENTRYPOINT in the environment)`.
- **Colour.** The app uses the terminal's own 16 colours, so it follows
the user's theme:
- blue (4): action and selection;
- yellow (3): the PM and decisions;
- green (2): working, pass, fresh;
- bright yellow (11): waiting, stale, expiring, outcome unknown;
- red (1): blocking, refused, error, conflict;
- bright black (8): hints and rules;
- reverse video: the selected row.
With `NO_COLOR` set, every state still reads from its word and mark.
## Boundaries the design keeps
- **REQ-DEC-3.** A human resolves a decision only from a `mosaic` CLI
session outside any agent run. The web shows the decision and a Copy
button for `mosaic decide <short> <k>`. It has no Resolve button.
- **Seen is not resolution.** Seen on the Board and in the inspector
acknowledges an Input needed line or a decision. It answers nothing.
- **Read-only web.** Tasks, the queue, the business file, roles and
settings are views. Agents change tasks through the broker's verbs.
Rows move only through `queue move`.
- **Secrets.** Credentials appear as service, account, role and expiry.
Values and file paths are never shown.
- **Loopback only, no sign-in** in v1 (PRD scope).
## Coverage
The Coverage tab lists 41 features. Each row gives the requirement, the
web screen, the TUI screen and a status. The status describes the code
today, not these screens:
- **implemented**: exists in the code now (20 features);
- **in progress**: has an open queue row (3);
- **planned**: in the PRD or a brief, with no code yet (1);
- **proposed**: new in this design (17).
- **In progress.** All row 41 (S6): talk to the stack-owned PM
session, the launch budget, and `mosaic stop`.
- **Planned.** The business file view.
- **Proposed** (the larger items). The Inbox tabs, Seen for decisions,
task priority and requirement columns, agent state per role, the
field-writer table on tasks, credential expiry, the command palette,
and the business, library, queue, runs and ledger views. Also
first-run setup and the five-state treatment on every view.
Corrections on 2026-10-10, checked against the code:
- the 08:00 digest is implemented (`packages/cli/src/notifier.mjs`);
- `mosaic stop` is row 41 work;
- task priority and agent state are not in the bus reads, so they
moved out of the implemented rows.
`IMPLEMENTING.md` has the gap map per view.
## Open decisions for Jason
1. **Default palette and mode.** Provisional: Harbor, following the
system setting, with Dim available.
2. **Final mark.** The refined Relay is the placeholder (Jason,
2026-10-10: "Use the design's logo for now and we will revise.").
3. **Resolving from the web.** The PRD rules it out (REQ-DEC-3).
Provisional: keep the Copy command through v1.
4. **One `mosaic` app.** Provisional: `mosaic` with no arguments opens
the full-screen app, and the verbs remain for scripts.
5. **Decision Seen from the web.** It would give the browser a
human-authority write. Recommended: keep it in the terminal for
v1.
## Files
- `IMPLEMENTING.md`: the brief for implementing agents.
- `mosaic-stack-design.html`: the preview page. Its source is built from
a scratch file. Edit the HTML directly for draft 2.
- `tokens.json`, `tokens.css`: design values. `tokens.css` is
generated by `tools/build-tokens.mjs`.
- `icons.svg`: the icon sprite, plus the placeholder mark.
- `brand/relay-refined.svg`, `brand/relay-original.svg`: the mark in
Harbor action blue.
- `tools/check-design.mjs`: browser checks for the preview.