diff --git a/docs/designs/decisions/ui/DL-418.md b/docs/designs/decisions/ui/DL-418.md
new file mode 100644
index 000000000..927c91d1a
--- /dev/null
+++ b/docs/designs/decisions/ui/DL-418.md
@@ -0,0 +1,6 @@
+---
+id: DL-418
+decision: "Compass loads its brand faces itself: `@font-face` rules in `tokens.css` for Space Mono (regular, bold), Departure Mono, and IBM Plex Mono from OFL files bundled under `apps/ui/src/design/fonts/`, `font-display: swap`; host-installed fonts are never assumed"
+status: "Active (Matt, 2026-10-07)"
+record: ../../ui/compass-brand-parity/design.md#a1--ship-the-brand-faces
+---
diff --git a/docs/designs/decisions/ui/DL-419.md b/docs/designs/decisions/ui/DL-419.md
new file mode 100644
index 000000000..2b666f98b
--- /dev/null
+++ b/docs/designs/decisions/ui/DL-419.md
@@ -0,0 +1,6 @@
+---
+id: DL-419
+decision: "Compass corners are square, as on rigel.build: the `--cx-radius-*` tokens and every `border-radius` declaration are deleted and a stylelint rule bans the property; this supersedes the radius values in ux-foundation D1"
+status: "Active (Matt, 2026-10-07)"
+record: ../../ui/compass-brand-parity/design.md#a2a--square-corners
+---
diff --git a/docs/designs/decisions/ui/DL-420.md b/docs/designs/decisions/ui/DL-420.md
new file mode 100644
index 000000000..778587089
--- /dev/null
+++ b/docs/designs/decisions/ui/DL-420.md
@@ -0,0 +1,6 @@
+---
+id: DL-420
+decision: "A live agent's state dot is a client-side join over the per-account `AccountSession` that the event stream keeps, projected through `agentDotState`, with comms presence as the fallback. On READY the order is waiting (presence WAITING) > done > idle; done means the last WORKING→READY time is after the agent's last-opened time, which is persisted per workspace in `localStorage`. No proto change"
+status: "Active (Matt, 2026-10-07)"
+record: ../../ui/compass-brand-parity/design.md#a3--agent-lifecycle-is-a-client-side-join-over-session-status
+---
diff --git a/docs/designs/decisions/ui/DL-421.md b/docs/designs/decisions/ui/DL-421.md
new file mode 100644
index 000000000..40990c282
--- /dev/null
+++ b/docs/designs/decisions/ui/DL-421.md
@@ -0,0 +1,6 @@
+---
+id: DL-421
+decision: "`StateDot` `working`/`waiting`/`done` cells follow the rigel.build renders (the other five glyphs keep their DL-150 cells); the glyph scales only by integers, 1× (9px) in dense spots and 2× (18px) in tree rows; the working pulse breathes between 0.7 and 1"
+status: "Active (Matt, 2026-10-07)"
+record: ../../ui/compass-brand-parity/design.md#a4--site-glyph-cells-and-an-integer-2-scale
+---
diff --git a/docs/designs/decisions/ui/DL-422.md b/docs/designs/decisions/ui/DL-422.md
new file mode 100644
index 000000000..d5bae1ca6
--- /dev/null
+++ b/docs/designs/decisions/ui/DL-422.md
@@ -0,0 +1,6 @@
+---
+id: DL-422
+decision: "The agent tree is a main view at `/agents`, the site's Manager tree as depth-indented agent cards, listed first in the left sidebar's view links and first in the palette's view destinations; the left-sidebar tree stays the compact navigator with the 2× state glyph"
+status: "Active (Matt, 2026-10-08)"
+record: ../../ui/compass-brand-parity/design.md#a5--the-agent-tree-the-highlight
+---
diff --git a/docs/designs/decisions/ui/DL-423.md b/docs/designs/decisions/ui/DL-423.md
new file mode 100644
index 000000000..7c95e03fb
--- /dev/null
+++ b/docs/designs/decisions/ui/DL-423.md
@@ -0,0 +1,6 @@
+---
+id: DL-423
+decision: "A channel message renders the rigel.build anatomy on `.msg` directly: author handle in text color, a kind tag (`AGENT`/`HUMAN`/`SYSTEM`), an `ASK` flag for an ask block and a `STEER` flag for an @-mention of an agent, time pushed right in faint, body in dim text; a human message sits on the raised surface with a 2px accent left rule. The `.msg-role` author colors and `--cx-author-system` are deleted"
+status: "Active (Matt, 2026-10-07)"
+record: ../../ui/compass-brand-parity/design.md#a6--message-anatomy
+---
diff --git a/docs/designs/decisions/ui/DL-424.md b/docs/designs/decisions/ui/DL-424.md
new file mode 100644
index 000000000..75de4f9a8
--- /dev/null
+++ b/docs/designs/decisions/ui/DL-424.md
@@ -0,0 +1,6 @@
+---
+id: DL-424
+decision: "Compass text entry uses the D3 primitives, each imported by the component that uses it: top search and the shortcuts search are `cx-search`, new-topic fields are `cx-input`, and the channel composer is a `textarea.cx-composer` that grows to its content up to 40vh (Enter sends, Shift-Enter inserts a newline, Enter during IME composition does nothing) with a primary `cx-btn` send; a new `--cx-border-field` (mute) edges text boxes"
+status: "Active (Matt, 2026-10-07)"
+record: ../../ui/compass-brand-parity/design.md#a7--text-entry-uses-the-primitives
+---
diff --git a/docs/designs/decisions/ui/DL-425.md b/docs/designs/decisions/ui/DL-425.md
new file mode 100644
index 000000000..eed67c537
--- /dev/null
+++ b/docs/designs/decisions/ui/DL-425.md
@@ -0,0 +1,6 @@
+---
+id: DL-425
+decision: "The topbar brand is the Compass needle mark alone at 24px, replacing the plain-text \"Compass\" name, with \"Compass\" as its accessible name; purple lives only in that SVG asset; `surfaces.md` Mark placement names the needle instead of the sigil wordmark"
+status: "Active (Matt, 2026-10-08)"
+record: ../../ui/compass-brand-parity/design.md#a8--the-compass-mark-in-the-top-bar
+---
diff --git a/docs/designs/decisions/ui/DL-430.md b/docs/designs/decisions/ui/DL-430.md
new file mode 100644
index 000000000..866438ebe
--- /dev/null
+++ b/docs/designs/decisions/ui/DL-430.md
@@ -0,0 +1,6 @@
+---
+id: DL-430
+decision: "Status greens and type weight follow rigel.build: `--cx-ci-pass` is the working green and `--cx-review-approved` is cyan (`--cx-ok` stays the syntax-tier green); chrome carries hierarchy by color, case, and letter-spacing, and a stylelint rule allows only weight 400 outside markdown headings"
+status: "Active (Matt, 2026-10-07)"
+record: ../../ui/compass-brand-parity/design.md#a9--site-greens-and-hierarchy-by-color
+---
diff --git a/docs/designs/decisions/ui/DL-437.md b/docs/designs/decisions/ui/DL-437.md
new file mode 100644
index 000000000..0edf3624c
--- /dev/null
+++ b/docs/designs/decisions/ui/DL-437.md
@@ -0,0 +1,6 @@
+---
+id: DL-437
+decision: "Compass surfaces follow rigel.build with stronger pane edges: shell chrome (topbar, both sidebars, the Session Log) sits on `--cx-bg` and pane heads on `--cx-bg-panel`; `--cx-border` is night-2 for lines inside a pane, and `--cx-border-strong` is selection and draws every pane edge (both sidebars, the Session Log, and the topbar's bottom edge)"
+status: "Active (Matt, 2026-10-08)"
+record: ../../ui/compass-brand-parity/design.md#a2b--surfaces-and-lines
+---
diff --git a/docs/designs/decisions/ui/DL-438.md b/docs/designs/decisions/ui/DL-438.md
new file mode 100644
index 000000000..84385a5e4
--- /dev/null
+++ b/docs/designs/decisions/ui/DL-438.md
@@ -0,0 +1,6 @@
+---
+id: DL-438
+decision: "Backlog and Done are Bridge segments that keep their list layouts: the control is `Issues | PRs | Backlog · N | Done`; `/backlog` and `/done` stay routed and render the Bridge on that segment, so every path, chord, and palette entry keeps working; the left sidebar drops both links; Issues/PRs stay the DL-097 local signal, and the board keyboard group runs only on them"
+status: "Active (Matt, 2026-10-08)"
+record: ../../ui/compass-brand-parity/design.md#a10--backlog-and-done-inside-the-bridge
+---
diff --git a/docs/designs/ui/compass-brand-parity/design.md b/docs/designs/ui/compass-brand-parity/design.md
new file mode 100644
index 000000000..fdcea9d16
--- /dev/null
+++ b/docs/designs/ui/compass-brand-parity/design.md
@@ -0,0 +1,754 @@
+# Design: Compass Brand Parity with rigel.build
+
+Builds on: [UX foundation](../compass-ux-foundation/design.md) (DL-148, DL-150, DL-184), [glyph primitives](../compass-glyph-primitives/design.md) (DL-367), [channels in the agent tree](../compass-channels-in-agent-tree/design.md)
+Refs: RIG-4774 (parent RIG-4770); RIG-1622 (agent tree); ledger DL-418 to
+DL-425, DL-430, DL-437, DL-438
+Depends on: #1811 (RIG-4771 chrome cleanup), #1814 (RIG-4772 session
+stream), #1644 (DL-399 local baselines)
+Siblings: RIG-4771 (chrome cleanup, pane edges), RIG-4772 (Session Log
+stream), RIG-4773 (Bridge toggle), RIG-4775 (Settings), RIG-4776
+(Backlog/Done; Matt's answer lands here as A10). This record does not redo
+their work.
+
+## Problem / Intent
+
+Matt's dogfood review: the Compass UI does not look like
+[rigel.build](https://rigel.build). The colors look bad, the agent status
+icons do not show, messages are plain text, the composer does not read as a
+composer, and the top search, new-topic name, and first-message fields look
+unstyled. This record finds the concrete causes in `apps/ui/src/` and plans
+eleven small PRs that bring Compass to the marketing site's look, with the
+agent tree as the highlight. Matt's RIG-4776 answer on the Backlog and Done
+views is folded in as A10.
+
+Out of scope: Settings (RIG-4775), usage display (RIG-4771 deletes
+`UsageBar`), and the pane-edge rules themselves.
+PR #1811 (RIG-4771) puts the `.right` and `.log-panel` edges on
+`--cx-border-strong` and hands the token values back to this record; T2b
+sets them.
+
+## Approach
+
+The reference is the public site: [rigel.build](https://rigel.build) and
+[rigel.build/compass](https://rigel.build/compass), whose shipped CSS uses
+the same `--rigel-*` primitive values as `apps/ui/src/design/tokens.css`
+(night `#011627`, panel `#0e2a45`, night-2 `#0b2942`, fog `#d6deeb`, haze
+`#89a4bb`, mute `#5f7e97`, blue `#82aaff`). The primitives already match.
+The gaps are in five places: fonts that never load, a surface and line model
+that hides edges, semantic aliases and weights that differ from the site,
+component CSS that is never imported, and an agent-state data path that
+drops most states. A10 is not a site gap: the site has no Backlog or Done
+view. It carries Matt's RIG-4776 answer.
+
+### Gap audit
+
+| Site element (rigel.build) | Compass today | Gap | Task |
+| --- | --- | --- | --- |
+| Brand faces load from `@font-face` (`/fonts/SpaceMono-Regular.ttf`, `/fonts/DepartureMono-Regular.otf`) | No `@font-face` anywhere under `apps/ui`; `--cx-font-ui: var(--rigel-mono)` names Space Mono, but nothing loads it, so the host falls back to `ui-monospace` | The whole UI renders in the wrong face outside CI (CI pins the faces through fontconfig, so baselines hide it) | T1 |
+| Display face for headings (`.bridge-heading` in Departure Mono 22px) | `--cx-font-display` is used by one rule in `app.css`; the face never loads | Fixed when the face loads | T1 |
+| Square corners everywhere: cards, inputs, `.seg`, and square status pips (`.dot` 10×10, `.ci-badge` 7×7) | `--cx-radius-sm/md/lg` are 3/6/10px, used by 57 declarations; 26 more literal radii (`.tree-agent` 4px, `.bridge-link .count` 10px, round pips at 50%, 999px pills) | Rounded corners and round pips are off-brand | T2a |
+| Night-2 hairlines drawn on the night page (`html,body{background:var(--rigel-night)}`, `.topbar{border-bottom:1px solid var(--rigel-night-2)}`); raised is kept for cards, menus, the root card, and the human message | Topbar, `.left`, `.right`, and `.log-panel` sit on `--cx-bg-raised`; `--cx-border` is `color-mix(in srgb, var(--rigel-panel) 70%, transparent)`; night-2 and raised are the same hex (`#0b2942`) | Pane edges barely show; the site's own line color would vanish on raised chrome | T2b |
+| Form input: raised ground, mute border, 11×14 padding, blue border on focus (site `input` rule) | Text boxes have no visible edge | No field border token | T7 |
+| CI success badge in green, approved review in cyan (selectors in A9) | `--cx-ci-pass` and `--cx-review-approved` both resolve to `--cx-ok`, the syntax-tier `--rigel-success` (`#22da6e`) | Wrong greens on every board card | T9 |
+| Hierarchy by color, case, and letter-spacing; no `font-weight` outside `@font-face` | 48 `font-weight: 600/700/bold` rules in `app.css`; Space Mono ships 400 and 700 only and `base.css` sets `font-synthesis: none`, so every 600 renders bold | Chrome reads heavy and loud | T9 |
+| Agent state glyph: 9×9 cells drawn at 16px (`.ac-glyph svg{width:16px;height:16px}`), state-colored, state label beside it; alive glyphs pulse 0.7→1 (`ac-pulse`) | `StateDot` draws 9×9 CSS px; live data reaches only 4 of 8 states; most rows show a grey hollow square; `cx-state-dot-pulse` dips to 0.4 | Icons "do not show" (root cause below) | T3, T4 |
+| Manager tree: depth-indented agent cards with spine elbows, glyph, name, colored state label, issue chip; root card raised with a 2px blue left rule; a blue pip runs down live spines (`spine-flow 1.4s` on `.tree-spine[data-flow="1"]`) | Left-sidebar text rows (`.tree-agent`, 12px name, 9px dot); `.tree-children` is a static 1px rule; no overview | No agent overview, no tree motion | T5 |
+| Thread message: author in fog 12px, kind tag (`MANAGER`, `HUMAN`), `ASK` flag in blue and `STEER` flag in cyan (`.msg-flag.ask`, `.msg-flag.steer`), time right-aligned in mute, body in haze 13px; human messages on raised with a 2px blue left rule | `.msg-role` colors authors blue (`--cx-accent`), bright green (`--cx-ok`), or magenta (`--cx-author-system`), weight 600; `.msg-at` sits beside the name; no tag or flag | Messages read as plain text with loud names | T6 |
+| (no composer on the site; the site `input` rule is the reference) | `Composer` is a one-line ``; its border is `--cx-border` on `--cx-bg-raised` | Composer does not read as a composer | T7 |
+| Text inputs | `.new-topic-name`/`.new-topic-message` carry only flex sizing (browser-default box); `.topbar-search-input` has no `font: inherit` and a faint border | Fields look unstyled | T7 |
+| (site CSS is all loaded) | Six primitives are never imported: `ask`, `badge`, `input`, `loader`, `panel`, `tree`. Two have users today: `ShortcutsOverlay` renders `cx-search`, and `Palette` renders `.cx-loader[data-topology="bar"]`; both are unstyled | Users of an unimported primitive fail silently | T7 |
+| Compass needle mark (`/compass-c-needle.svg`, purple north half on the navy tile) | Top bar shows the 11×11 `logo` `Glyph` in `--cx-accent` blue beside a plain-text "Compass" | Product mark missing | T8 |
+
+### Why the status icons do not show
+
+The SVG itself is fine: `StateDot` (`apps/ui/src/components/StateDot.tsx`)
+emits a `viewBox="0 0 9 9"` `crispEdges` SVG of `rect` cells filled with
+`currentColor`, and `state-dot.css` colors it per `data-state`. The cause is
+upstream and in sizing:
+
+1. **The live set is coarse.** Every agent row renders
+ `` (`AgentLeaf` in
+ `LeftSidebar.tsx`). `lifecycle` comes from `joinAgents`
+ (`apps/ui/src/roster.ts`): `lifecycle: info ? info.lifecycle : "stopped"`,
+ where `info` is the comms presence entry. Presence is a 4-value enum
+ (`AgentPresence` in `proto/compass/v1/comms.proto`: IDLE, WORKING,
+ WAITING, OFFLINE), and `presenceLifecycle` (`apps/ui/src/live/adapt.ts`)
+ maps `OFFLINE → "stopped"`. The server's `presenceFor`
+ (`go/internal/presence/presence.go`) folds STOPPED, ERRORED,
+ DISCONNECTED, and "no session" into OFFLINE. So live Compass can only
+ show working, idle, waiting, and stopped. Done, paused, error, and
+ disconnected never render.
+2. **The full session state is dropped.** `AgentSessionStatus` (with its
+ `state`) does arrive on `SubscribeEvents`, but on main `applyPayload` in
+ `runEventStream` (`apps/ui/src/live/events.ts`) keeps only
+ `runtime.set(account, adaptRuntimeMarker(payload.value))`.
+ `adaptRuntimeMarker` documents that "the identity/lifecycle fields the
+ status also carries are the presence path's job". #1814 (RIG-4772) keeps
+ the state for the Session Log, but nothing feeds it to the dot.
+ `agentDotState` (`apps/ui/src/agent-state.ts`), the 8-state projection
+ built for this, has no production caller.
+3. **Most rows are grey.** Any agent without a live session is "stopped": a
+ hollow outline in `--cx-st-stopped` (`--rigel-mute`). Idle is a mute
+ block too. In a fleet that is mostly idle or offline, the colored glyphs
+ (green `»`, amber `?`, cyan tick, red `!`) almost never appear.
+4. **The glyph is small.** `.cx-state-dot` is `width: 9px; height: 9px`
+ (`state-dot.css`). The brand spec names "the 12px row-dot size"
+ (`docs/specs/brand/state-icons.md`), and the site draws the tree glyph at
+ 16px.
+5. **Geometry drifted.** The site's cells for `working`, `waiting`, and
+ `done` differ from `STATE_CELLS` (A4 lists them). `idle` matches.
+
+### A1 — Ship the brand faces
+
+Load Space Mono (regular, bold), Departure Mono, and IBM Plex Mono with
+`@font-face` in `tokens.css`, from font files under
+`apps/ui/src/design/fonts/`. The files are the OFL faces already committed
+in `apps/eng-docs/public/fonts/`. Vite bundles them as assets for both hosts.
+`font-display: swap`, as on the site.
+
+CI pins the faces through fontconfig (`fontDirs` in
+`tools/toolchain/chromium-e2e-env.nix`: nixpkgs `google-fonts` Space Mono and
+`departure-mono`). The `SpaceMono-Regular.ttf`, `SpaceMono-Bold.ttf`, and
+`DepartureMono-Regular.otf` files in `apps/eng-docs/public/fonts/` have the
+same SHA-256 as those nixpkgs files, so the glyph outlines in CI do not
+change. Shots can still differ if Chromium rasterizes a webfont differently
+from a system face; T1 treats any diff as expected and recaptures.
+
+### A2a — Square corners
+
+The site draws no rounded corner except one footer tile, and its status pips
+are square (`.dot` 10×10, `.ci-badge` 7×7). `docs/specs/brand/surfaces.md`
+asks for "flat square cards". Compass has 57 `var(--cx-radius-*)`
+declarations and 26 literal radii in CSS, including `.tree-agent` 4px, the
+round pips (`border-radius: 50%`), and 999px pills. `boot-styles.ts` sets one
+more, `border-radius:4px`, in a TypeScript style string.
+
+Delete `--cx-radius-sm`, `--cx-radius-md`, and `--cx-radius-lg` from
+`tokens.css`, and delete every `border-radius` declaration under
+`apps/ui/src`. A stylelint rule keeps the CSS that way; it does not read
+`boot-styles.ts`, so T2a edits that file by hand. Three tokens all set to 0
+would be dead weight, and would still leave the 26 literal radii. This
+supersedes the radius line of ux-foundation D1 ("Radius:
+`--cx-radius-sm|md|lg` (3/6/10)").
+
+### A2b — Surfaces and lines
+
+The site draws night-2 lines on night ground: `html,body` are night,
+`.topbar` has `border-bottom:1px solid var(--rigel-night-2)`, and its product
+mock puts thread and lane heads on panel. Raised is kept for cards, menus,
+the root agent card, and the human message. Compass puts all chrome on
+`--cx-bg-raised`: `.topbar`, `.left`, `.right`, and `.log-panel`. Night-2 and
+raised are the same hex (`#0b2942`), so the site's line color is invisible
+on Compass chrome. `--cx-border` (panel at 70%) and `--cx-border-strong`
+(panel) are within a few levels of raised, which is why the pane edges in
+the ask do not show. Note that `apps/ui/src/design/surfaces.md` already
+puts the topbar on `--cx-bg`, so `app.css` has drifted from its own spec.
+
+Compass takes the site's surface model with pane edges one step stronger
+(DL-437). Chrome (`.topbar`, `.left`, `.right`, `.log-panel`) moves to
+`--cx-bg`, and heads (`.conv-head`, `.av-pane-head`) to `--cx-bg-panel`.
+`--cx-border` becomes night-2, the site's line, for lines inside a pane.
+`--cx-border-strong` becomes selection and draws every pane edge: 1.57:1 on
+night, against the site's 1.23:1. #1811 puts the `.right` and `.log-panel`
+edges on it; T2b moves the `.left` and `.topbar` edges from `--cx-border` to
+it, or the left edge would be night-2 on night. No new surface token.
+Keeping raised chrome with selection and mute lines was rejected: it is not
+the site's look. A separate new token, `--cx-border-field: var(--rigel-mute)`,
+is the site's input edge, used only by `input.css` (A7).
+
+### A3 — Agent lifecycle is a client-side join over session status
+
+T3 builds on #1814 (RIG-4772). That PR keeps one `AccountSession
+{ sessionId, state }` per agent account from `AgentSessionStatus` events in
+`runEventStream`, emits it through `onSessions`, clears it on resync, and
+stores it as `accountSessions`. T3 adds no second map. It projects that map
+through `agentDotState` in `joinAgents`:
+
+| Inputs for an account | `lifecycle` |
+| --- | --- |
+| session known | `agentDotState(session.state, { awaitingInput, turnDoneUnopened })` |
+| no session, presence entry | `presenceLifecycle(presence)` (today) |
+| neither | `"stopped"` (today) |
+
+- `awaitingInput` is `presence?.lifecycle === "waiting"`. The server sends
+ presence WAITING for STARTING or READY with an open ask (`presenceFor`).
+ Today `agentDotState` reads `awaitingInput` only for STARTING and WORKING;
+ READY returns `turnDoneUnopened ? "done" : "idle"`. T3 changes the READY
+ arm so the order is **waiting > done > idle**. Without that change the
+ join would turn every waiting agent grey.
+- `turnDoneUnopened` is `turnEndedAtUnixMs > lastOpenedAt(account)`.
+ - `AccountSession` gains `turnEndedAtUnixMs?: number`. `applyPayload` sets
+ it to the event time (`SubscribeEventsResponse.at_unix_ms`) when the
+ account's previous state in the map is WORKING and the new state is
+ READY. Other events for the same `sessionId` carry the previous value.
+ - `lastOpenedAt` is a per-agent time persisted in `localStorage` under
+ `compass.lastOpened.${workspace}`, the same shape as the pin store
+ (`loadPinnedAgents`/`savePinnedAgents`). One store effect writes it:
+ while the focused view's route is `view === "agent"`, it records
+ `max(Date.now(), turnEndedAtUnixMs)` for that agent, and again on each
+ new turn end. The `max` stops a client clock behind the server from
+ leaving the tick on. The effect keys on the route, not on `openAgent`,
+ so every way in counts: `openAgent`, a Mod-click or middle-click
+ (`dispatchLayout` open), a deep link, a tab focus, back/forward, and an
+ agent DM. A background tab open does not focus the view, so it does not
+ count.
+ - Because both sides are times, a cold-start ring replay and a page reload
+ give the same answer as the live stream. A resync clears the map; the
+ replay re-observes the edge with its original time. The residual: an
+ agent whose WORKING event fell out of the 1024-event ring shows `idle`,
+ not `done`.
+
+No proto change. Done, error, and disconnected become reachable, and
+waiting is kept. There is no cold-start seed: `GetAgentStatus` is
+admin-only (`classifyProcedure` in `go/internal/auth/admin_gate.go`) and its
+snapshot drops STOPPED and ERRORED (`isTerminal` in
+`go/internal/board/projection.go`). An agent whose last status left the ring
+shows its presence state. A server status read open to the owner is filed
+only if dogfood shows a missing `error`.
+
+### A4 — Site glyph cells and an integer 2× scale
+
+Replace the `working`, `waiting`, and `done` entries of `STATE_CELLS` with
+the site's cells. Site `working` is two 5-cell chevrons
+(`1,2 4,2 2,3 5,3 3,4 6,4 2,5 5,5 1,6 4,6`); Compass draws two 7-cell
+chevrons over rows 1-7. Site `done` is a 7-cell tick
+(`1,4 2,5 3,6 4,5 5,4 6,3 7,2`); Compass draws 9 cells. Site `waiting` is
+`3,1 4,1 5,1 2,2 6,2 6,3 4,4 5,4 4,5 4,7`. The other five glyphs have no
+site render and stay. `StateDot` gains `scale?: 1 | 2`; `2` sets
+`data-scale="2"` and an 18px box. Integer scale keeps every cell a whole
+2×2 block; the site's 16px is a non-integer 1.78×. The sidebar tree and the
+agent tree (A5) use 2×; dense spots (right-sidebar tab badge, Bridge cards,
+agent header) keep 1×.
+
+The site's working glyph breathes from 0.7 to 1 (`ac-pulse`). Compass
+`cx-state-dot-pulse` dips to 0.4, which reads as blinking. Set the low
+point to 0.7.
+
+### A5 — The agent tree, the highlight
+
+The tree is a main view at `/agents` (DL-422), first in the left sidebar's
+view links and first in the palette's view destinations. It is deep-linkable
+and a top-level window per DL-160. A Bridge `Tree` segment and a
+sidebar-only restyle were rejected. The view draws the site's Manager tree
+from `agentTree(store.agents())` (`stub-data.ts`):
+
+- Row: `padding-left: depth × 26px`, with a 1px elbow spine in
+ `--cx-border` to the parent (site `.tree-row`, `.tree-spine`).
+- Card: grid `20px 1fr auto`; 2× `StateDot`; handle; meta line with
+ `AGENT_STATE_LABEL[state]` in the state color; issue chip on the right. No
+ child count: the site's `N workers` counts dispatched workers, Compass has
+ no live worker source, and the spine already shows child agents.
+- Root cards: raised ground and a 2px `--cx-accent` left rule.
+- Issue chip (`agentIssueChip`): the agent's active issues
+ (`assignee === account.id && isActiveState(state)`); none → no chip; one →
+ `issueKey(issue, multiForge)`; more → `N open`.
+- Spine flow: a spine to a `working` child carries `data-flow="1"`, and a
+ 1×6px `--cx-accent` pip runs down it (site `spine-flow`, 1.4s). This is the
+ chase-light pip that ux-foundation D6 names in the Manager-tree reference.
+ It is the view's one unbounded motion; the state-dot column stays the
+ sanctioned exception (`apps/ui/src/design/motion.md`, Budget). The period
+ is a new token zeroed under reduced motion, like `--cx-pulse-period`.
+- Click or Enter on a card calls `store.openAgent(account.id)`.
+
+The sidebar tree stays the compact navigator and gets the 2× glyph (A4).
+
+### A6 — Message anatomy
+
+`MessageRow` (`ChannelView.tsx`) is the only emitter of `.msg`, and the agent
+view's chat goes through the same `ChannelView`, so the rules restyle `.msg`
+directly with no extra scope. The row emits the site anatomy:
+
+- `.msg-author`: handle, `--cx-text`, `--cx-text-sm`.
+- `.msg-tag[data-kind]`: `AGENT`, `HUMAN`, or `SYSTEM` from the author's
+ `kind`; 1px border, `--cx-text-xs`, letter-spaced. The site says
+ `MANAGER`; Compass uses its own domain word.
+- `.msg-flag`: `ASK` (`--cx-accent`) when the message has an ask block, and
+ `STEER` (new `--cx-msg-steer`, cyan) when a text block @-mentions an agent
+ account. The `Composer` doc defines an @-mention of an agent as a steer.
+- `.msg-at`: pushed right (`margin-left: auto`), `--cx-text-faint`.
+- Body: `--cx-text-dim` at `--cx-text-md`. A human message gets
+ `--cx-bg-raised` and a 2px `--cx-accent` left rule, with body in
+ `--cx-text`.
+
+Delete the `.msg-role` color rules and `--cx-author-system`; nothing else
+uses them.
+
+### A7 — Text entry uses the primitives
+
+Each component imports the primitive CSS it uses, as `RuntimeMarker.tsx`
+imports `runtime-marker.css` and `LayoutNotice.tsx` imports `button.css` and
+`toast.css`. Six primitives are never imported today. This wires the two
+that have or gain a user (`input`, `loader`) and adds a `button.css` import
+where `ChannelView` starts to render `cx-btn`. The four with no user (`ask`,
+`badge`, `panel`, `tree`) stay unimported until a component first renders
+them; importing unused CSS adds bytes and no fix.
+
+- `TopBarSearch` imports `input.css`; its input → `cx-search`.
+- `ShortcutsOverlay` imports `input.css`; its `cx-search` field starts
+ rendering as designed.
+- `Palette` imports `loader.css`; its `.cx-loader[data-topology="bar"]`
+ starts rendering.
+- `ChannelView` imports `input.css` and `button.css`.
+ - `NewTopic` name and first-message inputs → `cx-input`; start button →
+ `cx-btn`.
+ - `Composer` → `