Skip to content

feat(architect): the project page is one board for decisions - #627

Draft
monobyte wants to merge 8 commits into
feat/improve-architect-orchestrator-autonomyfrom
feat/architect-decision-board
Draft

monobyte wants to merge 8 commits into
feat/improve-architect-orchestrator-autonomyfrom
feat/architect-decision-board

Conversation

@monobyte

@monobyte monobyte commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Stacked on #624. The base is feat/improve-architect-orchestrator-autonomy, so this diff is only the board. It rebases onto main when #624 merges.

What this does

The Architect project page becomes one board. It follows the approved prototype apps/styleguide/public/prototypes/architect-one-screen.html. OpenSpec change: architect-decision-board.

  • The top tile always says where things are, in the Architect's own words, with one state line and two small meters.
  • One large tile shows what matters now: the question, the stop and its fix, the live work, or the result.
  • Plan and Decisions made exist only when they have content.
  • Live work is on the page. The Work view loses its Live tab and keeps Plan, Research and Evidence.
  • A question is answered by pressing a choice.
  • An assumption the Architect records can carry its reason. The board lists it as "Architect" under Decisions made.
  • Pictures. A checked step shows the screenshot its check saved, and the result shows the newest one. Live shows the last screenshot the Architect took in its browser during the current turn. The runtime reads the files through a new picture request, which refuses anything outside the project folder.

Prototype (left) and built (right)

Moment Prototype Built
Just started
Needs you
Working
Finished

States the prototype does not draw:

Stopped at the cap A Room with two agents
Paused Waiting on a check

Differences from the prototype that stay

  • The top bar keeps Open session and the project menu.
  • The progress meter reads "steps done".
  • A question keeps its optional note field.

Seen in the running app

One real project was run on 2026-10-08 with apps/desktop/e2e/architect-story.agent.spec.ts: a Sudoku game, a research Room first, then a Workflow, on deepseek-flash. It ran 45 minutes and spent $1.16. Four pictures are in openspec/changes/architect-decision-board/evidence/real-run/.

Seen working with real data: the Live tile with the Architect's own text and its last three actions, the Room's members listed by name, and the proof picture on a checked step.

Changed after that run (8a27264, d4b91b7): Room faces on the Live rows, no clocks, a fixed box for arriving text, a state line that says who is at work, Decisions made as a list under the plan, the host's type tokens, and "Approve the start" while the start prompt is open.

Not verified here

  • The Architect's last browser screenshot in Live has only been seen in the preview harness. The real run's Architect never used its browser.
  • No decision was asked in the real run, so the Needs you tile has not been seen with real data.
  • The Room faces are seen in the preview harness only. The real project had no live Room after the rebuild.

Found by the real run, not fixed here

  • A Room's answer arrives with no sign on the board.
  • The earlier-action lines show raw commands.
  • A Workflow step on the board does not say which of its own steps runs.
  • The Live tile looks different for the Architect, a Room and a Workflow.
  • The first press on "Open the Room" lands on the Orchestrator's home list.
  • A host prompt that blocks the run has no sign on the board.
  • A project paused before the app closes reopens as "Stopped", not "Paused by you".

Review

Two rounds with gpt-6-astra at high effort, both posted below. Round 1 found six defects. Five are fixed. The sixth, a Room member showing no earlier actions, is settled by narrowing the spec to the Architect's own work, because a member's snapshot has no history of finished tools. Round 2 found three defects in the fixes, all fixed. The two commits made after the real run are in a third round.

Checks

  • Architect plugin: 856 tests pass.
  • Root pnpm typecheck --force: 29 of 29.
  • React Doctor, last run before the picture commits: one new warning, the number of conditional tiles in BoardColumn. Two older warnings are unchanged.

Adds the approved prototype and the OpenSpec change architect-decision-board.
The top tile always says where things are in the Architect's words. One
large tile shows what matters now: the question, the stop and its fix, the
live work, or the result. Plan and Decisions made appear only when they
have content. Live work is on the page, so the Work view loses its Live tab.

An assumption can carry its reason, and the owner live notice keeps the
last three finished actions of the turn.

OpenSpec change: architect-decision-board
… it waits on a check

The wait card is drawn as a board tile.
@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

React Doctor found 2 new issues in 1 file · 2 warnings · score 93 / 100 (Great) · 0 fixed · vs feat/improve-architect-orchestrator-autonomy

2 warnings

ui/ProjectPage.tsx

  • ⚠️ L281 React function has high control-flow complexity no-high-complexity-react-function
  • ⚠️ L318 React function has high control-flow complexity no-high-complexity-react-function

Reviewed by React Doctor for commit d4b91b7. See inline comments for fixes.

…t sees

A step's saved capture shows on the step and on the result. The last
browser screenshot shows in Live for the current turn. The runtime reads
both through a new picture request, which only reads inside the project's
own evidence and browser folders.

Also fixes six review findings: a tool already running when the watch
opens is counted, an open decision no longer hides a stopped Workflow's
controls, Plan and Research are reachable before any step exists, the wait
tile cannot say Working without live work, and the top sentence uses a
newer outcome.
@monobyte

monobyte commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator Author

Review round 1 (gpt-6-astra, high)

Paths below are relative to plugins/sero-architect-plugin.

1. Runtime

  • runtime/work-watch.ts:128–134 — misses an already-running tool. Open the board while a tool is running, then let the next session event be that tool’s end. The initial snapshot displays the tool, but never seeds lastTool; the end event therefore adds nothing to recent actions. This also violates “Recent actions follow the work.”

