Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ e2e-artifacts/
.playwright-cli/
apps/desktop/.sero-e2e/
apps/desktop/.sero-baseline-home/
apps/desktop/.sero-ux-home/
apps/desktop/.sero-layout-test/
apps/desktop/.sero-test-data/
.sero-test-data/
Expand Down
1 change: 1 addition & 0 deletions apps/desktop/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ e2e/screenshots/living-loops/
e2e/screenshots/delivery/
e2e/screenshots/catalog/
e2e/screenshots/autonomous-delivery/
e2e/screenshots/architect-story/
426 changes: 426 additions & 0 deletions apps/desktop/e2e/architect-story.agent.spec.ts

Large diffs are not rendered by default.

282 changes: 282 additions & 0 deletions apps/styleguide/public/prototypes/architect-one-screen.html

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions apps/styleguide/src/PrototypeArchive.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@sero
import { ExternalLink, FileCode2, Image, type LucideIcon } from 'lucide-react';

const interactivePrototypes = [
['Architect — a board for decisions', 'architect-one-screen.html'],
['Rooms — member configuration changes: pending, applied, held, replaced', 'room-amendment-status.html'],
['Architect — waiting on a check, expiry and where each limit came from', 'architect-wait-status.html'],
['Architect — a milestone the Architect does itself (issue 620)', 'architect-direct-milestone.html'],
Expand Down
2 changes: 2 additions & 0 deletions openspec/changes/architect-decision-board/.openspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-10-08
59 changes: 59 additions & 0 deletions openspec/changes/architect-decision-board/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Design

## Context

See proposal.md for the motivation. The visual spec is the prototype `apps/styleguide/public/prototypes/architect-one-screen.html` at its four moments (`?moment=start|ask|working|done`).

The record already holds almost everything the board shows:

- `overview.outcome|objective|result|acknowledgement`: the Architect's short sentences.
- `working.assumptions`: choices the Architect made without asking.
- `decisions[]`: questions, and the user's answers.
- `agreement` and `budget`: the start cap and spend.
- `milestones[]` with `status`, `verification` and `evidence` (checks and captured pictures).
- `projectActivity()` in `shared/activity.ts`: the derived state.
- The owner live snapshot (`text`, `tool`, `request`) and the feedback rows for Room and Workflow members.

## Goals / Non-Goals

**Goals:**

- One pure function decides which tiles exist and which one is large, so the rule is tested without rendering.
- Reuse every existing action. The board adds no new way to change a project.

**Non-Goals:**

- No new owner tool. "Architect decided" reads `working.assumptions`.
- No streaming view of the browser. Live shows the last screenshot the Architect took, refreshed when its action changes.
- No redesign of Plan, Research, Evidence, History or the inspector.

## Decisions

**A board view-model in `ui/lib/board.ts`.** It sits beside `view-model.ts`, whose `needsYouItems` and `evidenceLines` it reuses. `boardOf(record, activity, { live, action })` returns the sentence, the state line, the progress, the list of large tiles, the plan steps and the decisions made. The large tiles stack in a fixed order: a question, a stop, live work. A result shows only when none of those do. A question and live work can both be present, because a decision parks only the steps that depend on it. An idle project has no large tile: the top tile already says nothing is running. Empty steps and decisions give no tile. Components only draw what it returns. Alternative considered: decide in each component, as today. That is what spread the state over `StateLine`, `NeedsYou` and `ProjectPage` and made the page hard to reason about.

**The hero sentence comes from saved text, newest first.** The newest of `overview.result`, `overview.acknowledgement` and `overview.objective` by its `at` time, else `overview.outcome`, else the user's idea. Live text is not used here: it belongs to the Live tile and changes every second.

**The state line reuses `projectActivity`.** Working and Waiting for you are fixed words. A stop reads Stopped, because its tile states the cause. Every other state shows the existing headline and owner line (Paused by you, Delivered, Last known), without the "Architect idle" suffix. Working is used only when this session observes work.

**Stopped is a main tile, not a fifth layout.** The cap field, Retry step, Resume, Open Room and Review access controls that `ProjectPage` puts in the header today move into this tile unchanged. The prototype has no stopped moment, so the tile reuses the Needs you tile's shape: a heading that states the stop, the saved reason, and the existing control.

**Live reuses the existing watch hooks.** The owner row uses `useOwnerLive`; Room members and Workflow steps use the feedback rows as `WorkLive` does now. One agent draws as the prototype shows. Several agents draw as a short list of rows in the same tile, each with its name, action and timer, and the arriving text of the one the user selects. Alternative considered: keep the eye toggle. Rejected: the user asked for live work to be obvious.

**Actions are said in plain words.** A small table maps a tool name to a phrase: `read` to "Reading", `edit`/`write` to "Editing", `bash` to "Running a command", `automation_browser` to "Using the browser", `codemode` to "Running a script". The tool's own summary is shown under it in small text. An unknown tool shows its name. This is a fixed label table, not interpretation of model output.

**The last few actions are kept by the plugin runtime.** The owner live notice gains `recent`: up to three finished tool calls of the current turn. `work-watch.ts` derives it from changes of the snapshot's tool, in the session subscription, so the host and `@sero-ai/common` do not change. It exists only while a view holds the watch lease, so a board opened in the middle of a turn starts the list from that moment. Alternative considered: add it to the host snapshot. Rejected for now: it is a host and published-package change for a three-line list.

**Decisions made is derived.** Rows, newest first: answered decisions (the chosen option's label, by the user), `working.assumptions` (by the Architect), then the start cap (by the user). An assumption becomes `{ text, why? }` so the row can show its reason. The `working` action accepts both forms, and a saved plain string reads as an assumption with no reason. Change on any row puts a short prefilled sentence in the message box and focuses it. It sends nothing itself.

**Glass surfaces.** New rules are prefixed `bd-` in a new `ui/board.css`. Tiles read the `--glass-*` tokens from `@sero-ai/ui`, with the dark values as fallbacks, so the board matches the Dashboard in both themes.

**The Work view keeps three tabs.** Live is removed from `WORK_TABS`. A stored `live` tab opens `plan`.

**Pictures come through one runtime request.** `picture` on the projects tool reads a PNG and returns it as a data URL. With a step id it reads that step's saved capture, and only inside the project's evidence folder. With no step it reads `.sero/tmp/automation-browser-shot.png`, where the browser tool saves a screenshot in a host workspace. The view passes the time of the picture it holds, so the same bytes are not sent twice. Live shows the browser screenshot only when it was saved during the current turn. Alternative considered: a file URL the view loads itself. Rejected: the request keeps the two readable paths in one checked place.

## Risks / Trade-offs

- [The header controls move, and a recovery control is lost in the move] -> the existing ProjectPage tests for cap, retry, resume and Open Room are kept and pointed at the board.
- [A project with no `overview` or `working` (charter flow) shows a thin board] -> the view-model falls back to the idea, `stateLine` and milestones, and the charter-flow notice stays.
- [The existing spec forbade live output on the overview] -> the requirement is replaced here on the user's instruction. The live text is the bounded end of the current turn, not a transcript.
- [One press answers a question, with no second step] -> the choices state their consequence on the button, and an answer can be reopened from Decisions made.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions openspec/changes/architect-decision-board/proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Proposal

## Why

The Architect project page does not say what is happening. It is one small card over an empty screen, the live work sits behind "Watch work" as a line of raw model text, and the plan, checks and decisions are spread over four tabs. A user cannot tell at a glance whether work runs, has stopped or needs them, and never sees the choices the Architect made for them.

## What Changes

- The project page becomes one board, drawn in the approved prototype `apps/styleguide/public/prototypes/architect-one-screen.html`. The prototype is the visual spec.
- The top tile always carries the Architect's own latest sentence, one state line (Working, Waiting for you, Stopped, Finished) and two small meters for progress and spend.
- One large tile shows the single thing that matters now: the open question, the live work, the stop and its fix, or the result.
- Live work is on the board while work runs: what is being done in plain words, a timer, the arriving text, and the last few actions. **BREAKING** for the spec: the overview no longer hides live output behind Watch work.
- Decisions made is a tile: the user's answers and limits, and the assumptions the Architect recorded, each marked with who decided. Change puts the decision into the message box.
- Plan is a side tile with one row per step. A checked step carries its proof picture and a link to its checks.
- A tile exists only when it has content. No placeholder tiles.
- A question is answered by pressing a choice. The separate Answer button goes.
- An assumption the Architect records can carry its reason, which the board shows.
- The Work view loses its Live tab. Plan, Research and Evidence stay as detail views reached from the board.
- The board uses the glass dashboard surfaces from `@sero-ai/ui`, so it matches the Sero Dashboard.

- Pictures: a checked step shows the screenshot its checks saved, the result shows the newest one, and Live shows the last screenshot the Architect took in its browser this turn. The runtime gains a `picture` request that reads those files.

Out of scope: the projects list, intake, History, the inspector, model settings, and a continuously updating view of the Architect's browser.

## Capabilities

### New Capabilities

None.

### Modified Capabilities

- `architect-ui`: the four-part project page and the separate Watch work view are removed. The board, live work on the board and decisions made are added. Decision cards answer on one press.

## Impact

- `plugins/sero-architect-plugin/ui`: `ProjectPage.tsx`, `StateLine.tsx`, `NeedsYou.tsx`, `WorkLive.tsx`, `WorkPage.tsx`, `styles.css`, the preview fixtures, and new board components.
- `plugins/sero-architect-plugin/ui/lib/board.ts`: a pure view-model that turns a record and its feedback into the board's tiles.
- `plugins/sero-architect-plugin/runtime/work-watch.ts`: the owner live notice keeps the last few finished actions of the turn.
- `plugins/sero-architect-plugin/shared`: an assumption may be `{ text, why }`. Saved plain-text assumptions still read.
- No new owner tool and no published package change.
106 changes: 106 additions & 0 deletions openspec/changes/architect-decision-board/specs/architect-ui/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Spec Delta

## ADDED Requirements

### Requirement: The project page is one board

The project page SHALL be one board that follows the approved prototype `apps/styleguide/public/prototypes/architect-one-screen.html`. A top tile SHALL always show the Architect's latest saved sentence, or the user's request when none is saved, with one state line, and meters for plan progress and spend. The progress meter SHALL appear only when a plan exists. Working SHALL be shown only for work this session has observed.

The state line SHALL read Working, Waiting for you or Stopped for those states, and otherwise the project's own state such as Paused by you or Delivered. Under the top tile the board SHALL stack the large tiles that apply, in this order: a decision or approval the user must give; a stop that needs the user, with its saved cause and its recovery control; work that is running. A delivered result SHALL be the large tile when none of those apply. A project with nothing to decide, recover, watch or deliver SHALL have no large tile. A Plan tile SHALL exist only when the project has plan steps, a written plan or research, and a Decisions made tile only when at least one decision exists. The board MUST NOT show an empty or placeholder tile. A message box for the Architect SHALL remain available.

A checked plan step SHALL link to its checks and show the picture those checks captured, when there is one. A delivered result SHALL show the newest of those pictures. While the Architect works, the live tile SHALL show the last screenshot it took in its browser during the current turn. Full plans, research, evidence, model settings, the inspector and history SHALL open as separate views. Every action on the board SHALL use the same authoritative tool action as the equivalent menu or detail control.

#### Scenario: Just started
- **WHEN** a project has started and has no plan and no question
- **THEN** the board shows the top tile, the live work as the large tile, and the user's start cap under Decisions made
- **AND** it shows no Plan tile and no progress meter

#### Scenario: A question is open
- **WHEN** the Architect has raised a decision
- **THEN** the large tile is the question with its choices and the state line reads Waiting for you
- **AND** no live tile is shown while nothing runs

#### Scenario: Work is running
- **WHEN** observed work is running and nothing needs the user
- **THEN** the large tile is the live work and the state line reads Working

#### Scenario: The cap stopped the work
- **WHEN** the project reaches its spending cap
- **THEN** the large tile states the stop and holds the field that raises the cap and resumes
- **AND** the state line reads Stopped

#### Scenario: Delivered
- **WHEN** every plan step is closed and at least one was accepted on evidence
- **THEN** the large tile is the result, with the Architect's result sentence and the ways to open the preview and the checks
- **AND** the state line reads Delivered

#### Scenario: Nothing to show is not a tile
- **WHEN** a project has no plan steps, written plan or research, or no decisions
- **THEN** that tile is absent and the remaining tiles use the space

#### Scenario: History is not on the page
- **WHEN** the board is open
- **THEN** history is reachable as a separate view and no history entries are on the board

### Requirement: Live work is on the board

While observed work runs, the board SHALL show it without a further click. For each agent that is working it SHALL show who it is, what it is doing in plain words with the tool's own short detail, and how long the current action has run. It SHALL show the arriving text of the Architect, or of the one agent the user selects when several work at once. For the Architect's own work it SHALL show up to three of the most recent finished actions. It SHALL link to the complete saved session. Showing live work MUST NOT alter execution or grant authority, and live text MUST NOT be saved by the board.

#### Scenario: The Architect works itself
- **WHEN** the Architect is editing files in its own turn
- **THEN** the live tile names the action, shows its timer and shows the Architect's text as it arrives

#### Scenario: Several agents work
- **WHEN** a Room has two members working
- **THEN** the live tile lists both with their actions and timers, and shows the text of the selected one

#### Scenario: Recent actions follow the work
- **WHEN** three of the Architect's own actions finish while the board is open
- **THEN** the live tile lists them, newest first, under the action in hand
- **AND** a new turn starts the list again

### Requirement: Decisions made are visible and can be reopened

The board SHALL list the decisions that shape the work: each answered question with the chosen option, each assumption the Architect recorded with its reason when it gave one, and the spending limit. Each row SHALL say whether the user or the Architect decided. Change on a row SHALL place a short message naming that decision in the message box and focus it. Change MUST NOT send a message or alter the project by itself.

#### Scenario: An assumption is shown
- **WHEN** the Architect records an assumption in its working plan
- **THEN** the board lists it as decided by the Architect

#### Scenario: Change opens a message
- **WHEN** the user presses Change on a decision
- **THEN** the message box holds a sentence that names the decision and has the focus
- **AND** nothing is sent until the user sends it

## MODIFIED Requirements

### Requirement: Decision cards

Each newly authored decision SHALL present one question, its reason, at most two choices with clear consequences, the recommended choice marked and an optional note. Saved decisions SHALL keep all original choices, identifiers, consequences and the original recommendation until answered, even when they contain more than two choices. Answering SHALL take one action: pressing a choice sends it. Consent-relevant information MUST remain visible. Supporting evidence and technical documents SHALL open separately. Routine internal technical choices, contained worker authorization and in-scope rechecking SHALL not become user decision cards. Architect SHALL continue eligible work within approved limits and raise a decision only when material uncertainty or required new authority prevents safe continuation.

#### Scenario: Answer in one action
- **WHEN** the user presses the recommended choice
- **THEN** the decision closes and authorized work can continue without another confirmation for that same decision

#### Scenario: Evidence is available
- **WHEN** the user wants support for a recommendation
- **THEN** the linked evidence opens outside the decision body without losing the pending answer

#### Scenario: Saved choices remain usable
- **WHEN** an older unanswered decision contains three choices
- **THEN** the card shows all three with their saved consequences and submits the selected original option id
- **AND** it does not hide a choice in the optional note, require a replacement decision or add another confirmation

## REMOVED Requirements

### Requirement: Project page shows four parts

**Reason**: Replaced by "The project page is one board". The four compact areas left the page nearly empty and put the live work behind a second view.

**Migration**: None for saved projects. The board reads the same record.

### Requirement: Watch work is a separate live surface

**Reason**: Live work is now on the project board, under "Live work is on the board". A separate view made the user look for it.

**Migration**: The Work view keeps Plan, Research and Evidence. A link or saved tab that names the live view opens the project board.
Loading
Loading