Forge
markdowndeeb25a2
1# ADR 0088: Host slot, регион внимания и ячейка deck — таксономия (не смешивать)
2
3**Статус:** Proposed
4**Дата:** 2026-04-22
5
6## Связанные ADR
7
8| ADR | Роль |
9|-----|------|
10| [0017](0017-multi-window-workspace-and-agent-surfaces.md) | зона **Mfd** vs **страницы** `MfdShellView` |
11| [0021](0021-pfd-mfd-cockpit-attention-model.md) | якоря PFD/MFD, география vs телеметрия |
12| [0047](0047-cockpit-instrument-descriptor-and-slot-composition.md) | `CockpitInstrumentDescriptor`, `slot_id` |
13| [0050](0050-declarative-instrument-zone-placement-toml.md) | `[instrument_routing]`, `pfd_primary` / `mfd_primary` |
14| [0063](0063-instrument-deck-named-composition-one-anchor.md) | **instrument deck**, `InstrumentDeckDescriptor`, `SemanticAnchorId` |
15| [0068](0068-deck-row-payload-and-presentation-projection.md) | полезная нагрузка строки vs проекция vs слот |
16| [0073](0073-pfd-instrument-deck.md) | каталог кандидатов на PFD |
17## Резюме
18
19- Таксономия **host slot / регион / ячейка deck** — не смешивать уровни.
20- Связь с [0068](0068-deck-row-payload-and-presentation-projection.md).
21
22
23**Резюме:** в обсуждениях **слот** называли и **всю колонку PFD**, и **малый прямоугольник** в сетке приборов. Этот ADR фиксирует **разведение уровней**: что такое **host slot** в wire хоста, что такое **регион/якорь внимания**, что такое **ячейка instrument deck** — и **что не смешивать**. Реализация **мульти-инструмента** на PFD (композитор deck на поверхности) **не** обязана менять смысл `CockpitSlotIds.Pfd` без отдельного согласования (см. §4).
24
25---
26
27## 1. Контекст: откуда путаница
28
291. В коде **`CockpitSlotIds.Pfd` / `Mfd`** — идентификаторы для **`MainWindowHostSurfaceCompositor`**: в кадр попадает **не больше одного** `CockpitInstrumentDescriptor` на **каждый** такой идентификатор; **географически** это **вся** видимая колонка PFD (или MFD) в `DockedGrid`, а не «одна плитка» внутри неё.
302. В продуктовой речи **PFD** — **зона первичного внимания** (целая колонка, отдельное окно P+M и т.д.).
313. **Instrument deck** [0063] вводит **именованную композицию** «несколько сущностей **в одном якоре**» с **`SemanticAnchorId`** = например `pfd` — то же слово, что и `slot_id`, но **другой уровень абстракции** (`InstrumentDeckDescriptor` vs кадр хоста).
324. В [0068](0068-deck-row-payload-and-presentation-projection.md) уже разделены **строка таблицы/полоса** и **тип ячейки**; остаётся явно связать это с **хостовым** слотом [0047].
33
34Без фиксированных имён снова возникает вопрос: *«Слот — это вся PFD или ячейка в deck?»*
35
36---
37
38## 2. Решение: канонические уровни
39
40Ниже — **рекомендуемые** термины в документации, ADR, ревью; в коде идентификаторы (`CockpitSlotIds`, поля TOML) **не обязаны** дословно совпадать с этими русскими/английскими именами, но **смысл** должен маппиться.
41
42**Грубая «лестница» сверху вниз (разные ветки):** *топология окон / пресентация* ([0017](0017-multi-window-workspace-and-agent-surfaces.md)) → *регион внимания* (PFD, MFD) → **страница оболочки** (`MfdShellPage`, §2.0) — для вторичного контура; *параллельно* на стороне PFD — **host slot** (§2.1) и далее deck / внутренние блоки прибора. **Page** сидит **выше** маршрута «какой кабинный `instrument_id` в `pfd`», иначе путали бы **чат** с **прибором**.
43
44<a id="adr0088-shell-page"></a>
45
46### 2.0. Страница оболочки (Page, `MfdShellPage`)
47
48- **Определение:** **навигация внутри `MfdShellView`** — какой **цельный** режим занимает **колонку** вторичного контура: Chat, Terminal, Solution Explorer, Build, … (`Models/MfdShellPage.cs`, команда `set_mfd_shell_page` в [0030](0030-command-ids-hotkeys-and-ui-registry-layers.md)).
49- **Уровень:** **выше** §2.1–2.4: это **не** `CockpitSlotIds`, **не** `CockpitInstrumentDescriptor`, **не** ячейка instrument deck. Смена страницы **ортогональна** выбору **PFD**-прибора в кадре хоста.
50- **Связь с [0017](0017-multi-window-workspace-and-agent-surfaces.md):** *зона внимания Mfd* (колонка/окно) **≠** *страница*; чат — **страница**, а не «ещё одна зона» рядом с PFD.
51- **PFD-ветка:** в v1 **аналога** `MfdShellPage` для колонки PFD как **переключаемого набора несвязанных UIs** нет: там в основном **один** смонтированный кабинный прибор (§2.1), его внутренняя мозаика — §2.4. Для Pfd называть навигационный **layout**, не *page stack*: контракт `IPfdLayout` + `PfdLayouts` в `Models/Shell/`. Для Mfd — `IShellPage` / `IMfdShellPage` + `MfdShellPageDescriptor` (тот же `MfdShellPage` в VM).
52
53<a id="adr0088-level-1"></a>
54
55### 2.1. Host slot (хостовый слот, `slot_id` в `CockpitInstrumentDescriptor`)
56
57- **Определение:** единица **маршрутизации инструмента в кадре хоста** главного/вспомогательного окна: *куда* композитор кладёт **релевантный** `instrument_id` для отображения в **данной** **геометрической** зоне колонки.
58- **Сегодня (v1):** один `instrument_id` на один host slot; пример: `CockpitSlotIds.Pfd` + `CockpitStandardInstrumentIds.WorkspaceNavigationMap`.
59- **Карта:** `MainWindowHostSurfaceCompositor.BuildInstruments` → список `CockpitInstrumentDescriptor(InstrumentId, SlotId)`.
60- **Не путать с:** мелким глифом, строкой в таблице WH, sub-slot внутри Avalonia-разметки одного `UserControl`.
61
62**Инвариант v1:** host slot **не** дробится на несколько `slot_id` **в той же** модели кадра, пока [0047] не расширен явно (см. §4).
63
64<a id="adr0088-level-2"></a>
65
66### 2.2. Регион / якорь внимания (PFD, MFD, …)
67
68- **Определение:** **семантическая зона кокпита** по [0021] — *зачем* эта часть экрана (первичный скан, вторичный контур, …).
69- **Связь с host slot:** для колонок primary/docked **география** «колонка PFD» совпадает с host slot’ом `pfd` **как площадь экрана**; **якорь** объясняет *роль* зоны, **host slot** — *точка подключения* в DTO кадра и MCP-нарративе «смонтировать инструмент X в Y».
70
71<a id="adr0088-level-3"></a>
72
73### 2.3. Instrument deck и ячейка deck (deck cell)
74
75- **Определение [0063]:** **именованная** композиция: упорядоченный набор **ячеек** (сетка, стек, полоса) под **`SemanticAnchorId`**.
76- **Ячейка deck (deck cell):** **одна** позиция в раскладке: стабильный **`cell_id`** (как `EnvironmentReadinessInstrumentDeck.OrderedCellIds`, `IdeHealthInstrumentDeck.OrderedSegmentIds` для **канала** IDE Health — аналог по **роли**).
77- **Критично:** ячейка deck **не** является `CockpitSlotIds` **в текущем** контракте [0047], пока не введён явный **mapping** «ячейка → host slot / вложенный маршрут».
78- **Назначение:** **несколько** индикаторов/инструментов **внутри** географии одного PFD-региона (при product decision) — через **другой** слой: либо **составной** `UserControl` (внутренняя раскладка = не deck в смысле host), либо будущий **deck host** / **PFD surface deck compositor** (см. §3).
79
80<a id="adr0088-instrument-internal-blocks"></a>
81
82### 2.4. Прибор целиком и внутренние блоки (ячейки прибора)
83
84Ортогонально §2.3: **один** `instrument_id` в host slot (например карта намерений в Pfd) **сам** может быть **составным** — пилот воспринимает **один** прибор, а внутри — **несколько блоков** (ячеек), в которых лежат **конкретные** индикаторы, подграфы, легенда, хром, подписи ([0064](0064-deck-primitives-visual-language-render-layer-and-palette.md) — виды примитивов).
85
86- **Внутренняя ячейка / блок** — единица раскладки **внутри** одного кабинного инструмента; стабильные id и политика композиции задаются **композитором этого прибора** (для мини-карты — pipeline карты намерений, см. [0055](0055-skia-instrument-composition-pipeline.md), [0056](0056-semantic-map-pipeline-adoption.md)), **не** путать с `cell_id` **instrument deck** на уровне региона (§2.3).
87- **Смысл для UX:** «прибор = композиция блоков» — тогда, например, **граф** и **легенда** к нему — **два** таких блока с явной укладкой (резерв под легенду, независимое масштабирование и т.д. по продукту), а не одна неразличимая каша.
88- **Реализация (карта PFD v1, продукт «Карта намерений»):** разбиение граф/легенда — `CodeNavigationMapInstrumentBlockCompositor` + `CodeNavigationMapInstrumentBlockDescriptor` / `CodeNavigationMapInstrumentBlockIds` в `Services/CodeNavigation/` (стабильные id `code_navigation.pfd_instrument.block.*`); альтернативный композитор с id `code_navigation.workspace_instrument.block.*` — `CodeNavigationMapWorkspaceInstrumentBlockCompositor` в `Services/Navigation/`. Итог пайплайна — `CodeNavigationMapCompositionResult.CodeNavigationMapInstrumentBlocks` (после `CodeNavigationMapLayoutStage` в `CodeNavigationMapCompositor`). Отрисовка единая (`CodeNavigationMapSceneDrawing`), прямоугольники согласованы с `LegendColumnLeft` / `LegendBlockTopY`.
89
90**Инвариант терминов:** *deck* на PFD = **колода из нескольких (кабинных) инструментов** в регионе; *блок* = **часть одного** прибора. В разговоре «ячейка» уточнять: *deck cell* (регион) vs *внутренняя ячейка прибора*.
91
92---
93
94## 3. Направление реализации (без фиксации срока)
95
961. **Композитор набора инструментов** на **одной** геометрии PFD: принимает `InstrumentDeckDescriptor` (или PFD-специфичный вариант) и **проецирует** `instrument_id` **в ячейки**; **внешний** кадр хоста по-прежнему может содержать **один** дескриптор на `pfd` с `instrument_id` = *deck host*, либо — при расширении модели — иначе; выбор **отдельной** итерации после прототипа.
972. **CDS / MCP / snapshot:** что считать «атомом» в кадре (один host instrument vs N внутренних) — **контрактная** граница; обновлять [0008] / `cds-contract` **вместе** с внедрением, не деградировать «один `instrument_id` в `pfd`» незаметно.
98
99---
100
101## 4. Правило различения: «что называть слотом в разговоре»
102
103| Вопрос | Канонический ответ (этот ADR) |
104|--------|------------------------------|
105| «Слот — вся PFD?» | **Host slot** `pfd` **в смысле [0047] / кадр хоста** — **да,** это **маршрут до колонки** (один выбранный инструмент на эту площадь в v1). |
106| «Слот — маленькая ячейка в сетке приборов?» | **Нет** для `CockpitSlotIds`; называть **ячейка deck** / **`cell_id`**. |
107| «`SemanticAnchorId` = `pfd` в `InstrumentDeckDescriptor` — то же, что `slot_id`?** | **Тот же якорь внимания / регион**, **не** дубликат **отдельного** host slot в DTO, пока deck не **поднят** в кадр как отдельный уровень; избегать «двух `pfd` в одном кадре» в речи без оговорки. |
108
109---
110
111## 5. Последствия
112
113- Документация, новые ADR, ревью: использовать **host slot** vs **deck cell** vs **регион PFD** по таблице §4.
114- [0073](0073-pfd-instrument-deck.md) (каталог PFD) и [0063](0063-instrument-deck-named-composition-one-anchor.md) остаются: этот ADR **уточняет** термины, **не** заменяет их.
115- Код: **немедленная** смена имён `CockpitSlotIds` **не** требуется; при появлении PFD multi-instrument — либо **внутренний** deck без нового `slot_id`, либо явное **расширение** 0047 + запись в changelog MCP.
116
117---
118
119## 6. Отклонённые альтернативы
120
121- **Считать «слот» только микро-ячейку** — ломает текущий язык MCP/«смонтировать в `pfd`» и [0047] без миграции.
122- **Переименовать `CockpitSlotIds.Pfd` в `PfdColumn`** и ввести `PfdCell_0`… — возможно в будущем, но **высокая** цена; до консенсуса пользуемся §2–4.
123- **Смешивать** строку WH и host slot — уже раскрыто в [0068]; не повторяем.
124
125---
126
127## 7. Открытые вопросы (не блокируют Proposed)
128
129- Точный wire: один `instrument_id` «PFD deck host» vs массив дескрипторов **в** `MainWindowHostSurfaceFrame` — **по итогам** PoC композитора.
130- Стабильные `cell_id` для PFD-деска vs пресетов TOML — эволюция [0050] / [0063 § deck в пресетах].
131
132---
133
134<a id="adr0088-glossary"></a>
135
136## Краткий глоссарий (для копипаста)
137
138| Термин | Смысл |
139|--------|--------|
140| **Страница оболочки (Page)** | `MfdShellPage` — **какой** контент **вторичного контура** в колонке Mfd (чат, терминал, …); **выше** host slot [0047]; [0017](0017-multi-window-workspace-and-agent-surfaces.md). |
141| **Host slot** | `slot_id` в `CockpitInstrumentDescriptor` / `CockpitSlotIds` — **точка крепления в кадре хоста**; v1: **вся** колонка PFD (или MFD), один выбранный `instrument_id`. |
142| **Регион / якорь внимания** | PFD, MFD — **зона кокпита** [0021]; география часто 1:1 с host slot’ом, семантика — «роль зоны». |
143| **Instrument deck** | Именованная композиция **внутри** якоря; `SemanticAnchorId` = регион. |
144| **Ячейка deck (cell)** | Позиция в раскладке **регионального** deck; **не** `CockpitSlotIds` в v1. |
145| **Блок / внутренняя ячейка прибора** | Единица **внутри** одного `instrument_id` (граф, легенда, полоса индикаторов); композитор **прибора**, не host deck. |
146
View only · write via MCP/CIDE