| 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 | |
| 29 | 1. В коде **`CockpitSlotIds.Pfd` / `Mfd`** — идентификаторы для **`MainWindowHostSurfaceCompositor`**: в кадр попадает **не больше одного** `CockpitInstrumentDescriptor` на **каждый** такой идентификатор; **географически** это **вся** видимая колонка PFD (или MFD) в `DockedGrid`, а не «одна плитка» внутри неё. |
| 30 | 2. В продуктовой речи **PFD** — **зона первичного внимания** (целая колонка, отдельное окно P+M и т.д.). |
| 31 | 3. **Instrument deck** [0063] вводит **именованную композицию** «несколько сущностей **в одном якоре**» с **`SemanticAnchorId`** = например `pfd` — то же слово, что и `slot_id`, но **другой уровень абстракции** (`InstrumentDeckDescriptor` vs кадр хоста). |
| 32 | 4. В [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 | |
| 96 | 1. **Композитор набора инструментов** на **одной** геометрии PFD: принимает `InstrumentDeckDescriptor` (или PFD-специфичный вариант) и **проецирует** `instrument_id` **в ячейки**; **внешний** кадр хоста по-прежнему может содержать **один** дескриптор на `pfd` с `instrument_id` = *deck host*, либо — при расширении модели — иначе; выбор **отдельной** итерации после прототипа. |
| 97 | 2. **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 | |