MalloryEstate Briefing
M·016Approved
← All briefings

Feature Waves

Wave 2a — Rich Feed Blocks

Rich content as an opt-in artifact Mallory verbally points to — the spoken channel stays primary and clean.

Dated 2026-06-13Programme Feature Waves

Situation

The feed rendered assistant replies as plain text, and Mallory's persona is voice-first — every reply is written to be read aloud, which is why he's told "plain prose only, no markdown/lists/URLs." Naively rendering all replies as markdown would fight that identity and make TTS read syntax aloud.

The resolving principle: the spoken channel stays primary and clean; rich content is an opt-in, rendered attachment Mallory verbally points to. This wave is the first slice of a layered sequence — link previews (2c) and diagrams/data widgets (2d) are deferred, slotting into the same artifact frame later.

Key decisions

Rich content = artifacts he points to

Non-speakable detail (table/image) renders as a collapsed card; Mallory says he's included it ("I've put a table together for you") rather than reading it. No custom artifact fence — standard markdown table/image, auto-collapsed by policy.

Choice chips

A model-emitted trailing ``chips`` fence, parsed client-side into tappable suggested user utterances (tap = send). No action/deep-link chip type.

Artifact display

Inline collapsed preview + Open/Expand, reusing the existing reply-level clamp (12em + fade + "Show more"), chosen over chip-gated display.

Flatten-for-speech is required

A pure toSpeech() strips the chips fence, tables, images, markdown emphasis/headings/code, and bare URLs before anything reaches TTS.

Safe links

Internal routes navigate in-app via isInternalHref; external/obsidian/tel/mailto open appropriately; DOMPurify's ALLOWED_URI_REGEXP extended for obsidian:, javascript: stays blocked.

Architecture

Two new pure modules (markdown, replyBlocks) shared between the feed and ReportViewer, plus a persona nudge permitting the new affordances.

web/src/lib/markdown.ts (new)
renderMarkdown(md, opts) — DOMPurify-sanitized marked output; feed uses breaks:true to preserve plain-prose line breaks, ReportViewer keeps breaks:false.
web/src/lib/replyBlocks.ts (new, pure)
parseChips (splits trailing chips fence from body), isInternalHref, toSpeech (strips all rich syntax for TTS) — unit-tested.
+page.svelte feed rendering
Settled replies render sanitized markdown + a chip row; .dispatch de-roles from a button to a plain div so links/chips are valid; link-click interception routes internal hrefs via goto.
session.svelte.ts
Speak call sites (auto-speak + replay) pass toSpeech(text) instead of raw text.
src/persona.ts
SPOKEN DELIVERY guidance extended: reference tables/images by saying he's included them, use links sparingly, may end with a chips block — restrained, most replies stay plain spoken prose.

Risks & guardrails

TTS reads syntax aloud

Mitigated by toSpeech at every speak call site — verified by unit test, since real TTS itself needs the device.

Streaming jank from partial markdown

While streaming, the reply renders as plain text (current behaviour); markdown/chip parsing only applies once the reply settles.

Misrouted chips fence

A ``chips`` fence not at the very end of the reply is left in the body, not stripped — avoids accidentally eating mid-reply content that merely resembles the fence.

Delivery

Task 1

Pure reply-block logic (replyBlocks.ts).

Task 2

Shared markdown renderer (markdown.ts) + ReportViewer refactor onto it.

Task 3

Flatten TTS text via toSpeech (session.svelte.ts).

Task 4

Persona nudge (src/persona.ts).

Task 5

Feed rendering — markdown, chips, safe links, artifacts (+page.svelte).

Out of scope

Custom artifact fences (tables/images are standard markdown)Link previews / URL unfurling (Wave 2c)Diagrams (Mermaid) / data widgets (Wave 2d)Action/deep-link chipsMarkdown rendering of user messagesAny change to the chat stream, /conversation or /chat payloads, or the DB
spec · docs/superpowers/specs/2026-06-13-wave-2a-rich-feed-blocks-design.md
plan · docs/superpowers/plans/2026-06-13-wave-2a-rich-feed-blocks.md
Mallory · Estate briefing