| 1 | # ADR 0063: Instrument deck — именованная композиция инструментов в одном якоре внимания |
| 2 | |
| 3 | **Статус:** Accepted |
| 4 | **Дата:** 2026-04-17 |
| 5 | **Обновлено:** 2026-04-24 — § deck страницы MFD (композиция внутри страницы Mfd). Подробности — [§ История](#adr0063-history). |
| 6 | |
| 7 | ## Связанные ADR |
| 8 | |
| 9 | | ADR / документ | Роль | |
| 10 | |----------------|------| |
| 11 | | [0021](0021-pfd-mfd-cockpit-attention-model.md) | Якоря; композиция **внутри** региона | |
| 12 | | [0021 § зоны](0021-pfd-mfd-cockpit-attention-model.md#anchor-pfd-mfd-content-vs-telemetry-page) | Различие терминов зон | |
| 13 | | [0050](0050-declarative-instrument-zone-placement-toml.md) | `[instrument_routing]`, слоты | |
| 14 | | [0046](0046-presentation-layout-authority-and-cockpit-invariants.md) | Политика layout P/F/M | |
| 15 | | [0047](0047-cockpit-instrument-descriptor-and-slot-composition.md) | `Instrument`, слоты | |
| 16 | | [0010](0010-ui-modes-toml-configuration.md) | UiModes, пресеты | |
| 17 | | [0064](0064-deck-primitives-visual-language-render-layer-and-palette.md) | Виды индикаторов, `PrimitivesKit` | |
| 18 | | [0068](0068-deck-row-payload-and-presentation-projection.md) | Payload строки vs проекция | |
| 19 | | [`workspace-health-implementation-map-v1.md`](../design/workspace-health-implementation-map-v1.md) | Чертёж IDE Health deck | |
| 20 | |
| 21 | ## Резюме |
| 22 | |
| 23 | - **Instrument deck** — именованная композиция вокруг **одного якоря** (фрагмент кода / метод). |
| 24 | - **`ContentRepresentation`**, таксономия примитивов (Readout, Trend, Gauge, Presence…). |
| 25 | - **Presence/Activity** vs **Dark Cockpit**; `DedicatedPage` — режим страницы MFD, не deck. |
| 26 | - Deck **внутри** страницы Mfd — ортогонально навигации между страницами. |
| 27 | |
| 28 | --- |
| 29 | ## Контекст |
| 30 | |
| 31 | В разговоре о кокпите раньше **смешивались две оси**: |
| 32 | |
| 33 | 1. **Форма представления** — *как* показать контент в разметке: полоса (**Strip**), блок «страницы» региона (**Page**), компактный индикатор и т.д. |
| 34 | 2. **Композиционная единица** — *что* и в *каком порядке*: набор инструментов / сегментов канала / индикаторов (вкладки, стек, split, порядок в композиторе). |
| 35 | |
| 36 | В текущем продукте **`DedicatedPage`** / **`bottom_strip`** в пресете канала IDE Health (`ide_health_surface` → `IdeHealthUiSurface.DedicatedPage` / `BottomStrip`) относятся к **оси 1** (форма представления того же логического канала IDE Health), а не к «именованной колоде инструментов целикого якоря». Имя **`DedicatedPage`** канал-специфично; абстрактно это режим **`ContentRepresentation.Page`** для IDE Health ([§ «Две оси»](#adr0063-two-axes) ниже). |
| 37 | |
| 38 | Отдельно: в разговоре о кокпите часто хочется сказать **«страница»** в смысле оси **2** — *упорядоченный набор инструментов и раскладка в одном месте*. Это пересекается с словом **Page** на оси **1** → нужны **разные имена** ([0021](0021-pfd-mfd-cockpit-attention-model.md#anchor-pfd-mfd-content-vs-telemetry-page)). |
| 39 | |
| 40 | Нужны **явные термины**, чтобы документация, TOML и обсуждения не смешивали: |
| 41 | - **форму представления** канала (Strip / Page / …), |
| 42 | - **пресет** UiMode (вся картина окон и якорей), |
| 43 | - **именованную композицию инструментов** в одном якоре — **instrument deck** (ось 2 для инструментов; для IDE Health порядок сегментов — композитор канала, ортогонально Strip/Page). |
| 44 | |
| 45 | <a id="adr0063-two-axes"></a> |
| 46 | <a id="две-ортогональные-оси-representation-vs-composition"></a> |
| 47 | |
| 48 | ## Две ортогональные оси: representation vs composition |
| 49 | |
| 50 | Смысл **deck** здесь: не дублировать имя **Page** на оси A (форма контейнера в регионе), а назвать ось B — **«какие сущности и в каком порядке/раскладке»** в этом контейнере: инструменты, сегменты канала, ячейки сетки. У канала IDE Health на оси B — порядок сегментов в композиторе, **независимо** от Strip/Page. |
| 51 | |
| 52 | | | **Ось A — форма представления** | **Ось B — композиция** | |
| 53 | |---|-------------------------------|-------------------------| |
| 54 | | **Вопрос** | *Каким шаблоном/контейнером* показать контент в регионе (полоса vs блок «страницы» региона …) | *Что* на этом контейнере и *в какой раскладке*: несколько инструментов на одном экране, сегменты канала, вкладки/стек, сетка … | |
| 55 | | **Каноническое имя (этот ADR)** | Перечисление **`ContentRepresentation`**: минимум **`Strip`**, **`Page`**. Дополнительные значения (например **`Indicator`**) — по мере продуктовой необходимости, не фиксируем полный список в Proposed. | Для инструментов в якоре — **`instrument deck`** (ниже). Для канала IDE Health — порядок сегментов в `IdeHealthSurfaceCompositor`, **независимо** от Strip/Page ([чертёж](../design/workspace-health-implementation-map-v1.md)). | |
| 56 | | **IDE Health сегодня** | TOML `ide_health_surface`: `bottom_strip` ↔ **`Strip`**, `dedicated_page` ↔ **`Page`**. В коде — `IdeHealthUiSurface.BottomStrip` / `DedicatedPage` (**не** синоним «любой страницы MFD**). | `IdeHealthSurfaceCompositor`: Build → Tests → Debug → Git. | |
| 57 | |
| 58 | **Инвариант:** смена **`ContentRepresentation`** для IDE Health **не** меняет снимок `IdeHealthInputSnapshot` и логику композитора сегментов — только выбор **какой View** (полоса vs вторичная страница) привязать к тем же `IdeHealthSegments` ([0021](0021-pfd-mfd-cockpit-attention-model.md#glossary-presentation-vs-channel), [чертёж](../design/workspace-health-implementation-map-v1.md)). |
| 59 | |
| 60 | <a id="adr0063-page-plus-deck-pfd"></a> |
| 61 | |
| 62 | **`ContentRepresentation.Page` и instrument deck — вместе:** типичный образ — **один экран региона** (например зона **PFD**), на котором **одновременно** видны **несколько инструментов** в раскладке — как на реальном PFD: альтиметр, указатель скорости, крен и т.д. на **одном** приборном поле. Здесь **`Page`** (ось A) задаёт **форму**: контент канала/якоря показан **блоком страницы региона**, а не узкой полосой (**`Strip`**). **`Instrument deck`** (ось B) задаёт **именно эту** композицию: **какие** инструменты и **как** размещены (сетка, доли колонок, приоритет ячеек). Оси **не смешиваются**, но **складываются**: «страница региона» без колоды была бы пустым контейнером; колода без выбора формы не определяет, полоса это или полный блок. |
| 63 | |
| 64 | **Узкий случай IDE Health:** для **одного канала** IDE Health **`DedicatedPage`** — это **`ContentRepresentation.Page`** только для **данных IDE Health** (те же сегменты, другой View), а не обязательно «весь PFD как авиа-приборная доска»; deck **всего** якоря PFD в продукте может включать **и** IDE Health, **и** другие инструменты — см. [0021](0021-pfd-mfd-cockpit-attention-model.md#anchor-pfd-mfd-content-vs-telemetry-page). |
| 65 | |
| 66 | **Вкладки / стек** — **частный случай** deck, когда инструменты **не** показаны одновременно, а переключаются; для образа «один экран — много приборов» важнее **совместная** сетка на **`Page`**. |
| 67 | |
| 68 | <a id="adr0063-content-representation-code"></a> |
| 69 | |
| 70 | **ContentRepresentation и код (направление; вопрос закрыт):** канон **имени** оси **формы представления** контента в регионе — **`ContentRepresentation`** (`Strip`, `Page`, …). У канала IDE Health это сегодня выражено **`IdeHealthUiSurface`** и TOML `ide_health_surface` — **не отдельная «ось канала»**, а выбор **шаблона размещения** (полоса vs блок страницы) для **данных IDE Health**; соответствие **`Strip`/`Page`** — в таблице выше. |
| 71 | |
| 72 | Когда для **другого потока данных** (другой канал в смысле [0021](0021-pfd-mfd-cockpit-attention-model.md)) понадобится **тот же** выбор «полоса или страница региона», переиспользуется **та же** ось **`ContentRepresentation`**. Каналы задают **что** показать; **форма** (Strip/Page) — **общая** ось представления, её не смешивают с «осями канала». |
| 73 | |
| 74 | Рефакторинг в коде: ввести enum `ContentRepresentation` и маппить на него `IdeHealthUiSurface` (или со временем переименовать тип) — **шаг реализации**, не открытый архитектурный выбор после этого ADR. |
| 75 | |
| 76 | <a id="adr0063-deck-presets-evolution"></a> |
| 77 | |
| 78 | **Deck в пользовательских пресетах (направление; закрыто эволюционно):** на текущий горизонт **deck** остаётся **понятием и внутренним чертёжом** композитора (и именем в обсуждении кода), **не** обязательной **сущностью** в пользовательском TOML. **Декларативное** описание именованных колод в `.cascade` / `settings` **откладывается**: это тянет контракт merge, валидацию, версионирование и UI, пока не стабилизирована сама **композиция слотов** и не ясна реальная потребность «сохранить колоду» у пользователя. |
| 79 | |
| 80 | Допустим **локальный** эксперимент (например только в твоём репо или за флагом), **без** обещания продукта и без расширения публичного контракта — если так быстрее итерировать. В **общий канон** и обязательный путь настройки декларативный deck попадает **отдельным шагом/ADR**, когда появятся данные и сценарии, а не «на всякий случай» заранее. |
| 81 | |
| 82 | ## Решение |
| 83 | |
| 84 | <a id="adr0063-p1"></a> |
| 85 | |
| 86 | **1. Ввести продуктовый термин *instrument deck* (рабочее русское: *колода инструментов* или *сцена слота*)** — это **именованная спецификация**: какие **инструменты** (`instrument_id` / alias из [0050](0050-declarative-instrument-zone-placement-toml.md)) участвуют в композиции, **в каком порядке** и с **какой структурой** (сетка на одной **`Page`**, вкладки, стек, split — перечень паттернов задаётся реализацией и политикой [0046](0046-presentation-layout-authority-and-cockpit-invariants.md)). Типичный случай при **`ContentRepresentation.Page`**: **несколько приборов на одном экране** якоря — см. [§ Page + deck](#adr0063-page-plus-deck-pfd). |
| 87 | |
| 88 | **Граница:** один deck привязан к **ровно одному семантическому якорю внимания** в смысле [0021](0021-pfd-mfd-cockpit-attention-model.md) — например регион **PFD** или **MFD** в данном пресете, но **не** «половина экрана произвольно». Не описывает перенос инструмента из PFD в MFD без смены пресета (это по-прежнему политика пресета / UiMode). |
| 89 | |
| 90 | <a id="adr0063-p2"></a> |
| 91 | |
| 92 | **2. Отличие от `[instrument_routing]` ([0050](0050-declarative-instrument-zone-placement-toml.md)):** маршрутизация v1 отвечает на вопрос **«какой один инструмент занимает семантический слот `pfd_primary` / `mfd_primary`»**. Deck — уровень **тоньше**: *несколько* инструментов и их **внутренняя** композиция **внутри** того же якоря/слота, когда продукт это поддерживает. Конкретный merge (deck поверх routing или отдельный ключ) — **не фиксируется** в этом ADR до появления реализации; инвариант только **семантический**. |
| 93 | |
| 94 | <a id="adr0063-p3"></a> |
| 95 | |
| 96 | **3. Оси A и B не подменяют друг друга:** **`Strip` vs `Page`** — про **контейнер**; **deck** — про **наполнение и раскладку**. Для канала IDE Health **`DedicatedPage` / `bottom_strip`** — это только выбор формы **для IDE Health** ([выше](#adr0063-two-axes)); это **не** отменяет того, что для якоря целиком **`Page` + instrument deck** — нормальный способ описать **несколько инструментов на одном экране** ([§](#adr0063-page-plus-deck-pfd)). |
| 97 | |
| 98 | <a id="adr0063-p4"></a> |
| 99 | |
| 100 | **4. Отличие от пресета UiMode ([0010](0010-ui-modes-toml-configuration.md)):** пресет задаёт **глобальную** картину (окна, якоря, топология [0017](0017-multi-window-workspace-and-agent-surfaces.md)). Deck — **локальная** именованная композиция **внутри** одного контекста якоря; переключение deck’ов (если будет) не должно подменять смену пресета целиком, если только продукт явно не введёт «над-пресет» — это **вне** минимального определения. |
| 101 | |
| 102 | <a id="adr0063-p5"></a> |
| 103 | |
| 104 | **5. Именование в документации:** в русских текстах избегать голого «страница» без уточнения. Для **оси A** — **«форма Page» / «режим Strip»** или **`ContentRepresentation.Page`**, для **оси B** — **deck / колода / композиция слота**. Для IDE Health явно: **«IDE Health в режиме Page (DedicatedPage)»** vs **«полоса IDE Health (Strip)»** — не смешивать с deck целого якоря. |
| 105 | |
| 106 | <a id="adr0063-mfd-page-deck"></a> |
| 107 | |
| 108 | ### Deck страницы MFD (вложенный уровень) |
| 109 | |
| 110 | **Оболочка Mfd** ([0017](0017-multi-window-workspace-and-agent-surfaces.md), `MfdShellView` / `MfdShellPageStack`) в продукте v1 переключает **одну активную страницу** из перечисления `MfdShellPage` (чат, терминал, сборка, …) — это **навигация верхнего уровня** внутри якоря **Mfd**, а не сам по себе **instrument deck** всего региона. |
| 111 | |
| 112 | **Deck страницы MFD** — отдельная ось: **именованная композиция инструментов внутри выбранной страницы** (сетка сегментов, вкладки внутри страницы, порядок ячеек — ось B по смыслу [§ две оси](#adr0063-two-axes)), **ортогонально** смене `MfdShellPage`. Якорь внимания по-прежнему **регион Mfd** в смысле [0021](0021-pfd-mfd-cockpit-attention-model.md); **вложенность** — «страница оболочки → при необходимости свой deck». |
| 113 | |
| 114 | **Уже в коде (частные случаи):** на странице Workspace Health — композитор сегментов IDE Health и `IdeHealthInstrumentDeck`; на странице Environment Readiness — `EnvironmentReadinessInstrumentDeck`. **Направление реализации:** явно моделировать «у страницы MFD опционально свой `InstrumentDeckDescriptor`» и не смешивать в доках **смену страницы** с **колодой внутри страницы**. Таксономия **host / slot / region / cell** при детализации ячеек — [0088](0088-host-slot-region-deck-cell-taxonomy.md). |
| 115 | |
| 116 | **Пресеты каталога оболочки Mfd** (какие `MfdShellPage` доступны, порядок в палитре, страница по умолчанию) — **технически допустимы**, но по **тем же причинам отсрочки**, что и декларативный instrument deck в пользовательском TOML ([§ deck в пресетах](#adr0063-deck-presets-evolution)): merge, валидация, версия схемы, UI — пока не стабилизирована **страница → deck** в коде и не ясны сценарии. Публичный контракт на «сборку страниц MFD из пресета» — **отдельный шаг**, не обязательство этого ADR. |
| 117 | |
| 118 | ## Не-цели (на момент Proposed) |
| 119 | |
| 120 | - Зафиксировать **синтаксис TOML** или ключи для deck (отдельный ADR или расширение [0050](0050-declarative-instrument-zone-placement-toml.md) после прототипа). |
| 121 | - Требовать **drag-and-drop** между якорями или произвольную геометрию вне политики пресета. |
| 122 | - Заменять **CDS** ([0036](0036-cds-channel-compositor-surface-pipeline.md)) или **слой топологии дисплеев** (строка размещения якорей; см. [0017 §](0017-multi-window-workspace-and-agent-surfaces.md#adr0017-display-screens-topology-naming)). |
| 123 | |
| 124 | <a id="adr0063-cds-not-presentation"></a> |
| 125 | |
| 126 | **CDS и топология дисплеев — не путать:** **CDS** ([0036](0036-cds-channel-compositor-surface-pipeline.md)) — контур **канал → контракт кабины → композитор → поверхность**, наблюдаемость и согласованный кадр для MCP; это **не** слой «как нарисовать всю презентацию UI» и **не** то же самое, что **топология якорей** на экранах ([0017](0017-multi-window-workspace-and-agent-surfaces.md), [0046](0046-presentation-layout-authority-and-cockpit-invariants.md)). Слово **presentation** в имени **`[presentation]`** / политике **CockpitPresentationLayout** исторически смешивает эту топологию с обыденным значением «презентация» — **направление имён TOML, ёмкость нотации, *screen* vs монитор, `display.layout` vs `display.screens`** — нормативно в [0017 §](0017-multi-window-workspace-and-agent-surfaces.md#adr0017-display-screens-topology-naming). **Deck**, **`ContentRepresentation`** и раскладка инструментов в регионе описывают **форму и состав внутри якоря**; они **стыкуются** с композиторами и CDS как с контуром данных и кадра, **без** подмены CDS отдельным «движком presentation» и **без** лишнего параллельного контура «поверх CDS». |
| 127 | |
| 128 | ## Альтернативы (имя абстракции) |
| 129 | |
| 130 | | Вариант | Плюсы | Минусы | |
| 131 | |--------|--------|--------| |
| 132 | | Оставить только «страница» | Привычно | Коллизия с IDE Health Page и с веб-терминологией | |
| 133 | | **Deck** / колода | Коротко, авиа-кокпит метафоры не противоречит; отдельно от Page | Новый жаргон — нужен глоссарий | |
| 134 | | **CompositionPage** (составная «страница» слота) | Понятно «это про композицию», не про Strip/Page | Слово **Page** тянет путаницу с **`ContentRepresentation.Page`** и с IDE Health `DedicatedPage` — в ADR **не** канон | |
| 135 | | Scene / сцена | Понятно «состав кадра» | Пересечение с «сценой» 3D/игр | |
| 136 | | Layout bundle | Технически ясно | Длинно, «bundle» уже занят UiModes | |
| 137 | |
| 138 | **Выбор для ADR:** зафиксировать англ. ***instrument deck*** как каноническое имя абстракции; русский эквивалент в UI/доках — по согласованию продукта («колода», «композиция слота»). |
| 139 | |
| 140 | <a id="adr0063-composition-page-synonym"></a> |
| 141 | |
| 142 | **CompositionPage и deck:** если **CompositionPage** означает **именованную упорядоченную композицию содержимого слота** (инструменты, порядок, вкладки/стек — ось B), это **то же самое**, что **instrument deck**; отличие только в имени. Канон в нормативных текстах — **deck**, чтобы не смешивать с **Page** на оси формы (**`ContentRepresentation`**) и с **`DedicatedPage`** у канала IDE Health. |
| 143 | |
| 144 | <a id="adr0063-indicator-kinds"></a> |
| 145 | |
| 146 | ## Типы индикаторов в составе deck (направление) |
| 147 | |
| 148 | Чтобы **deck** давал **плотные, читаемые** экраны без «второго монитора текста», имеет смысл заранее договориться о **небольшом наборе визуальных примитивов** — *как* клетка deck’а или фрагмент инструмента показывает состояние. Это **не** замена оси **`ContentRepresentation`** (Strip/Page): примитивы живут **внутри** ячейки композиции или внутри Skia-инструмента. Связь с иерархией внимания — [0021](0021-pfd-mfd-cockpit-attention-model.md) (канал EICAS, W/C/A, Dark Cockpit): тип индикатора задаёт **геометрию сигнала**, не семантику канала. |
| 149 | |
| 150 | <a id="adr0063-primitive-vs-instrument"></a> |
| 151 | |
| 152 | **Примитив vs инструмент:** **примитив** (в т.ч. Lamp / Bar / Sign ниже) — **атомарный glance**: один визуальный ответ на «что сейчас?» без полноценного сценария навигации и без обязательной модели взаимодействия как у целого слота. **Инструмент** кабины ([0047](0047-cockpit-instrument-descriptor-and-slot-composition.md)) — **сценарий с состоянием**: дескриптор слота, данные, команды, контекст использования. Примитивы **собирают картинку** внутри инструмента или в ячейке deck и **не подменяют** инструмент целиком; разрастание примитивов до «мини-приложений» — признак сдвига границы в сторону нового инструмента или новой ячейки deck. |
| 153 | |
| 154 | **Предлагаемая таксономия (имена — ориентиры, не обязательные идентификаторы в коде v1):** |
| 155 | |
| 156 | | Тип | Роль | Заметка | |
| 157 | |-----|------|--------| |
| 158 | | **Lamp** | Дискретное состояние, «зажёгся / погас», latch внимания | Annunciator / master caution | |
| 159 | | **Bar** | Величина или отклонение на оси (заполнение, позиция маркера); линейная полоса | Glideslope / deviation / progress | |
| 160 | | **Sign** | Краткая маркировка категории (иконка, бейдж, Warning/Error) | Не путать с **Readout** и **Caption** | |
| 161 | | **Readout** | Табло: крупная цифра или моноширинная строка-значение (время, счётчик, версия) | Отдельный режим чтения, чем иконка-Sign | |
| 162 | | **Trend** | Микро-график (sparkline) по времени | «Куда движется», не только мгновенное значение Bar | |
| 163 | | **Gauge** | Скаляр в диапазоне на дуге/кольце | Когда линейный Bar в ячейке неудобен; кольцо можно трактовать как **вид** Bar или отдельный тип — решение реализации | |
| 164 | | **Stack** | Несколько долей в одной полосе (разбиение 100%) | Модель данных иная, чем у одного значения Bar; допустимо как **вариант Bar**, если API обобщают | |
| 165 | | **Caption** | Одна строка текста с жёстким truncate (ветка, файл, команда) | Контекст-указатель, не «категория» как у Sign | |
| 166 | | **Presence** / **Activity** | **Семантика роли** в продукте (связь, ожидание, ход работы), не обязательно отдельная «форма» примитива | По геометрии см. ниже; политика — [§](#adr0063-presence-dark-cockpit) | |
| 167 | |
| 168 | **Статический Presence и Lamp:** да — **дискретный** статус «в сети / нет / деградация» по смыслу это **Lamp** (несколько устойчивых состояний, без обязательной анимации) или, если удобнее метафора иконки, **стабильный Sign** (две иконки / одна с вариантом). Отдельный тип «Presence» в таблице не дублирует Lamp: это **роль данных**, которую обычно рисуют **через Lamp/Sign**; путаница возникает, если назвать отдельным примитивом то, что визуально уже покрыто **Lamp**. |
| 169 | |
| 170 | **Activity** тоже **не обязана** быть отдельной геометрией: «busy» часто — **Lamp** с другим состоянием или кратковременная смена; ход с долей выполнения — **Bar** / **Trend**; бесконечный спиннер без семантики — скорее анти-паттерн ([§](#adr0063-presence-dark-cockpit)). Риск **Dark Cockpit** — у **анимации и яркости в штате**, не у слова Presence. |
| 171 | |
| 172 | **Зачем:** одна и та же **компактная страница** (deck в режиме плотной сетки) может собираться из ячеек с разными примитивами — без обязательного полного текста в каждой клетке. Это усиливает **glanceability** в [0021](0021-pfd-mfd-cockpit-attention-model.md) и согласуется с общим Skia pipeline ([0055](0055-skia-instrument-composition-pipeline.md)), не дублируя его. |
| 173 | |
| 174 | <a id="adr0063-presence-dark-cockpit"></a> |
| 175 | |
| 176 | **Presence / Activity и Dark Cockpit ([0021](0021-pfd-mfd-cockpit-attention-model.md) §6):** в продуктовом языке **Presence** — сигнал **«есть связь / агент на линии / синхронизация»**; статически его обычно выражают **Lamp/Sign**, см. абзац выше. **Activity** — **ход работы** (сборка, запрос), часто с **пульсацией, спиннером, бегущим акцентом** — те же примитивы в других режимах, плюс политика не шуметь. |
| 177 | |
| 178 | Такой примитив **может** нарушить **Dark Cockpit**, если сделать **постоянное** движение или яркий цвет в **штатной** тишине («всё ок, но точка мигает каждые две секунды ради красоты»). Тогда внимание тратится на шум, а не на реальную эскалацию — против идеи §6. |
| 179 | |
| 180 | **Как согласовать:** |
| 181 | |
| 182 | 1. **Номинал / нет активной работы** — Presence **приглушён, статичен или скрыт** (как «невидимый» хром, пока нечего говорить оператору). Не декоративный pulse «мы онлайн». |
| 183 | 2. **Идёт значимая работа** (сборка, долгий MCP, блокирующая операция) — **Activity** допустим как **кратковременный** или **привязанный к реальному прогрессу** сигнал; предпочтительнее **устойчивое** состояние (Lamp «busy») или **Bar/Trend** с реальной динамикой, чем бесконечный спиннер без семантики. |
| 184 | 3. **Отклонение от штатного** — уводить в **иерархию W/C/A** и канал EICAS ([0021](0021-pfd-mfd-cockpit-attention-model.md) §5), а не размножать «живые» пиксели в deck: **эскалация заметна**, штат — **тихо**. |
| 185 | 4. **Развести семантику:** *статический* Presence (подключено / нет) — по примитивам это **Lamp/Sign**, не отдельная геометрия; *временной* Activity (работа идёт) — **строже** политика по умолчанию (показывать только пока есть факт хода работы), визуально чаще **Lamp busy**, **Bar**/прогресс или **Trend**, не декоративный вечный спиннер. |
| 186 | |
| 187 | Итог: **Presence/Activity не запрещены** — они запрещены в режиме **вечного маркетингового мерцания**. Политика та же, что для EICAS-зоны: в норме не отвлекать ([0021](0021-pfd-mfd-cockpit-attention-model.md), пример про появление блока только при активных оповещениях — по духу сопоставимо). |
| 188 | |
| 189 | **Границы (Proposed):** не фиксируем здесь enum в репозитории, размеры в DP, ни привязку к конкретному контролу Avalonia — только **направление**. Публичный контракт примитивов для сторонних авторов **не цель текущей фазы** (см. [§ открытые вопросы](#adr0063-open-questions)). Отдельно решать, когда появится необходимость: общий слой **токенов** (цвет/толщина по severity), **a11y** (не только цвет), связь с **intent** ([0051](0051-intent-based-attention-routing-toml.md)), **продуктовые правила** для Presence/Activity **по разным UiMode** — актуально, когда в продукте снова будет **несколько** режимов; на текущей линии разработки **один режим — Flight**, остальное намеренно вне scope ([§ открытые вопросы](#adr0063-open-questions), [0017 § режимы UI](0017-multi-window-workspace-and-agent-surfaces.md#adr0017-modes-scope)). |
| 190 | |
| 191 | <a id="adr0063-intent-and-deck"></a> |
| 192 | |
| 193 | ### Intent routing и deck |
| 194 | |
| 195 | **Intent routing и deck ([0051](0051-intent-based-attention-routing-toml.md); вопрос уточнён):** intent задаёт **политику внимания** (какой якорь, какой профиль, какие подсказки) — не «заменяет» deck. Внутри deck поведение зависит от **режима композиции**: при **сетке на одной `Page`** (все ячейки видны, образ PFD) intent может подсвечивать **ячейку** или **поток данных**, а не «вкладку». При **вкладках/стеке** (один видимый инструмент) отдельно задаётся, может ли intent **переключать активную вкладку** или только поднимать **якорь** — это продуктовое правило **после** появления такой композиции в коде, не догма ADR. |
| 196 | |
| 197 | <a id="adr0063-open-questions"></a> |
| 198 | |
| 199 | ## Открытые вопросы |
| 200 | |
| 201 | **Контекст:** внешней аудитории и **публичного** контракта примитивов пока нет — разрабатываем так, как удобно внутри репозитория; при смене решения переложить код проще, чем ломать чужих потребителей. **Плагины и сторонние авторы инструментов** отложены; вопрос «стабильный enum в Contracts» **не блокирует** текущую работу. |
| 202 | |
| 203 | **Режимы UI:** на текущей линии разработки **один продуктовый режим — Flight**; прочие семейства / пресеты UiMode **намеренно не ведём** (переработка Power, Balanced и т.д. — **отдельная** дорожная карта, см. [0017 § «Уточнение: режимы UI»](0017-multi-window-workspace-and-agent-surfaces.md#adr0017-modes-scope)). Продуктовая формулировка «актуальная линия (ветка Skia, ~2026), один режим Flight, старые референсы Focus/Balanced/Power — архив» — в [`docs/ui-ux/README.md`](../ui-ux/README.md). Ветка **`feature/skia`** и работа по инструментам **не обязаны** заранее согласовывать политику Presence по несуществующим режимам. **Вопрос дифференциации Presence/Activity по разным UiMode** (Focus / Power / …) и отдельной нормативки против «вечной» анимации **снят для текущей фазы**: достаточно общих принципов [§ Presence / Dark Cockpit](#adr0063-presence-dark-cockpit); вернуться к пресетам по режимам или отдельному ADR — **если** снова появится **несколько** продуктовых режимов или явная потребность. |
| 204 | |
| 205 | - **Публичный enum / контракт** по расширенному набору примитивов (в т.ч. Readout, Trend, Gauge, Stack, Caption, Presence/Activity) и **где ровно граница** с произвольной отрисовкой инструмента и с [§ примитив vs инструмент](#adr0063-primitive-vs-instrument) — оставить на **фазу перед** плагинами и публичной поверхностью; сейчас достаточно таксономии в этом ADR и внутренних типов по мере надобности. |
| 206 | |
| 207 | ## Последствия |
| 208 | |
| 209 | - Вопрос «вводить ли `ContentRepresentation` в код» считается **снятым по смыслу ADR**: канон имени оси формы — **`ContentRepresentation`**; `IdeHealthUiSurface` — текущая привязка IDE Health; обобщение на другие каналы данных — **та же ось формы**, не «вторая ось канала» — см. [§](#adr0063-content-representation-code). |
| 210 | - Вопрос «deck в пресетах vs только внутри композитора» закрыт **эволюционно**: сначала внутренний чертёж; декларативные именованные колоды — позже и отдельным контрактом; локальный эксперимент допустим — см. [§](#adr0063-deck-presets-evolution). |
| 211 | - Связка **`ContentRepresentation.Page` + instrument deck** зафиксирована как образ **одного экрана с несколькими приборами** (PFD); узкий случай IDE Health — см. [§](#adr0063-page-plus-deck-pfd). Сочетание **intent** и deck — см. [§](#adr0063-intent-and-deck). |
| 212 | - **MFD:** навигация между страницами оболочки (`MfdShellPage`) и **deck внутри страницы** разведены нормативно — см. [§ deck страницы MFD](#adr0063-mfd-page-deck); декларативные пресеты **каталога** страниц Mfd отложены **в той же логике**, что [§ deck в пресетах](#adr0063-deck-presets-evolution). |
| 213 | - Документация и ADR, где фигурирует «страница» в смысле композиции инструментов, могут со временем **сослаться на этот ADR** и уточнить, речь о **deck** или о **IDE Health Page**. |
| 214 | - Реализация композиции в слоте (сетка на **`Page`**, вкладки, порядок) получает **стабильное имя** для обсуждения и тестов без смешения с маршрутизацией [0050](0050-declarative-instrument-zone-placement-toml.md). |
| 215 | - Появляется **общий словарь** для компактных deck-экранов: какие **виды** индикаторов допустимы в ячейке, не смешивая с **формой** канала (Strip/Page) и с **deck** как списком инструментов. |
| 216 | - Зафиксировано правило: **примитив = атомарный glance**, **инструмент = сценарий с состоянием** — см. [§](#adr0063-primitive-vs-instrument). |
| 217 | - Зафиксировано: **CDS** не есть presentation UI; граница с **топологией дисплеев** и со **deck** — см. [§](#adr0063-cds-not-presentation). Направление снятия путаницы **presentation** (ключи **`display.screens`**, **`topology`**) — нормативно [0017 §](0017-multi-window-workspace-and-agent-surfaces.md#adr0017-display-screens-topology-naming). |
| 218 | - На фазе **только Flight** вопрос отдельной политики Presence/Activity **по UiMode** не ставится (см. [§ открытые вопросы](#adr0063-open-questions)); при возврате мультирежимности — заново по необходимости. |
| 219 | |
| 220 | --- |
| 221 | |
| 222 | ## История изменений |
| 223 | |
| 224 | <a id="adr0063-history"></a> |
| 225 | |
| 226 | | Дата | Изменение | |
| 227 | |------|-----------| |
| 228 | | — | [§ CDS не presentation](#adr0063-cds-not-presentation). | |
| 229 | | — | [§ ContentRepresentation и код](#adr0063-content-representation-code) — вопрос про enum закрыт формулировкой ADR. | |
| 230 | | — | [§ Page + deck](#adr0063-page-plus-deck-pfd) — один экран региона, несколько инструментов (образ PFD). | |
| 231 | | — | [§ deck в пресетах](#adr0063-deck-presets-evolution) — эволюционно, без обязательной сущности в TOML на старте. | |
| 232 | | — | [§ примитив vs инструмент](#adr0063-primitive-vs-instrument). | |
| 233 | | — | [§ типы индикаторов](#adr0063-indicator-kinds) — направление **Lamp / Bar / Sign** для компактных deck-страниц. | |
| 234 | | — | ключи топологии дисплеев / `display.screens` — нормативно [0017 §](0017-multi-window-workspace-and-agent-surfaces.md#adr0017-display-screens-topology-naming). | |
| 235 | | — | расширенная таксономия примитивов + [§ Presence и Dark Cockpit](#adr0063-presence-dark-cockpit). | |
| 236 | | — | статический Presence по геометрии — **Lamp**/Sign, не отдельный примитив. | |
| 237 | | — | то же по смыслу, что неформальное имя **CompositionPage** (см. [§ синоним](#adr0063-composition-page-synonym)). | |
| 238 | | 2026-04-18 | согласовано: **instrument deck** остаётся отдельной осью (композиция инструментов / порядок во вкладках и т.д.), ортогонально оси **`ContentRepresentation`** (Strip/Page). | |
| 239 | | 2026-04-24 | [§ deck страницы MFD](#adr0063-mfd-page-deck): композиция **внутри** одной страницы оболочки Mfd, ортогонально навигации между `MfdShellPage`. | |
| 240 | |