ADR 0072: Chat topic cards, drill-in/back и intent-based Melody/Chords для навигации по темам¶
Статус: Accepted · Implemented
Дата: 2026-04-19
Связанные ADR¶
| ADR | Роль |
|---|---|
| 0031 | пакеты уточнений, ThreadNode, обзор размаха |
| 0057 | chat surface → Skia pipeline |
| 0060 | Melody, CascadeChord, паритет с палитрой — уточняется в chat-domain, см. ниже |
| 0013 | Поверхность команд и discoverability (палитра, минимальный toolbar) |
| 0030 | Слои идентификаторов команд, хоткеев и UI (без одной таблицы «всё в одном» пока) |
| 0017 | мультиоконность, фокус |
| 0070 | Command Palette как прямой overlay surface, маршрутизируемый в активный TopLevel |
| 0044 | Разделение ролей — Avalonia как хост («фюзеляж»), кастомная отрисовка для чата агента (Skia как гипотеза) |
| 0008 | Стабильные контракты MCP и тестируемая инфраструктура |
| 0096 | сводка на карточке, spine продуктовой линии — продуктовая семантика поверх overview/detail; CIDE как пример; §4 |
| 0119 | Слэш-команды в ChatInput — тот же command_id, что Melody/Chords/palette |
Вне ADR¶
| Документ | Роль |
|---|---|
| intent-melody-language-v1.md | IML v1: грамматика c: и мотивация |
Отношение к 0060: этот ADR не заменяет общую keyboard-first модель (палитра, CascadeChord, Command Melody c:). Он нормативно уточняет, как те же принципы применяются к навигации по темам чата (topic-level intents). См. § «Связь с ADR 0060». |
Контекст¶
0031 уже вводит треды как устойчивые линии работы (ThreadNode vs MessageNode), пакеты уточнений и вектор «обзор размаха» сессии вместо одной бесконечной ленты. 0057 переводит чат на общий pipeline Intent → Declutter → Layout → Render и выделяет доменные узлы (ThreadNode, MessageNode, …) как first-class на стадии Intent.
Однако этого недостаточно для продуктового UX-контракта: данные о ветвлениях могут существовать в модели, а экран по умолчанию всё ещё воспринимается как одна линейная лента. Не зафиксированы:
- явная модель экрана «обзор тем → вход в тему → назад»;
- адаптивный default (одна тема vs несколько);
- обязательный для v1 слой клавиатурной навигации по темам через те же
command_id, что палитра и Melody/Chords (0060), без привязки к координатам контролов.
Проблема¶
- Разрыв данных и навигации:
ThreadNodeи snapshot layout (0057) описывают граф; без явного view mode (overview vs detail) пользователь остаётся в ментальной модели «одна лента», даже когда тем несколько. - Отсутствие канона drill-in/back: выход из темы не должен возвращать в абстрактную «общую ленту», если продуктовая модель — карточки тем как первичный обзор.
- Keyboard-first без intent-слоя: если Melody/Chords будут напрямую дергать фокус Skia-элементов или хитбоксы, теряется кроссплатформенность и паритет с MCP (0008); дублируется логика с pointer.
- Смешение с опасными подтверждениями: навигация по темам не должна конкурировать по UX с PFD-подтверждениями и пакетами уточнений как с «да/нет» — границы остаются по 0017 и 0031.
Резюме¶
- Topic cards в чате: drill-in/back, adaptive default; intent-based Melody/Chords v1.
- Уточняет аккорды 0060 в chat-domain.
- Дополняет Intercom/spine (0096).
Решение¶
1. Topic cards как первичная форма multi-topic chat overview¶
- Карточка темы представляет устойчивую линию работы (
ThreadNode), а не отдельное сообщение. - При одной теме в сессии допустимо открывать чат сразу в detail (timeline этой темы).
- При нескольких темах default — overview из карточек тем (см. §3).
- Main line (основной тред) остаётся одной из карточек, а не скрытым «режимом без карточек».
2. Drill-in / Back как каноническая модель навигации¶
- Drill-in: выбор темы раскрывает её как detail timeline (сообщения и связанный контент внутри темы).
- Back: возврат из detail ведёт в topic overview, а не в отдельную «глобальную ленту» без карточек.
- История внутри темы остаётся хронологической; ветвления отражаются данными модели (0031), а не произвольным «перепрыгиванием» по UI-дереву.
3. Adaptive default view¶
| Условие | Default view |
|---|---|
| Одна тема (или эквивалент «фокус только на main thread») | Detail timeline |
| Несколько тем | Overview (карточки) |
Точные правила «когда считать тему одной» — предмет реализации в VM; ADR фиксирует продуктовый принцип, а не алгоритм детекции.
4. Intent-based Melody и Chords как обязательный v1 keyboard-first слой для chat topics¶
- Навигация по темам должна иметь входы: прямые команды (палитра / toolbar), CascadeChord (0060) и Command Melody
c:(0060 §11) над одним наборомcommand_id(0030). - Melody и Chords для chat-topic navigation не адресуют конкретные контролы, координаты или внутренние
HitTarget; они вызывают chat navigation intents (см. §5). - Минимальный набор v1 (идентификаторы — к внесению в
IdeCommands/ реестр; здесь — логические имена):
| Intent | Назначение |
|---|---|
focus_chat_surface |
Фокус на поверхность чата (MFD/host), без смены темы |
focus_next_topic |
Фокус на следующей теме в overview или логический «следующий тред» в рамках контракта фокуса |
focus_previous_topic |
Аналогично назад |
enter_focused_topic |
Переход из overview в detail выбранной темы |
return_to_topic_overview |
Выход из detail в overview |
Расширение набора (например «свернуть ветку», «переименовать тему») — отдельными командами и ADR при необходимости.
Паритет с 0060: любая команда, доступная только с аккорда или только с c:, обязана быть discoverable через палитру и MCP с тем же command_id (0060 §9 discoverability).
5. Intent-first interaction contract¶
- Поток:
Melody / Chords / palette / MCP→ intent (command_id) → состояние VM (в т.ч. view mode, focused thread) → layout (0057) → render (SkiaChatSurfaceControl). - Один и тот же intent должен иметь предсказуемый эффект в overview и detail (например «следующая тема» в detail может трактоваться как «следующая среди видимых тем сессии» — конкретная семантика задаётся VM, но не дублируется отдельным shortcut-слоем для каждого режима без причины).
- Pointer/tap на карточку или кнопку «назад» сводится к тем же intent-командам, что и клавиатура, а не к параллельной навигационной логике.
6. Separation of concerns¶
- Intent / pipeline (0057): знает темы, сообщения, подтверждения и связи; строит
ChatSurfaceState. - Layout: решает, какие регионы overview vs detail и какие lanes/entries (
ChatSurfaceLayout,ChatThreadOverviewItem). - Render (
SkiaChatSurfaceControl): отрисовка и hit-testing без вычисления ветвления домена из геометрии в обход snapshot.
Связь с ADR 0060¶
- 0060 остаётся каноном для: трёх входов команд (палитра,
CascadeChord, слэш в Intercom — 0119 §1a), осей S/T/M/E где применимо, overlay, Command Melodyc:, паритета с реестром. - 0072 вводит дополнительный продуктовый контракт только для chat-topic navigation и не отменяет общую chord/melody модель.
- Формулировка уровня «amended in part»: для домена чата нормативно заданы overview/detail, topic cards и минимальный набор intent-команд с обязательным Melody/Chords/palette паритетом; остальная часть 0060 не изменена.
Якоря реализации (код)¶
| Компонент | Роль |
|---|---|
ChatPanelViewModel |
Режим просмотра (overview/detail), выбранный/фокусный тред, исполнение intent-команд, обновление snapshot |
ChatSurfaceSnapshot / ChatThreadOverviewItem |
Сущности уровня layout для overview-карточек и дорожек |
ChatSurfaceCompositor |
Разделение pipeline: overview vs detail layout поверх ChatSurfaceState |
SkiaChatSurfaceControl |
Интерактивные карточки тем, hit targets, affordance «назад» — в терминах snapshot, не доменной логики |
MainWindowHotkeyService, MainWindowViewModel.CascadeChord |
Привязка жестов к command_id (0030) |
IdeCommands / реестр |
Канонические строки command_id для intent из §4 (например IdeCommands.PowerDocuments и соседние частичные классы по мере добавления команд) |
Диаграмма потока (намерение → состояние → layout)¶
flowchart LR
keyboardInput[KeyboardInput] --> melodyChordParser[MelodyChordParser]
melodyChordParser --> chatNavIntent[ChatNavigationIntent]
pointerInput[PointerInput] --> chatNavIntent
chatNavIntent --> chatViewState[ChatViewState]
chatIntentPipeline[ChatIntentPipeline] --> chatViewState
chatViewState --> overviewCards[OverviewCards]
chatViewState --> topicDetail[TopicDetail]
Не-цели (v1)¶
- Свободный mind-map layout тем без отдельного ADR и оценки фокуса.
- NLP-based авто-детекция тем как обязательная база UX.
- Замена 0057 pipeline или отказ от Skia product path.
Риски¶
- Перегрузить v1 полноценным graph layout вместо карточек и линейного detail.
- Неясный фокус между
TextBoxввода, chat surface и палитрой (0013, 0017). - Скрытая keyboard UX, если команды не видны в палитре и в help (0060).
- Протечка UI-bound shortcuts в обход
command_id. - Смешение опасных подтверждений с навигацией по темам — по-прежнему разводить по 0017 и 0031.
Последствия¶
- Появление явного состояния навигации в chat VM и тестов на overview/detail.
- Обновление реестра команд,
hotkeys.toml(шип и пользовательский merge) и melody alias для topic intents. - Лучшая ориентация в сессии при цене более строгой модели фокуса и документации для пользователя.
Provenance и формализация¶
Продуктовые идеи topic cards, drill-in/back, intent-first Melody для чата вырабатывались в живом диалоге с пользователем и здесь формализованы как архитектурный канон репозитория. Внешние продукты (в т.ч. исследовательские линии вроде Comet/Perplexity) могут упоминаться в других документах как контекст формулировок, но нормативным источником для CascadeIDE остаётся этот ADR и связанные ADR в docs/adr/, а не экспорт внешних чатов.
План внедрения (после принятия ADR)¶
- Добавить navigation state в
ChatPanelViewModel. - Разделить layout в
ChatSurfaceCompositorна overview и detail. - Перестроить
SkiaChatSurfaceControlпод topic cards + drill-in/back. - Ввести intent-level chat navigation commands и зарегистрировать в палитре.
- Добавить привязки Melody/Chord к тем же
command_id. - Тесты: overview/detail, keyboard contract, паритет palette/MCP.