MalloryEstate Briefing
M·045Approved — ready for plan
← All briefings

Q & Hermes

Q In-Feed Dispatch

Slice 1 of "feed as the home for async work" — Q's conversational chat joins Mallory and Moneypenny in one persona-tagged home feed.

Dated 2026-06-21Programme Q & Hermes

Situation

The home feed should become the one place async/agentic work surfaces across personas, decomposed into three independently-shippable slices. Slice 1 builds the dispatcher and the edge↔Tower-in-feed seam the later slices reuse: folding Q's conversational chat into the feed as a persona alongside Mallory and Moneypenny, plus persona dispatch — Mallory routing a turn to Q or Moneypenny when he judges it belongs there.

It deliberately doesn't build the rich live-reference card (Slice 2) or digs-in-feed (Slice 3) — the offline affordance here is a minimal pending indicator, not a live task-action card.

Key decisions

Manual selector + auto-dispatch

A manual addressee selector in the composer, plus Mallory auto-dispatching to Q or Moneypenny via a classifier route field when he judges the message belongs there.

Client-mediated routing

Reuses the existing qsocket/sendQ wholesale rather than adding a new edge→QHub-DO forward path — lower risk, less new code, and /chat never opens a Tower connection.

Precedence: manual > route > mode

Manual addressee selection wins; then the classifier's route; then the existing resolvePersona(mode, 'home') default. Q is never produced by mode alone.

Read-time merge, single-store persist

The home feed unions messages (Mallory/MP) with the general-thread q_messages (task_id IS NULL) at read time; each turn is written to exactly one store by its route, tagged with a new messages.persona column (migration 022).

Scene markers from persona transitions

A pure deriveSceneMarkers emits a divider whenever the responding persona changes across the merged stream — live or async, source-agnostic.

Presence-driven liveness

Q renders live when online/working; offline shows a minimal pending indicator, and qhub drains queued chats on reconnect — the rich queued→working→ready card is Slice 2.

Architecture

The edge classifies before persisting so a Q-routed turn writes a Mallory handoff line instead of the raw utterance, which the client then relays over the existing Q socket.

migrations/022_messages_persona.sql
Adds messages.persona, so the merged stream is fully persona-tagged on reload.
src/orchestrator.ts
Classifier gains route?: 'mallory' | 'moneypenny' | 'q', validated like the existing signals/live dimensions.
src/routes/chat.ts
handleChat reorders to classify before persisting; route:q persists a handoff line + returns meta{route:'q'} with no Anthropic reply; handleGetConversation serves the unioned, persona-tagged page.
src/persona/resolve.ts (+ resolveAddressee helper)
resolvePersona stays the floor; a small pure helper layers manual/route precedence above it.
web qsocket home-feed consumer
The home feed becomes a second consumer of the existing socket (previously only R&D), listening for taskId:null Q frames + presence.
web deriveSceneMarkers + composer addressee selector
Pure marker-derivation helper feeding the existing buildRows; Auto/Mallory/Moneypenny/Q selector driving the manual send path.

Risks & guardrails

Relay durability at send time

A Q-routed utterance depends on the client's qsocket being open; a momentary closed socket needs a retry-on-reconnect or an explicit "Q unreachable" fallback to an edge turn — flagged for review against the alternative (edge-mediated durability via a DO inject method).

Classifier failure

Defaults to mallory — persist and stream as today, never blocks a turn.

No double-persist

The classify-before-persist reorder is the mechanism that keeps each turn in exactly one store; getting the reorder wrong risks either a lost utterance or a duplicate.

Delivery

Worker

Migration 022, classifier route + validation, resolveAddressee precedence helper, merged conversation read, /chat routing + persona persist.

Web

deriveSceneMarkers, home feed hydration onto derived scene markers, composer addressee selector, Q chat send/receive wired into the feed.

Eval battery

A routing test case added (a dev request → route:q handoff, a personal request → moneypenny) as a pre-merge check.

Deploy (held for Alex)

Migration 022 applied remote-first; Worker deploy from the main checkout preserving HERMES_DIGEST_CN; web build+deploy from the same checkout.

Out of scope

Inline Q task actions + the live-reference card primitive (Slice 2)Digs-in-feed + demoting R&D/Investigations to reference views (Slice 3)Task-scoped Chat-to-Q merging into the home feed (stays on the R&D surface)
spec · docs/superpowers/specs/2026-06-21-q-in-feed-dispatch-design.md
plan · docs/superpowers/plans/2026-06-21-q-in-feed-dispatch.md
Mallory · Estate briefing