Files
stack/docs/plans/2026-10-10_design-implementation.md
T
jason.woltjeandClaude Opus 5.5 f824fcc9e5 docs(plans): design implementation brief, lead decisions 80 and 81
Brief for rows 53 to 61 implementing docs/design (Jason's directive via
Mos, DECISIONS 1a312ff). Decision 80 records the Q14 window, rev7 item 6
checks and the freeze; decision 81 the row shape and the design's open
decisions.

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

13 KiB

Design implementation: console and terminal rows (2026-10-10)

Status: written by Sage, lead. It follows docs/plans/BRIEF-TEMPLATE.md. Jason accepted the design direction and handed the queue to Sage (Mos relay, DECISIONS 1a312ff: "That design can be immediately implemented by the Mosaic Stack agents ... I am going to leave this in your power"). Lead decision 81 records the shape. The design package is docs/design/ at 811e7ba5. Every row below reads docs/design/IMPLEMENTING.md first; its sections "Strings to keep exactly", "Boundaries" and "Acceptance" apply to every row and are not repeated here.

Two rules apply to every row in this file.

  • The Q14 freeze holds packages/bus, packages/tasks, packages/cli, scripts/bus-service.sh and scripts/mosaic until ops-01 reports the Q14 hold ended. A row that needs one of those paths doesn't start before then. Importing from them is fine; changing them is not.
  • No commit to the checkout, queue moves included, from 2026-10-11T15:00Z until ops-01 reports the hold ended. Work in your own scratch tree during that window and commit nothing.

Design questions go to Sage, who relays them to the design session (tmux mosaic-design) and back.

Console tokens and shell restyle

Problem

The console in packages/webui sets its colours inline: theme() in packages/webui/src/public/app.js loops setProperty over brand.js values. It has no shared component set and no loading, empty, error or refusal states. The design (docs/design/tokens.css, icons.svg, mosaic-stack-design.html) defines the tokens, icons, components and five view states, and IMPLEMENTING.md sections "Tokens", "Icons and the mark" and "Components" give the adoption steps.

Owner and reviewer

  • Owner: Dewey.
  • Reviewers: Darkwing and Filbert.

Files owned

  • packages/webui/src/public/ (not shared/, which other packages read)
  • packages/webui/src/serve.mjs, only to add the new static files to the files map
  • packages/webui/tests/
  • packages/webui/README.md
  • agents/dewey/work/queue-53/ for evidence

docs/design/ is read-only for this row. Copy tokens.css and icons.svg into src/public/, and add a test that fails when the copy differs from docs/design/.

What ships

  • tokens.css served through the files map; theme() stops setting properties inline. data-palette and data-mode stay. Add a System choice that removes data-mode. The localStorage key stays mosaic-console-appearance. Harbor following the system setting is the default (decision 81).
  • --r 6px and --r-lg 10px, the type scale from "Tokens", and tabular numbers in tables.
  • JetBrains Mono 400, 500 and 700 self-hosted, from the official JetBrains release only, with each file's sha256 and the OFL text committed beside it. If the seat can't fetch the release, ship the system monospace stack and say so in the packet. Sage files the font as a follow-up.
  • The icon sprite, with the mark in one component and the placeholder Relay mark.
  • The command bar, section list, dense table, inspector, status mark, class chip, copy command, toast, command palette (Ctrl+K) and not found.
  • Five states (normal, loading, empty, error with stale data, refusal) on Board, Inbox, Tasks, Agents and Trail. Restyle only. No new data, endpoints or writes.
  • Tests: node --test tests/ in packages/webui green, the browser checks from "Acceptance" (no script errors, no sideways scroll at 400px, keyboard path, visible focus), seeded empty, stale-error and refusal states, and the string grep test.

Out of scope

New views (row 54), the terminal app (row 55), any backend read (rows 56 to 61), Decision Seen from the web (decision 81: not in v1), and the control board's own page on port 7331.

Gate

Darkwing and Filbert approve on the row's issue, each naming the candidate manifest. On Sage's gate rerun, packages/webui tests, node docs/design/tools/build-tokens.mjs --check and every scripts/test-*.sh are green.

Read-only console views: Queue, Business and Settings

Problem

