Forge
markdowndeeb25a2
1# ADR 0066: Cockpit UI и слой presentation IDE — раздельные опоры
2
3**Статус:** Accepted
4**Дата:** 2026-04-19
5
6## Связанные ADR
7
8| ADR | Роль |
9|-----|------|
10| [0021](0021-pfd-mfd-cockpit-attention-model.md) | Модель внимания, EICAS |
11| [0046](0046-presentation-layout-authority-and-cockpit-invariants.md) | Политика `presentation` |
12| [0064](0064-deck-primitives-visual-language-render-layer-and-palette.md) | `PrimitivesKit`, палитра кабины |
13| [0065](0065-instrument-categories-domain-taxonomy.md) | Категории / `graph_kind` |
14| [0013](0013-command-surface-and-discoverability.md) | Палитра команд |
15| [0030](0030-command-ids-hotkeys-and-ui-registry-layers.md) | Реестр команд, hotkeys |
16| [0079](0079-ide-display-system-ids-overlay-pipeline.md) | IDS — оверлеи shell (**не** cockpit UI) |
17
18**Код:** `Cockpit/PrimitivesKit/`, `Features/UiChrome/`, `Themes/*.json`.
19
20---
21## Контекст
22
23В продукте одновременно существуют:
24
251. **Инструментальный слой кабины** — deck, зоны PFD/MFD/Forward, приборы, лампы, semantic map как визуальный инструмент, палитра ролей в смысле EICAS/annunciator ([0021](0021-pfd-mfd-cockpit-attention-model.md), [0064](0064-deck-primitives-visual-language-render-layer-and-palette.md)).
262. **Оболочка IDE** — меню, окно, палитра команд, модальные оверлеи без семантики «прибор», типовые поля и отступы для настроек и диалогов, токены темы для **обычного** UI.
27
28Без явного разделения обсуждения и код ревью смешивают **Cockpit UI** и **presentation-слой IDE** (условно «UI kit» хрома): тащат примитивы кокпита в диалоги или, наоборот, дублируют оверлеи и отступы внутри `PrimitivesKit`. Это ломает смысловую границу и усложняет эволюцию темы и кокпита независимо.
29
30---
31
32## Решение
33
34Зафиксировать **две опоры** (два контекста проектирования), не два обязательных неймспейса на каждую строчку кода:
35
36| Опора | Смысл | Типичное место в коде / артефактах |
37|-------|--------|-------------------------------------|
38| **Cockpit UI** | Визуальный язык **инструментов и deck** в метафоре кабины: виды индикаторов, отрисовка приборов, семантические цвета кабины (`CockpitPrimitivesPalette`), Skia-сцены инструментов, правила Dark Cockpit для **этого** слоя. | `Cockpit/PrimitivesKit/`, палитра кокпита; ADR [0064](0064-deck-primitives-visual-language-render-layer-and-palette.md), [0063](0063-instrument-deck-named-composition-one-anchor.md), [0065](0065-instrument-categories-domain-taxonomy.md); связь с [0021](0021-pfd-mfd-cockpit-attention-model.md). |
39| **IDE presentation (хром)** | Общие для приложения **не-приборные** вещи: оболочка окна, палитра команд, переиспользуемые **модальные оверлеи**, согласованные отступы/типографика для хрома, токены темы `CascadeTheme` / JSON для **shell**. | `Features/UiChrome/`; `Views/` для конкретных экранов; темы в `Themes/`; команды и палитра — [0013](0013-command-surface-and-discoverability.md), [0030](0030-command-ids-hotkeys-and-ui-registry-layers.md). |
40
41**Правило по умолчанию:** если виджет имеет смысл **без** метафоры deck / зон внимания / прибора — он не относится к **Cockpit UI**; если смысл — «показать состояние в ячейке deck / на приборе / в кокпитной полосе» — не смешивать с общим слоем оверлеев и «просто IDE».
42
43**Инвариант:** семантическая палитра **кабины** ([0064](0064-deck-primitives-visual-language-render-layer-and-palette.md)) не является единственным каталогом цветов для всего приложения: **тема** и **хром** могут задавать токены для меню, редактора и модалок; совпадения по hex допустимы только как сознательное согласование, не как обязательная зависимость кокпита от shell.
44
45---
46
47## Последствия
48
49- Ревью и обсуждения явно указывают контекст: **Cockpit** vs **хром IDE**; спорные случаи решаются правилом по умолчанию из таблицы выше.
50- Новые **переиспользуемые** не-модальные примитивы хрома (оверлеи, типовые карточки настроек) развиваются в зоне **`Features/UiChrome`** (или рядом в `Views`, без переноса в `Cockpit/`).
51- **Cockpit** остаётся ответственным за согласованность приборов, deck и Skia-отрисовки по [0064](0064-deck-primitives-visual-language-render-layer-and-palette.md); не дублировать туда палитру меню «ради единства файла».
52
53### Проверка в сборке (Roslyn)
54
55Граница **импортов** между `Features/UiChrome` и `Cockpit/PrimitivesKit` закреплена анализатором `CascadeIDE.ArchitectureAnalyzers`:
56
57- **CASCOPE011** — в `Features/UiChrome/` запрещён `using CascadeIDE.Cockpit.PrimitivesKit`.
58- **CASCOPE012** — в `Cockpit/PrimitivesKit/` запрещён `using CascadeIDE.Features.UiChrome`.
59
60Подробности и ограничения (MCP / `RoslynMcpWorkspace`) — [CascadeIDE.ArchitectureAnalyzers/README.md](../../CascadeIDE.ArchitectureAnalyzers/README.md). Полный список CASCOPE* — там же.
61
62---
63
64## Не-цели (текущая фаза)
65
66- Ввести отдельную сборку «UIKit» или переименовать папки в одном коммите без потребности.
67- Исчерпывающий каталог всех токенов темы и компонентов (это живой гайд и код, не дублирование в ADR).
68- Запретить исключения: локальный прототип в фиче возможен, но не задаёт второй канон без пересмотра ADR.
69
70---
71
72## Альтернативы (кратко)
73
74| Вариант | Минус |
75|--------|--------|
76| Один «UI kit на всё», включая кокпит | Смешение семантик; кабина тянет за собой shell и наоборот |
77| Только устная договорённость | Нет стабильной ссылки для ревью и онбординга |
78| Новый ADR на каждый контроль (кнопка, поле) | Шум; граница слоёв достаточна на уровне этого ADR |
79
View only · write via MCP/CIDE