ADR 0072: Chat topic cards, drill-in/back and intent-based Melody/Chords for topic navigation¶
Status: Accepted · Implemented
Date: 2026-04-19
Related ADRs¶
| ADR | Role |
|---|---|
| 0031 | refinement packages, ThreadNode, scope review |
| 0057 | chat surface → Skia pipeline |
| 0060 | Melody, CascadeChord, parity with palette - to be specified in chat-domain, see below |
| 0013 | Command surface and discoverability (palette, minimal toolbar) |
| 0030 | Layers of team identifiers, hotkeys and UI (without one “all-in-one” table for now) |
| 0017 | multi-window, focus |
| 0070 | Command Palette as direct overlay surface routed to active TopLevel |
| 0044 | Separation of roles - Avalonia as a host (“fuselage”), custom rendering for agent chat (Skia as a hypothesis) |
| 0008 | Stable MCP contracts and testable infrastructure |
| 0096 | summary on card, product line spine - product semantics on top of overview/detail; CIDE as an example; §4 |
| 0119 | Slash commands in ChatInput - same command_id as Melody/Chords/palette |
Outside ADR¶
| Document | Role |
|---|---|
| intent-melody-language-v1.md | IML v1: c: grammar and motivation |
Relation to 0060: This ADR does not replace the generic keyboard-first model (palette, CascadeChord, Command Melody c:). It normatively clarifies how the same principles apply to navigating chat topics (topic-level intents). See § “Relation to ADR 0060”. |
Context¶
0031 already introduces threads as persistent lines of work (ThreadNode vs MessageNode), refinement batches and a "sweep overview" vector of sessions instead of one endless thread. 0057 transfers the chat to the common pipeline Intent → Declutter → Layout → Render and allocates domain nodes (ThreadNode, MessageNode, ...) as first-class at the Intent stage.
However, this is not enough for a product UX contract: branching data can exist in the model, and the default screen is still perceived as one linear feed. Not recorded:
- explicit screen model “topic overview → topic entry → back”;
- adaptive default (one theme vs several);
- mandatory for v1 layer keyboard navigation by topic through the same
command_idas the palette and Melody/Chords (0060), without reference to control coordinates.
Problem¶
- Data and navigation gap:
ThreadNodeand snapshot layout (0057) describe the graph; without an explicit view mode (overview vs detail), the user remains in the “one feed” mental model, even when there are several topics. - Lack of a drill-in/back canon: exiting a topic should not return to the abstract “general feed” if the product model is topic cards as a primary review.
- Keyboard-first without an intent layer: if Melody/Chords directly pull the focus of Skia elements or hitboxes, cross-platform and parity with MCP are lost (0008); The logic with pointer is duplicated.
- Mixing with dangerous confirmations: topic navigation should not compete in UX with PFD confirmations and clarification packages as “yes/no” - the boundaries remain at 0017 and 0031.
Summary¶
- Topic cards in chat: drill-in/back, adaptive default; intent-based Melody/Chords v1.
- Clarifies 0060 chords in chat-domain.
- Complements Intercom/spine (0096).
Solution¶
1. Topic cards as the primary form of multi-topic chat overview¶
- The thread card represents a threadnode rather than a separate message.
- With one topic in a session, it is permissible to open the chat immediately in detail (timeline of this topic).
- With several topics default — overview from topic cards (see §3).
- Main line (main thread) remains one of the cards, and not a hidden “mode without cards”.
2. Drill-in / Back as a canonical navigation model¶
- Drill-in: selecting a topic reveals it as a detail timeline (messages and related content within the topic).
- Back: returning from detail leads to topic overview, and not to a separate “global feed” without cards.
- The story within the topic remains chronological; branches are reflected by model data (0031), and not by arbitrary “jumping” along the UI tree.
3. Adaptive default view¶
| Condition | Default view |
|---|---|
| One thread (or the equivalent "focus on main thread only") | Detail timeline |
| Multiple topics | Overview (cards) |
The exact rules “when to consider a topic as one” are the subject of implementation in the VM; ADR captures the product principle, not the detection algorithm.
4. Intent-based Melody and Chords as a mandatory v1 keyboard-first layer for chat topics¶
- Topic navigation must have inputs: direct commands (palette/toolbar), CascadeChord (0060) and Command Melody
c:(0060 §11) over one set ofcommand_id(0030). - Melody and Chords for chat-topic navigation do not address specific controls, coordinates or internal
HitTarget; they call chat navigation intents (see §5). - Minimum set v1 (identifiers for inclusion in the
IdeCommands/ registry; here - logical names):
| Intent | Destination |
|---|---|
focus_chat_surface |
Focus on the chat surface (MFD/host), without changing the topic |
focus_next_topic |
Focus on the next topic in an overview or logical “next thread” within the focus contract |
focus_previous_topic |
Likewise back |
enter_focused_topic |
Transition from overview to detail of the selected topic |
return_to_topic_overview |
Exit from detail to overview |
Expanding a set (for example, “collapse branch”, “rename topic”) - with separate commands and ADR if necessary.
Parity with 0060: any command accessible only from a chord or only from c: must be discoverable via the palette and MCP with the same command_id (0060 §9 discoverability).
5. Intent-first interaction contract¶
- Stream:
Melody / Chords / palette / MCP→ intent (command_id) → VM state (including view mode, focused thread) → layout (0057) → render (SkiaChatSurfaceControl). - The same intent should have a predictable effect in overview and detail (for example, “next topic” in detail can be interpreted as “next among the visible topics of the session” - the specific semantics are set by the VM, but not duplicated by a separate shortcut layer for each mode for no reason).
- Pointer/tap to a card or back button reduces to the same intent commands as the keyboard, and not to parallel navigation logic.
6. Separation of concerns¶
- Intent / pipeline (0057): knows topics, messages, confirmations and connections; builds
ChatSurfaceState. - Layout: decides which regions are overview vs detail and which are lanes/entries (
ChatSurfaceLayout,ChatThreadOverviewItem). - Render (
SkiaChatSurfaceControl): rendering and hit-testing without calculating domain branching from geometry bypassing snapshot.
Communication with ADR 0060¶
- 0060 remains canon for: three command surfaces (palette,
CascadeChord, slash in Intercom — 0119 §1a), S/T/M/E axes where applicable, overlay, Command Melodyc:, registry parity. - 0072 introduces additional product contract for chat-topic navigation only and does not override the general chord/melody model.
- Formulation of the “amended in part” level: for the chat domain overview/detail, topic cards and a minimal set of intent commands with mandatory Melody/Chords/palette parity are specified; the rest of 0060 is unchanged.
Implementation anchors (code)¶
| Component | Role |
|---|---|
ChatPanelViewModel |
View mode (overview/detail), selected/focus thread, intent command execution, snapshot update |
ChatSurfaceSnapshot / ChatThreadOverviewItem |
Layout level entities for overview cards and tracks |
ChatSurfaceCompositor |
Splitting pipeline: overview vs detail layout on top of ChatSurfaceState |
SkiaChatSurfaceControl |
Interactive topic cards, hit targets, affordance “back” - in terms of snapshot, not domain logic |
MainWindowHotkeyService, MainWindowViewModel.CascadeChord |
Binding gestures to command_id (0030) |
IdeCommands /registry |
Canonical command_id strings for intent from §4 (e.g. IdeCommands.PowerDocuments and adjacent partial classes as commands are added) |
Flow diagram (intent → state → layout)```mermaid¶
flowchart LR keyboardInput[KeyboardInput] --> melodyChordParser[MelodyChordParser] melodyChordParser --> chatNavIntent[ChatNavigationIntent] pointerInput[PointerInput] --> chatNavIntent chatNavIntent --> chatViewState[ChatViewState] chatIntentPipeline[ChatIntentPipeline] --> chatViewState chatViewState --> overviewCards[OverviewCards] chatViewState --> topicDetail[TopicDetail] ```
Non-targets (v1)¶
- Free mind-map layout of themes without separate ADR and focus assessment.
- NLP-based auto-detection of topics as a mandatory UX base.
- Replacement of the 0057 pipeline or abandonment of the Skia product path.
Risks¶
- Reload v1 with full graph layout instead of cards and linear detail.
- Unclear focus between
TextBoxinput, chat surface and palette (0013, 0017). - Hidden keyboard UX, if commands are not visible in the palette and in help (0060).
- Leaking UI-bound shortcuts bypassing
command_id. - Mixing dangerous confirmations with topic navigation - continue to separate 0017 and 0031.
Consequences¶
- Addition of explicit navigation state in chat VM and overview/detail tests.
- Updated command registry,
hotkeys.toml(spike and custom merge) and melody alias for topic intents. - Better session orientation at the cost of a more rigorous focus model and user documentation.
Provenance and formalization¶
Product ideas topic cards, drill-in/back, intent-first Melody for chat were developed in live dialogue with the user and here formalized as the architectural canon of the repository. External products (including research lines like Comet/Perplexity) may be referred to in other documents as context of wording, but the normative source for CascadeIDE remains this ADR and associated ADRs in docs/adr/, not exporting external chats.
Implementation plan (after ADR adoption)¶
- Add navigation state to
ChatPanelViewModel. - Divide the layout in
ChatSurfaceCompositorinto overview and detail. - Rebuild
SkiaChatSurfaceControlfor topic cards + drill-in/back. - Enter intent-level chat navigation commands and register in the palette.
- Add Melody/Chord bindings to the same
command_id. - Tests: overview/detail, keyboard contract, palette/MCP parity.