The console can't show the queue, the business file or settings. The data exists in modules with no endpoint: list and show in packages/queue/src/store.mjs, loadBusiness in packages/business/src/business.mjs, loadRole and resolveInstance in packages/business/src, and readNotifyConfig in packages/cli/src/cli.mjs.

Owner and reviewer

  • Owner: Dewey, after row 53 (both change app.js and the shell).
  • Reviewers: Darkwing and Filbert.

Files owned

  • packages/webui/src/ (not public/shared/)
  • packages/webui/tests/
  • packages/webui/README.md
  • agents/dewey/work/queue-54/

No change to packages/queue, packages/business or packages/cli. If a module lacks a read the view needs, stop and tell Sage.

What ships

  • GET JSON endpoints /api/queue, /api/queue/<id>, /api/business and /api/settings. Keep the existing CSP, Host and Origin checks. No write, no network call, no new dependency.
  • Views #/queue, #/business and #/settings, with all five states. A missing or invalid business file shows the refusal state with the module's own refusal text.
  • Secrets as metadata only. Show service, account, role and expiry. No value, token or file path appears in any response or log. Notifier settings show binding names only, never a Discord channel, guild or user id. A test asserts each of these on a seeded fixture that holds such values.
  • Settings: appearance (the row 53 control), notifications (names only) and about (loopback address, RELEASE). Read-only apart from appearance.
  • Queue rows show state, owner, reviewers and the brief link. Rows move only through queue move; the view shows that command, not a button.
  • Tests as in row 53.

Out of scope

The Ledger view: the ledger CLI calls Gitea and reads the T3 database, so it needs a cached report first and gets its own row later. Runs and releases (row 56). Any backend read for the bus (rows 57 to 61).

Gate

As row 53, plus the secret and id assertions above passing.

Full-screen terminal app

Problem

mosaic with no argument exits 4 with usage. The design specifies a full-screen terminal app (IMPLEMENTING.md "The full-screen terminal app") built on the conversation Terminal class (packages/conversation/src/terminal.mjs:54).

Owner and reviewer

  • Owner: Darkwing.
  • Reviewers: Dewey and Filbert.
  • Starts after ops-01 reports the Q14 hold ended (packages/cli is frozen). Rebase on row 41 if it has landed by then.

Files owned

  • packages/cli/src/ (new app modules, and the no-argument entry)
  • packages/cli/tests/
  • packages/cli/README.md
  • docs/TOOLS.md, the mosaic entry
  • agents/darkwing/work/queue-55/

What ships

  • No-argument mosaic on a TTY opens the app (decision 81). Not on a TTY it keeps today's usage text and exit 4. In an agent run it exits 3 through transport.mjs.
  • Screens Inbox, Tasks, Agents, Trail and Help, with keys c, i, t, a, r, j, k, :, ? and q. Decide shows and runs the existing mosaic decide flow with its strings unchanged.
  • 16 ANSI colours, NO_COLOR honoured, fits 80x24, designed at 120x36.
  • No new dependency.
  • Tests: every screen fits 120 columns and 80x24, NO_COLOR output has no escape codes, an agent-run environment exits 3, a non-TTY exits 4 with the usage text, and the string grep test.

Out of scope

Talk and stop (after row 41), Decision Seen (needs its own CLI verb row), the web console.

Gate

Dewey and Filbert approve on the row's issue naming the candidate. packages/cli tests and every scripts/test-*.sh are green on Sage's gate rerun.

Runs and releases reader module

Problem

The run and release readers live inside scripts/mosaic-task.mjs and scripts/release.sh and aren't exported, so the console can't show runs or the active release.

Owner and reviewer

  • Owner: Rocko.
  • Reviewers: Darkwing and Filbert.

Files owned

  • a new packages/runs/ (module, tests, README)
  • scripts/mosaic-task.mjs, only to import the extracted readers
  • agents/rocko/work/queue-56/

What ships

  • A read-only module that lists runs under <dataRoot>/runs/, reads one run's result.json and reads the release pointer and activation log under <dataRoot>/state/. It never writes, prunes or follows a symlink out of the data root.
  • mosaic-task.mjs list and show use it, and their output is byte-identical before and after on a seeded data root.
  • Tests in packages/runs and scripts/test-task.sh green.

Out of scope

