ADR 0079: IDS (Ide Display System) — пайплайн оверлеев IDE, ортогонально CDS¶
Статус: Accepted
Дата: 2026-04-20
Связанные ADR¶
| ADR | Роль |
|---|---|
| 0036 | CDS: кабина, канал → CDS → композитор → поверхность |
| 0066 | Cockpit UI vs presentation IDE: хром и оверлеи |
| 0070 | Command Palette как прямой overlay в активном TopLevel |
| 0057 | чат: композитор снимка поверхности; аналогия по слою «композиция» |
| 0013 | палитра и discoverability |
| 0115 | CDS — общий слой graph-backed приборов (реализация в кабине, не IDS) |
Резюме¶
- IDS — пайплайн IDE-оверлеев (intent → композитор → снимок → поверхность).
- Ортогонально CDS 0036; Roslyn CASCOPE013–016.
Контекст¶
0036 задаёт цепочку для семантики кабины (PFD/MFD/инструменты, CockpitSurfaceState, слоты приборов). Она не должна разрастаться до «всех пикселей IDE», иначе CDS станет God-слоем и смешается с 0066.
Параллельно продукту нужны глобальные IDE-оверлеи: командная палитра (Ctrl+Q), позже — toast, блокирующие диалоги, иные «поверх всего workspace» поверхности. У них другие инварианты:
- привязка к активному
TopLevelи возврат фокуса (0070); - keyboard-first и предсказуемый перехват ввода;
- по возможности — снимки для тестов и наблюдаемости агента без привязки к конкретному дереву
Control.
Без явного имени и границ этот контур расползается по Views/* и *ViewModel, дублируя логику «кто сверху» и «кто ест клавиши».
Решение¶
Вводится отдельный продуктовый контур IDS — Ide Display System (неймспейс и типы в коде: CascadeIDE.IdeDisplay.*).
1. Назначение IDS¶
IDS описывает presentation IDE для модальных и полумодальных оверлеев (и в перспективе — других IDE-surfaces, которые не являются приборами кабины): отделение данных/намерения и композиции снимка от конкретного рендера (Avalonia Control, Skia-хост, гибрид).
CDS остаётся каноном кабины; IDS — канон оверлеев IDE. Смешивать семантику слотов кабины и стек IDE-оверлеев в одном типе — анти-паттерн; при необходимости общ only на уровне слов «канал / композитор / снимок», не на уровне одного DTO.
Различение CDS и IDS (одно приложение, два домена)¶
Оба контура выполняются внутри одного процесса CascadeIDE (географически «всё это IDE»). Путаница снимается вопросом домена смысла, а не exe-файла:
| CDS (и кабина вокруг него) | IDS | |
|---|---|---|
| Вопрос | Куда в модели внимания кабины попадает содержимое: PFD / Forward / MFD, слот прибора, страница вторичного контура? | Как показать оверлей оболочки поверх workspace: палитра, модалка, toast; фокус, z-order, перехват ввода? |
| Типичный тест | «На какой странице MFD / в какой зоне deck / в каком слоте прибора?» | «Модально поверх всего окна, как в обычном приложении, без семантики прибора?» |
| Норматив | 0036, 0021 | этот ADR, 0070 |
| Слои «прибор vs хром» | Семантика приборов и зон (0036) | Не-приборный presentation shell (0066) |
Мнемоника: решаешь «куда в кабине» → CDS; «глобально поверх workspace, не слот прибора» → IDS. Границу закрепляет CASCOPE016: Cockpit/ не импортирует IdeDisplay.
2. Та же дисциплина цепочки, что у 0036 (по смыслу, не по типам)¶
Для каждого оверлея в IDS соблюдается цепочка:
- Канал / состояние — что пользователь ввёл, что отфильтровано, какой режим (команды / go-to / melody), без координат пикселей.
- Композитор поверхности — чистая функция (или близко): из канала строит снимок для рендера и навигации (строки, выделение, подсказки, opacity).
- Поверхность — Avalonia/Skia: фокус, hit-test, анимации; не источник семантики оверлея.
Обобщающий контракт композиторов: IIdsSurfaceCompositor<TIntent, TSnapshot> с методом TSnapshot Compose(TIntent intent) (параметр без in при контравариантном TIntent — ограничение языка C#).
3. Единый хост ввода (input capture)¶
Инвариант направления: перехват клавиатуры/фокуса для стека оверлеев IDE сходится к одному месту — условный IdsOverlayHost / input router на корне активного host, а не к разрозненным PreviewKeyDown в каждом оверлее без политики.
На момент принятия ADR полная реализация хоста может быть strangler; палитра может временно оставаться self-contained (0070), но новые оверлеи не должны добавлять третий независимый «глобальный перехват» без явного согласования в этом ADR или отдельном ADR.
4. Слоты (SurfaceSlot) — опционально¶
SurfaceSlot (или IdsSurfaceSlot) вводится, когда появляется несколько одновременно конкурирующих IDS-поверхностей или нужен явный z-order / mount id для наблюдаемости и тестов.
Для одной палитры как единственного верхнего оверлея слот не обязателен. Для «палитра + toast + блокирующий диалог» — слот или эквивалентный стек становится частью IDS-хоста.
Именование: по умолчанию Ids* в коде, чтобы не путать с CockpitInstrumentDescriptor и слотами CDS (0047).
5. Наблюдаемость агента¶
Снимки IDS (например, состав строк палитры и выбранный индекс) могут поставляться в MCP/контракт агента отдельно от cockpit_surface, либо тонким полем «overlay» в общей сводке — решение по полю JSON не фиксирует этот ADR; фиксируется только разделение семантики CDS vs IDS.
6. Roslyn-guardrails (CASCOPE013–016)¶
На сборке CascadeIDE.ArchitectureAnalyzers:
- CASCOPE013 / CASCOPE014 / CASCOPE015 — в каталоге
IdeDisplay/запрещены зависимости отCascadeIDE.Cockpit…, от Avalonia UI и отCascadeIDE.Features.UiChrome(в т.ч. типы в членах классов вCascadeIDE.IdeDisplay.*). - CASCOPE016 — в
Cockpit/запрещёнusing CascadeIDE.IdeDisplay…(кабина не тянет IDS).
Полные формулировки и уровни — в README анализаторов.
Состояние реализации (фиксация на дату ADR)¶
- Сделано: контракт
IIdsSurfaceCompositor<TIntent, TSnapshot>; для палитры —CommandPaletteSurfaceIntent,CommandPaletteSurfaceSnapshot,CommandPaletteSurfaceCompositor; обновление снимка изMainWindowViewModelпри открытой палитре; тесты композитора; Roslyn CASCOPE013–016 (см. §6). - По плану (strangler): единый
IdsOverlayHost/ router ввода; опциональныеIdsSurfaceSlotпри втором оверлее; при необходимости — проекция в MCP без смешения с CDS.
Последствия¶
- Новые IDE-оверлеи по умолчанию проектируются через IDS (intent → compositor → snapshot → surface), а не «сразу в AXAML логикой наполовину в VM».
- CDS и реестр приборов кабины не раздуваются ответственностью за глобальные IDE-модалки.
- Тесты могут опираться на снимок IDS там, где важна семантика списка/выбора, без хрупкой привязки к визуальному дереву.
Не цели¶
- Замена Avalonia как host для оверлеев.
- Переименование или перепрофилирование CDS под IDE-chrome.
- Полная спецификация JSON для агента в этом ADR.
Отклонённые альтернативы (кратко)¶
- Всё в CDS: отклонено — смешивает кабину и IDE-shell, ломает 0066.
- Отдельный ADR на каждый оверлей без общего IDS-имени: допустимо как временная мера, но ведёт к дублированию политики input/stack.