Refined control surface for an agentic chat session: read from many sources,
write to one, capture the session to the ledger. Below: the fullscreen surface, the inline + PiP +
periodic-reminder forms, and every state (pending / empty / error / abort-confirm). Semantic tokens throughout;
light/dark via data-mode.
Fullscreen · the control surface
Alt C is the canonical surface (earlier two-rail and owner-grouped studies removed). Read from many sources, write to one, capture the session to the ledger. Selected sources show as removable chips; + Add source opens a type-to-filter palette across all sources, so it never renders dozens of rows. Read = multi-select; write = a single dropdown (cardinality-honest). Privacy lock on private KBs; the write-target visibility tier is spelled out.
Why Alt C (ui-designer + perceptual-UX review): the palette is
closed by default (chips + +Add only). Favorites are the fast-path: the ≤10 amber ★ (a 4th hue → a
preattentive pop-out) pre-fill the palette before any keystroke and are the pre-checked default read-set on a fresh
session — turning "45 sources" into "10 stars + a search box". Scope presets: ★ Favorites (default) · All (45)
· Custom — "All" exists but isn't default (reading 45 dilutes retrieval + burns context). Agentic NL scope: a
user saying "read from all marketing, GTM & product-shipping bubbles, none others" → the model resolves
names→bubble IDs over ListBubbles and calls a set-session-scope tool; the provenance line ("Set from
your message — …") shows it back, and re-opening the card mirrors exactly that set. Keystone dependency: this
NL↔card↔reads round-trip requires per-session scope persistence (a store keyed by the MCP session id) — the
server is memoryless today, so without it the card shows defaults, not the NL selection. That store + the
set-session-scope tool is the real backend work to close the loop. Write stays a single dropdown (cardinality-honest);
the privacy tier + prospective-change note must survive the collapse. A 150ms calm copper fill confirms a write-target
switch (change-blindness guard).
In-thread strip · auto-surfaced (session-start + periodic)
This is the whole inline surface — there is no separate "inline status row" vs "recording reminder";
they're one strip. It shows session scope (read → write) + capture state + dest, with Manage to expand to the full
control surface. The server attaches it to tool results on a cadence (we can't push): first render after
session start if not shown yet (danger-red rule = the consent moment), then periodic re-renders on a calm
sage rule + the live red dot — same cadence logic as the ox CLI whisper (whisper_recording_reminder.go:
show once past heartbeat ≥ N, then ~interval). Abort is omitted (fat-finger risk in a passive strip) — it lives only
in the full control surface + PiP.
First render at session start carries the danger-red consent rule (same strip, red left edge + "SageOx is recording this session → #api-go"); subsequent periodic renders drop to the calm form above.
Picture-in-Picture · persistent recording pill (status-at-edge)
When the host supports PiP, the recording state floats at the edge (Apple menu-bar-recording model) with quick controls — ambient, glanceable, always reachable. The card requests PiP display mode; the host honors it.

Rec 18:24 · #api-go team
States · self-healing, honest
Every state offers the next move. Pending is the most common first render for AI-derived data — it must never read as "empty".

