diff --git a/.planning/todos/pending/2026-08-06-aiui-answers-in-prose-instead-of-the-content-and-context-surfaces.md b/.planning/todos/pending/2026-08-06-aiui-answers-in-prose-instead-of-the-content-and-context-surfaces.md new file mode 100644 index 00000000..2b7b7ce8 --- /dev/null +++ b/.planning/todos/pending/2026-08-06-aiui-answers-in-prose-instead-of-the-content-and-context-surfaces.md @@ -0,0 +1,76 @@ +# AIUI answers in prose where the content + context surfaces should carry it + +Operator-reported 2026-08-06, with a full exported transcript as evidence +("Exploring My Node", exported 8/7/2026 12:57 AM). Add to the +fix → test → debug → fix loop. + +## The complaint + +Almost every answer in that transcript is rendered as **markdown prose in the chat +window** — bullet lists, fenced code blocks, a hand-built table — when the phase +already has a **content surface** (cards/grids) and a **context surface** for exactly +this. The chat window is doing work the surfaces exist to do, so the product reads as +a chatbot that talks about the node rather than an interface onto it. + +## Every case in the transcript, and what should have rendered + +| Turn | Rendered as | Should drive | +|---|---|---| +| "What apps do I have installed?" | bulleted list of 6 apps | app grid — icon, status pill, Open action per app | +| "How's my Bitcoin node doing?" | bold key/value prose | node status card — height, sync %, mempool gauge, fee band | +| "What's my Lightning balance?" | bold key/value prose | balance card + channel list (5 channels, 8 peers) | +| "What files do I have stored?" | bulleted list of 10 of 47 | file grid — type icons, folders navigable, open actions | +| "Read my todo.txt" | fenced code block | file viewer surface | +| "Show me my bitcoin.conf" | fenced code block | config viewer, **redacted** (see below) | +| "Mempool seems slow, check?" | 10 log lines in a fence | log viewer surface — scrollback, level filter, follow | +| "Open Mempool" | ✅ opened the app frame | (this one is right — the model of the rest) | +| "What other apps can I install?" | 3 grouped bullet lists | marketplace grid with Install actions | +| "Full status summary" | a hand-built markdown table of 14 apps | dashboard surface — system health tiles + app grid | + +Only 1 of 10 turns used a surface. The content is correct in every case; the +*presentation channel* is wrong. + +## Why this is more than cosmetics + +- The grids/cards carry **actions** (open, install, restart, follow logs). Prose + carries none, so every answer dead-ends and the user has to go find the app. +- It burns model tokens re-formatting structured data the node already has + structured, and invites the transcription errors we already fixed once in the + content-card parser (title *n* paired with description *n−1*). +- A markdown table of 14 apps is unreadable on mobile; the app grid is responsive. + +## Security defect found in the same transcript — fix regardless + +The `bitcoin.conf` answer printed **`rpcpassword=archipelago123` in cleartext** into +the chat. Whatever the source (this looks like mock data), the rule has to hold: a +config file rendered by the assistant must be **redacted before it reaches the model +or the transcript** — `rpcpassword`, `rpcauth`, tokens, keys, mnemonics. This is the +phase's own non-negotiable (keys out of the browser and the model). + +Related and currently RED — likely the same gap, and a real failing test on main: + + assistant::backends::routstr::tests::secret_shaped_content_never_reaches_the_stub + panicked at archipelago/src/assistant/backends/routstr.rs:1073 + "a secret-shaped body must be blocked" + +`screen_outbound` (`assistant/egress.rs:411`) is NOT blocking a 12-word BIP-39-shaped +seed in a user turn on the Routstr paid leg, so it would be sent to a third-party +inference provider. Pre-existing, from 13-13 — confirmed unrelated to the appgate +Authorization fix (that commit touched only `appgate/mod.rs`; `routstr.rs` has no +reference to appgate). 1300 passed / 1 failed. + +## Suggested shape of the work + +1. Fix `screen_outbound` first — it is a live security hole with a failing test. +2. Redact secrets in file/config rendering, on the node side, before the model sees it. +3. Audit which intents already have a surface and are simply not being routed to it + vs. which have no surface yet. Ties directly to the open item "audit all ten + `AIContextCategory` values in `fetchAndSanitize` for real coverage, not stubs". +4. Make structured model output the contract for these intents rather than parsing + prose back into cards — the same conclusion the content-card parser item reached. + +## Loop + +Per `RESUME-2026-08-06-media-loop.md`: fix → build → deploy to archi-dev-box → test +live → verify the shipped bundle changed → commit → push. No item is done without a +live check on the node.