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]>
218 lines
11 KiB
Markdown
218 lines
11 KiB
Markdown
# 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.
|