Voice & Persona
Voice Canvas Primary
The immersive canvas becomes the conversational surface — one mic path, everywhere, that deepens to fit the ask.
Situation
Reviewing the input controls, Alex found the mic doing three different things — opening the immersive /voice canvas on home, dictating inline in a task, and doing nothing in R&D/Q — with "add a loop" left as a bare input. Rather than harmonise each composer separately, the decision resolves the inconsistency at its root: make the immersive canvas the single primary way to talk to Mallory/Q, across simple asks and sustained task work.
Bottom nav stays for browsing; the canvas is for talking. It renders a context chip naming who/what you're talking to, and it deepens — a quick ask gets a spoken answer, a contextual ask surfaces an artefact card, and "let's work through X" grows a live breakdown strip into a full voice-first working session.
Key decisions
One canvas, invoked everywhere
Every surface's mic opens the same canvas scoped by a context descriptor (chat/task/dig/q); a context chip names it and ✕ returns to the originating surface.
Deepens to fit the request
Quick ask → spoken answer; contextual ask → answer plus an artefact card; "let's work through X" → a sustained working session with a live breakdown strip.
Text-label controls, not icons
Send (recording) · Cancel (thinking) · Pause · Talk · Type (reply states) — the mic keeps a distinct primary affordance.
Five states with calm motion
recording → thinking (reused .build shapes) → text-arriving ("Clearing my voice…") → speaking (amber waveform) → finished, with the control bar morphing per state and honouring prefers-reduced-motion.
Three required controls
Pause/long-press-mute his voice, an adaptive reply font that steps down and scrolls for longer replies, and a keyboard Type toggle that swaps mic for text without leaving the canvas.
Architecture
A context descriptor threads through the shared Composer's onMic, so every surface opens the same canvas scoped to its own activity; the canvas itself gains a state machine, three controls, and an optional working-session depth.
{ kind: 'chat'|'task'|'dig'|'q', refId?, title? } set per-surface mic; renders the chip and drives ✕-return.session_steps machinery — the Task Workspace, voice-first, inside the canvas.stopSpeaking/skipSpeaking), replyFontTier(len) adaptive font, and the Type keyboard toggle reusing Composer's textarea.task/q, avoiding duplicated conversation UI.Risks & guardrails
Duplicated conversation UI
TaskWorkspace/QConversation must stay thin and share session data with the canvas's working strip, not re-implement it.
Barge-in correctness
Talk during speaking must cleanly interrupt playback and re-enter listening without dropped audio or state desync.
Reduced-motion coverage
All five states' motion (breathe/pulse/typewriter) must have an instant, spinner-free fallback.
Home composer decision deferred
Whether the home text field routes into the canvas's Type mode or stays fully separate is explicitly left open to plan time.
Delivery
P1 — State machine + motion refit
States, labels, typewriter, amber, thinking-shapes, and holding-phrases on the existing /voice.
P2 — The three controls
Pause/mute, adaptive font, keyboard toggle.
P3 — Context descriptor + chip
Mic-everywhere invocation and ✕-return across surfaces.
P4 — Working-session depth
Live breakdown strip via task sessions, plus artefact cards.
P5 — Surface integration
Thin TaskWorkspace/Q/add-loop, then verify and a design pass; subagent-driven TDD, two-stage review, deploy, on-device review.
Out of scope
docs/superpowers/specs/2026-06-17-voice-canvas-primary-design.mdplan ·
docs/superpowers/plans/2026-06-17-voice-canvas-primary.md