Context & Investigations
In-Feed Brief
"What can I do?" stops opening a settings-style modal and instead drops a transient brief panel into the conversation feed, sourced live from the Wave 1-A capability registry.
Situation
Wave 1-B. The home/empty state and the "Briefing" help sheet both describe Mallory's capabilities in hand-written prose, disconnected from each other and, until Wave 1-A, from the truth. The modal help sheet reads as a settings panel, not as Mallory presenting himself.
Decided in brainstorming: the brief is menu-triggered and rendered in the feed, not auto-shown and not a modal. The empty/calm state stays unchanged; the existing "What can I do?" menu item instead appends a brief panel as a block in the feed and scrolls to it, and the modal helpOpen overlay is retired outright.
Key decisions
In-feed, not modal
"What can I do?" appends a transient brief block to the conversation and scrolls to it; the helpOpen overlay, its hardcoded list, and its styles are removed.
Registry-sourced content
A new GET /capabilities endpoint maps CAPABILITIES to {id, label} partitioned by built/not-yet — label is a new UI-voiced field distinct from the persona's claim, so it can't drift from the registry.
Presentation is web-side only
A thin PRESENTATION map keyed by id assigns grouping/icon — visual concern only; an unmapped id still surfaces under a default group rather than being silently dropped.
Transient, never persisted
The panel is a local UI item, not inserted into session.messages — never sent to the model, never written to D1, never replayed on reload.
Graceful fallback
loadCapabilities() returns a small built-in fallback set if the fetch fails, clearly a backstop rather than the source of truth.
Architecture
A new browser-facing route exposes the registry; the web side gets a presentation-only panel component wired through the existing menu.
label field to Capability and every entry, alongside the existing persona-voiced claim.handleGetCapabilities — new GET /capabilities, gated like other browser GET routes, returns built/not-yet partitions.loadCapabilities() — fetch, cache in a small store, fallback set on failure.helpOpen; removes the modal markup and dead styles.Risks & guardrails
Two label fields on Capability
claim and label are mild redundancy but serve genuinely different audiences (model vs Alex) — both live in one registry, so neither drifts.
Empty-state summon
Tapping the menu from the empty state shows the block above the composer and may scroll the greeting up — accepted.
Duplicate renders
Reactivity must not duplicate the block on repeated taps; guarded with an idempotent flag rather than pushing again.
Delivery
Registry label
Add UI label to the registry + a uiCapabilities() helper.
Endpoint
GET /capabilities route.
Web client
loadCapabilities() + types + fallback.
Panel
Brief ordering helper + BriefPanel.svelte.
Feed wiring
Wire into the feed; retire the modal entirely.
Out of scope
docs/superpowers/specs/2026-06-12-in-feed-brief-design.mdplan ·
docs/superpowers/plans/2026-06-12-in-feed-brief.md