Cadora · design spec
Everything needed to rebuild or extend the human review surface — the exact tokens, the panel's anatomy, its states, and how it behaves. The rendered components are live HTML; edit them here or lift the specs into Figma.
Dark instrument surface · amber signals a human is needed
--amber · #ffd08aReview-gate accent--green · #16c784Approve · gate pass--red · #fb7185Abort · failure--blue · #3b82f6Document links--bg · #0f172aPage ground--canvas · #111c2fInset · doc rows--panel-2 · #162237Callout surface--line · #334158Borders--text · #f5f7fbPrimary--muted · #9aa8bcSecondary · captionsSystem sans for reading · monospace for the instrument voice
| Role | Family | Size / weight | Notes |
|---|---|---|---|
| Node / doc title | system-ui | 15px / 500 | Run and node names |
| Body · doc link | system-ui | 13px / 400 | Link color --blue, underline on hover |
| Label · badge · kind | mono | 10–11px / 600 | Uppercase, letter-spacing .05em |
| Time · duration | system-ui | 13px | HH:MM:SS · 2m 30s — never raw ISO |
| Metric | Value | Metric | Value |
|---|---|---|---|
| Card radius | 12px | Control radius | 8px |
| Pill radius | 999px | Callout border | 1px var(--amber) |
| Panel padding | 12–14px | Row gap | 6px |
| Button padding | 7px 15px | Doc row padding | 8px 10px |
The one component the whole journey turns on
The conversation row sits between the documents and the comments: a document picker, one input, and Ask / Revise. Ask answers in place; Revise rewrites the chosen document and re-surfaces it. Each is a real executor turn — style the reply area for streamed text and rendered markdown.
Every condition the panel must render
Default · gate open
Preview open
Submitting
Error · fail-soft
No changed documents
No changed documents surfaced
Resolved · advances
Asking · awaiting reply
Answered / revised
What each control does, and the rules that protect the reviewer
| Control | Action | Result on the run |
|---|---|---|
| Approve | POST decision approve | Node passes; run continues to the next gate. Comments (if any) pass downstream. |
| Request changes | POST request_changes + comments | Same stage re-runs with the comments in its prompt (up to 3 revisions). |
| Abort | POST abort | Run stops, recorded in the evidence pack. |
| Document link | Open the rendered file | Serves the live under-review doc from the run workspace. |
| Preview | Render the doc inline | No navigation; markdown rendered in the panel. |
| Ask | POST a question message | The parked run runs the executor scoped to the doc; the answer renders in the reply area. |
| Revise | POST a revision message | The executor rewrites the doc in place; the new draft is shown and re-surfaced for a decision. |
| Rule | Why |
|---|---|
| Auto-refresh pauses during review | The 5s poll never rebuilds the panel under the reviewer — no wiped comment, no missed click. |
| Fail-soft submission | A bad decision or empty required-comment returns a message in place; the gate stays open to retry. |
| Indefinite wait (--review-timeout 0) | An async reviewer can step away; the gate holds rather than failing closed. |
| Loopback + JSON-only POST | The write path is local and guarded; the surface is unauthenticated by design. |
Words are part of the design
| Do | Not |
|---|---|
| Sentence case — “Request changes” | Title Case — “Request Changes” |
| Name the outcome — “submitted: approve” | “Success!” |
| Say what to do — “Comments required to request changes” | “Invalid input” |
| 09:34:06 · 2m 30s | 2026-07-17T07:34:06.215495+00:00 |