2. UI

  • ui/lib/board.ts:162, ui/ProjectPage.tsx:285 — an open decision hides independent recovery controls. With an unanswered decision and a failed Workflow below the project cap, projectActivity returns waiting-for-you. Because asks is true, the board omits the stopped tile entirely. The previously available Workflow-cap field, Retry step, or Restart the Workflow disappears, depending on the failure. The saved stop is hidden too.

  • ui/ProjectPage.tsx:345–347 — saved research and working plans can become unreachable. An approved project can have working.approach and completed research before it has milestones. With no milestones, approvals, or evidence, there is no Full plan link or other entry into the Work tabs. The previous Watch work entry provided that route. This violates the requirement that full plans and research remain accessible as separate views.

  • ui/ProjectPage.tsx:287, ui/components/WaitCard.tsx:23–32 — shows “Working” without live work. Keep a previously satisfied wait whose wake has been consumed, with no current blockers, then reopen with runtimeRunning=false. The page still renders WaitCard; its record-only derivation returns “Working” (ui/lib/wait-status.ts:111–114). This violates “Working SHALL be shown only for work this session has observed.”

3. Additional spec mismatches

  • ui/lib/board.ts:100–103 — the top sentence is not necessarily the latest saved sentence. Save an objective, then save a newer outcome. The sort excludes overview.outcome, so the board continues showing the older objective. This violates “The project page is one board.”

  • ui/components/BoardLive.tsx:74–80 — Room members never show recent actions. Select a working Room member and let three tools finish while the board remains open. MemberNow always supplies recent: [], so none appears under “Just before.” This violates “Recent actions follow the work.”

Status at 4dc7b5f

Findings 1 to 5 are fixed. Finding 6 is settled by narrowing the spec: recent actions are shown for the Architect's own work, because a Room member's snapshot carries no history of finished tools.

…stays current

A picture file that is a link to somewhere outside the project folder is
not read. The result shows the proof of the step checked last, not the
step listed last. A short browser call that ends between two updates now
makes the board ask for the new screenshot.
@monobyte

monobyte commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator Author

Review round 2: the fixes (gpt-6-astra, high)

Paths are relative to plugins/sero-architect-plugin.

  1. runtime/project-picture.ts:24–29,40–44 — symlinks escape containment. Make .sero/tmp/automation-browser-shot.png a symlink to a readable file outside the project, then call picture without a milestone. Both filesystem operations follow the symlink, returning the outside file’s bytes as base64. An evidence capture replaced with a symlink escapes likewise. Normalizing .. and checking the absolute-path prefix does not prevent this.

  2. ui/ProjectPage.tsx:283 — the result selects by milestone order, not picture age. With milestones ordered [M1, M2], let independent M2 finish and capture first, then M1 finish and capture later. Once both are delivered, findLast selects M2’s older picture instead of M1’s newest picture.

  3. ui/components/BoardLive.tsx:67 — a short screenshot call can leave the picture stale. After three owner actions have finished, let a screenshot call start and finish within one 200 ms watch-push interval. The snapshots before and after both have the same turn, no running tool, and recent.length === 3. The picture hook’s key therefore does not change, so no new picture request runs. While the owner subsequently streams text, the previous picture—or no picture—remains displayed.

Status at 1314c0c

All three are fixed. The reader resolves links and refuses a file outside the project folder. The result picks the step with the latest check time. The watch now sends a count of finished tool calls, and the picture is asked for again when the count changes.

…sions under the plan

A real Sudoku project was followed from the request to its check, and the
board was changed for what the run showed.

- Live rows show the face the Room gives each member.
- The clocks are removed. They timed one model call and reset every few seconds.
- Arriving text sits in a box of fixed height, so the tiles below do not move.
- The state line says who is at work, not the action in hand.
- Decisions made is a list under the plan. A row opens to show its reason.
- Text sizes are the host's text-xs, text-sm and text-base.
- While the start prompt is open the board says "Approve the start".

architect-story.agent.spec.ts is the gated capture run that produced the pictures.
}

/** The large tiles that apply now, in their fixed order, then the decisions made. */
function BoardColumn({ record, actions, page, board, activity, wait, rows, notice, headerActions, onOpenWork, onChangeDecision, hasPlan, asking }: BoardColumnProps) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Doctor · react-doctor/no-high-complexity-react-function (warning)

BoardColumn has cyclomatic complexity 21, cognitive complexity 15, and maximum nesting depth 1, so its React logic is hard to understand and change. Extract independent branches into components or hooks.

Fix → Extract independent render branches and state logic into focused components or hooks until the control flow is easy to follow.

Docs

);
}

export function ProjectPage({ record, actions, onBack, onOpenModels, onOpenInspector, onOpenHistory, onOpenWork, confirm, runtimeRunning, permissionPending = false, startRefusal = null }: ProjectPageProps) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Doctor · react-doctor/no-high-complexity-react-function (warning)

ProjectPage has cyclomatic complexity 18, cognitive complexity 16, and maximum nesting depth 1, so its React logic is hard to understand and change. Extract independent branches into components or hooks.

Fix → Extract independent render branches and state logic into focused components or hooks until the control flow is easy to follow.

Docs

@monobyte

monobyte commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator Author

Review round 3 (gpt-6-astra, high effort)

Scope: 99c5b3125..d4b91b7c9, the board changes made after the real run and the capture spec. Six questions: the decisions list as <details>, the fixed-height live text box, liveSummary, the open-prompt path, the decisions tile moving under the plan, and the removed clocks.

Result: no defects found that fail now on a reachable path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant