| 1 | # ADR 0025: SDK и зоны внимания (PFD / Forward / MFD / EICAS / HUD) |
| 2 | |
| 3 | **Статус:** Proposed |
| 4 | **Дата:** 2026-04-08 |
| 5 | |
| 6 | ## Связанные ADR |
| 7 | |
| 8 | | ADR | Роль | |
| 9 | |-----|------| |
| 10 | | [0021](0021-pfd-mfd-cockpit-attention-model.md) | семантика зон и каналов внимания | |
| 11 | | [0024](0024-ide-sdk-and-stable-contracts.md) | SDK, capability‑модель, `CascadeIDE.Contracts` | |
| 12 | | [0010](0010-ui-modes-toml-configuration.md) | overlay презентации без подмены семантики | |
| 13 | |
| 14 | --- |
| 15 | ## Контекст |
| 16 | |
| 17 | [0024](0024-ide-sdk-and-stable-contracts.md) вводит SDK как способ держать **единую ментальную модель продукта** (модули, capabilities, introspection). Отдельно [0021](0021-pfd-mfd-cockpit-attention-model.md) задаёт **модель внимания** кокпита: три пространственных якоря (`Forward`, `Pfd`, `Mfd`), канал оповещений `Eicas`, слой `Hud` на лобовом. |
| 18 | |
| 19 | Сегодня зоны реализованы в приложении (`AttentionZone`, `AttentionZoneIds`, маппинг панелей — например `AttentionZonePanelRuntime`), а **`CascadeIDE.Contracts` не содержит явной оси «зона внимания»** для `UiSurfaceCapabilityDescriptor` / команд. Из‑за этого SDK и кокпитная геометрия живут рядом, без формального моста: агент, диагностика и overlay не могут опереться на один канонический словарь зон на уровне контрактов. |
| 20 | |
| 21 | Нужно зафиксировать **отдельное решение**: как связать capability‑слой с моделью внимания, не раздувая SDK и не дублируя разметку Axaml. |
| 22 | |
| 23 | --- |
| 24 | |
| 25 | ## Решение |
| 26 | |
| 27 | 1. **Канон зон — тот же, что в [0021](0021-pfd-mfd-cockpit-attention-model.md) и в коде:** строковые id `forward`, `pfd`, `mfd`, `eicas`, `hud` (см. `AttentionZoneIds` / `AttentionZone.ToCanonicalId()`). Семантика «EICAS — канал, не четвёртый якорь-колонка» **не меняется**. |
| 28 | |
| 29 | 2. **SDK должен уметь выражать привязку capabilities к зоне внимания** как **метаданные**, а не как дублирование визуального дерева: |
| 30 | - минимум: опциональное поле на **`UiSurfaceCapabilityDescriptor`** (и при необходимости на **`CommandCapabilityDescriptor`**, если команда считается привязанной к зоне по смыслу — напр. фокус в редакторе); |
| 31 | - значение: **канонический id зоны** (строка, совместимая с TOML overlay и capability‑map), либо ссылка на общий enum/константы в `CascadeIDE.Contracts` после выноса. |
| 32 | - для поверхностей, совпадающих с **панелью shell**: опциональное **`HostAttentionPanelId`** (`AttentionPanelCanonicalIds`) вместе с **`PrimaryAttentionZoneId`** — мост к `AttentionZonePanelRuntime`; см. [attention-zone-panel-playbook-v1](../design/attention-zone-panel-playbook-v1.md) и проверку **`CapabilityAttentionConsistency`** при сборке карты. |
| 33 | |
| 34 | 3. **Презентация по-прежнему через overlay** ([0010](0010-ui-modes-toml-configuration.md), [0024](0024-ide-sdk-and-stable-contracts.md)): видимость, размер, вкладка MFD shell — **не** переносятся целиком в SDK. Зона в контракте отвечает на вопрос **«где в модели внимания живёт эта поверхность»**, а не «в каком пикселе». |
| 35 | |
| 36 | ### Нативные диалоги (Open/Save) и метаданные зоны |
| 37 | |
| 38 | - **Зона в SDK не задаёт**, что выбор файла или решения обязан рисоваться **внутри** MFD/Forward как встроенная панель. Это отдельное решение **пресета и UX** ([0010](0010-ui-modes-toml-configuration.md)); при необходимости его явно проектируем (онбординг, режимы), а не выводим из одного поля «зона». |
| 39 | - **Системные диалоги открытия/сохранения** на десктопе обычно реализуются как **отдельное top-level окно** (модально к приложению); типичные API **не предназначены** для встраивания того же UI «в ячейку» сетки кокпита как дочернего виджета. Имеется в виду: нативный выбор — это **оверлей поверх сцены**, хотя команда могла быть вызвана из зоны (кнопка в MFD, палитра и т.д.). |
| 40 | - **Политика продукта (по умолчанию):** опираться на **нативный диалог ОС** для выбора пути/файла, чтобы не отнимать у пользователя привычный проводник и интеграции облака/ОС; **свой** встроенный браузер файлов в области shell — только если это **осознанное** решение сценария (inline-опыт, единая сцена для агента и т.п.), а не обязательное следствие модели зон. |
| 41 | - **Избыточность:** навязывать всем командам заполненную зону «для галочки» не нужно; команды с **глобальным** смыслом (палитра, настройки, открытие файла через системный диалог) могут оставаться **без** первичной зоны в метаданных или с зоной только там, где это реально помогает карте capabilities (см. открытые вопросы ниже). |
| 42 | |
| 43 | 4. **Реализация — поэтапно:** |
| 44 | - **Фаза A (документ):** этот ADR + ссылка из [0024](0024-ide-sdk-and-stable-contracts.md). |
| 45 | - **Фаза B (контракты):** **сделано:** `AttentionZoneCanonicalIds` + опциональное `PrimaryAttentionZoneId` на `CommandCapabilityDescriptor` и `UiSurfaceCapabilityDescriptor`; строковые id в приложении (`AttentionZoneIds`) алиасят константы из Contracts. |
| 46 | - **Фаза C (реестр):** заполнять поля при регистрации модулей по смыслу; `CapabilityMap` и JSON-дампы содержат зону и `HostAttentionPanelId` (сериализация record). При обоих заданных — согласованность с `AttentionZonePanelRuntime` (предупреждение в Debug при `BuildMap()`). Playbook: [attention-zone-panel-playbook-v1](../design/attention-zone-panel-playbook-v1.md). |
| 47 | - **Фаза D (опционально):** снять оставшееся дублирование — enum/расширения только в приложении, строки — из Contracts везде, где уместно. |
| 48 | |
| 49 | 5. **Стабильность:** новые поля в `Experimental` namespace контрактов; изменение набора зон или id — только с обновлением [0021](0021-pfd-mfd-cockpit-attention-model.md) и этого ADR. |
| 50 | |
| 51 | --- |
| 52 | |
| 53 | ## Последствия |
| 54 | |
| 55 | - Capability‑map и агентские сценарии смогут отвечать: «эта UI‑поверхность задекларирована как MFD», без чтения Axaml. |
| 56 | - Появляется явная связь между **продуктовой метафорой кокпита** и **машиночитаемым SDK** — то, что ожидалось от «ментальной модели в SDK», но вынесено в отдельное решение, чтобы не смешивать с общим scope [0024](0024-ide-sdk-and-stable-contracts.md). |
| 57 | - Риск: лишняя формальность, если регистрировать зону «для галочки». Митигация: поле опционально; дефолт «не задано», пока фича не осознанно относится к зоне. |
| 58 | |
| 59 | --- |
| 60 | |
| 61 | ## Отклонённые альтернативы |
| 62 | |
| 63 | - **Только теги в `Tags` без канона** — слишком слабо для инструментов и валидации overlay. |
| 64 | - **Полная схема layout в SDK** — избыточно; разметка остаётся в UI, в SDK — только семантическая ось внимания. |
| 65 | - **Всё держать только в [0024](0024-ide-sdk-and-stable-contracts.md)** — размывает документ и смешивает два уровня решений (общий SDK vs кокпитная ось). |
| 66 | |
| 67 | --- |
| 68 | |
| 69 | ## Открытые вопросы |
| 70 | |
| 71 | - Нужна ли явная привязка **Service** capability к зоне (обычно нет — сервис без UI) vs только **UiSurface** (да). |
| 72 | - Нужен ли отдельный тип «зона не применима» для команд, которые глобальны (палитра, настройки). |
| 73 | |