The #/runs view (a later row on this module), release.sh behaviour, and pruning.

Gate

Darkwing and Filbert approve naming the candidate. packages/runs tests and every scripts/test-*.sh are green on Sage's gate rerun, with the byte-identical output check in the packet.

Bus read: decisions routed to roles and recent decisions

Problem

inbox returns open decisions for the caller's role only. The design's Inbox tabs "Routed to roles" and "Recent" need a reader op for decisions routed to other roles and for closed ones.

Owner and reviewer

  • Owner: Filbert, after row 41 (S6 rewrites packages/bus).
  • Reviewers: Darkwing and Dewey.

Files owned

packages/bus/, packages/webui/src/bus.mjs and its tests, and agents/filbert/work/queue-57/.

What ships

A reader op and its webui endpoint, read-only, with tests. The reader session's authority doesn't widen: it reads what a human reader may read today, and a test shows a role session can't use it to read another role's open decisions.

Out of scope

Decision Seen and any write.

Gate

Darkwing and Dewey approve naming the candidate; bus, webui and every scripts/test-*.sh green on Sage's gate rerun.

Bus read: task priority and requirement

Problem

Priority isn't in task_current.fields, and the requirement sits only in the task.created event body, so the Tasks table can't show either.

Owner and reviewer

  • Owner: Darkwing, after row 41.
  • Reviewers: Dewey and Filbert.

Files owned

packages/bus/, packages/tasks/, the webui Tasks endpoint and tests, and agents/darkwing/work/queue-58/.

What ships

Both fields in the task read model, with a projection rebuild test, and the two columns in the Tasks view.

Out of scope

Field writers (row 61).

Gate

Dewey and Filbert approve naming the candidate; bus, tasks, webui and every scripts/test-*.sh green on Sage's gate rerun.

Bus read: agent state per role

Problem

The control board has state and Input needed per seat; the bus has nothing per role. The Agents view needs both per role.

Owner and reviewer

  • Owner: Filbert, after row 41.
  • Reviewers: Darkwing and Dewey.

Files owned

packages/bus/, packages/control-board/ (read side only), the webui Agents endpoint and tests, and agents/filbert/work/queue-59/.

What ships

A seat-to-role mapping read from committed data, or state on the bus. The packet says which and why. The Agents view shows the state mark and Input needed per role. Read-only.

Out of scope

Launch budget and stop (after row 41, a later row).

Gate

Darkwing and Dewey approve naming the candidate; bus, control-board, webui and every scripts/test-*.sh green on Sage's gate rerun.

Bus read: credential status on the broker

Problem

Credentials.status() (packages/bus/src/credentials.mjs:118) isn't exposed on the broker, so the console can't show credential health.

Owner and reviewer

  • Owner: Filbert, after row 41.
  • Reviewers: Darkwing and Dewey.

Files owned

packages/bus/, the webui endpoint and tests, and agents/filbert/work/queue-60/.

What ships

A broker read op returning service, account, role and expiry only. A test on a seeded store holding a value, a token and a path shows none of them in the op's output or the host log.

Out of scope

Any credential write, rotation or new credential.

Gate

Darkwing and Dewey approve naming the candidate; bus, webui and every scripts/test-*.sh green on Sage's gate rerun.

Task field-writer table as data

Problem

Which actor may write which task field is prose in docs/plans/2026-10-04_slice-1.md lines 62-72. The task inspector needs it as data.

Owner and reviewer

  • Owner: Darkwing, after row 41.
  • Reviewers: Dewey and Filbert.

Files owned

packages/tasks/, the webui Tasks inspector and tests, and agents/darkwing/work/queue-61/.

What ships

The table as a committed data file with a schema, a test that the writers the code enforces match it, and the inspector showing who may write each field. The slice 1 prose stays the reviewed source; if the code and prose disagree, stop and tell Sage.

Out of scope

Changing who may write a field.

Gate

Dewey and Filbert approve naming the candidate; tasks, webui and every scripts/test-*.sh green on Sage's gate rerun.

After row 41: Talk, launch budget, stop and Library

Not a queue row yet. Sage briefs these when row 41 lands, because they read what S6 creates (packages/harness, session.launched, launch.revoke). The same goes for the Ledger view's cached report and a Decision Seen CLI verb.