| 1 | # CDS — контракт «кабины» в CascadeIDE (чертёж v0) |
| 2 | |
| 3 | **Статус:** живой чертёж (не ADR). **Назначение:** зафиксировать **контрактный смысл CDS** до разрастания кода и MCP, чтобы новые фичи расширяли **один** семантический слой, а не плодили параллельные «снимки внимания». |
| 4 | |
| 5 | **Связь:** [ADR 0036 — цепочка канал → CDS → композитор → поверхность](../adr/0036-cds-channel-compositor-surface-pipeline.md) (нормативная ось). [ADR 0021 §1.1 — CDS / `UiLayoutSnapshot`](../adr/0021-pfd-mfd-cockpit-attention-model.md#glossary-cds-contract), [0017](../adr/0017-multi-window-workspace-and-agent-surfaces.md) (мультиоконность, `presentation`), [workspace-health-implementation-map-v1](workspace-health-implementation-map-v1.md) (канал IDE Health — ортогонален CDS). |
| 6 | |
| 7 | --- |
| 8 | |
| 9 | ## 1. Зачем отдельный документ |
| 10 | |
| 11 | - **ADR 0021** задаёт **принципы** зон и внимания; этот файл — **черновик полей** агрегированного «состояния кабины» для API, тестов и агента. |
| 12 | - **`UiLayoutSnapshot`** остаётся слоем **дерева контролов**; CDS — слой **семантики** (что за кабина, без обхода визуального дерева). |
| 13 | |
| 14 | --- |
| 15 | |
| 16 | ## 2. Термины |
| 17 | |
| 18 | | Термин | Смысл | |
| 19 | |--------|--------| |
| 20 | | **CDS (контракт)** | Снимок **семантики** отображения: зоны, топология, окна, активный вторичный контур. Не реализация ARINC 661 и не один God-class в репозитории. | |
| 21 | | **Cockpit surface state** (рабочее имя DTO) | Условное имя будущей структуры/JSON, агрегирующей поля ниже; версионируется (`schema_version`). | |
| 22 | | **Канал** | Поток данных внутри слота (IDE Health, EICAS, readiness) — **не** входит в CDS целиком; в CDS только **какие слоты/страницы активны**, без полного текста сегментов. | |
| 23 | | **Instrument (кабинный)** | Именованный выбор **представления в слоте внимания** (результат композитора); не `Control` Avalonia. Термин сознательно в духе PFD/MFD; в бытовом английском *instrument* многозначно — в глоссарии закреплено значение «логическая единица кабины», см. [ADR 0047](../adr/0047-cockpit-instrument-descriptor-and-slot-composition.md). Дескриптор в коде — `CockpitInstrumentDescriptor` (`Cockpit/Composition/CockpitInstrumentDescriptor.cs`). Пример слота PFD: дерево решения vs Semantic Map — два разных `instrument_id`. | |
| 24 | |
| 25 | --- |
| 26 | |
| 27 | ## 3. Слои (не смешивать) |
| 28 | |
| 29 | | Слой | Вопрос | Типичные источники в коде | |
| 30 | |------|--------|---------------------------| |
| 31 | | **CDS** | Какая **кабина** сейчас: пресет, зоны, окна, страница MFD | `presentation`, `PresentationParseResult`, флаги VM колонок/хоста, `CurrentMfdShellPage`, `AttentionLayoutSurfaceKind` | |
| 32 | | **Дерево UI** | **Что** нарисовано в виде контролов | `UiLayoutSnapshot`, MCP `ide_get_ui_layout` | |
| 33 | | **Каналы** | **Что** в полосах и списках | `Cockpit/Channels/**` (данные), `Cockpit/Composition/**` (порядок/разметка для VM): `Composition/Shell/MainWindowShellSurfaceCompositor` — только **колонки** PFD/MFD в main grid; `Composition/HostSurface/MainWindowHostSurfaceCompositor` — **кадр хоста** (shell + список `CockpitInstrumentDescriptor`, ADR 0047) без деревьев контролов — удобная граница перед Skia в слотах. | |
| 34 | | **Avalonia (хост)** | Окна, фокус, ввод, DPI; **фюзеляж** для тяжёлых контролов (редактор и т.д.); **не** канон смысла зон — см. [architecture-policy.md](../architecture-policy.md) (раздел «Avalonia и слой кабины») | `MainWindow`, `MfdHostWindow`, привязки VM; отрисовка слотов кабины — поверх хоста (в т.ч. Skia) по кадру композитора | |
| 35 | |
| 36 | ### Источник правды сегодня и как сблизить с CDS |
| 37 | |
| 38 | **Сейчас** каноническое **состояние кабины** в рантайме по-прежнему живёт в **свойствах `MainWindowViewModel`** (видимость колонок, активная страница оболочки Mfd, хост Mfd и т.д.); **CDS** — **проекция** в `CockpitSurfaceState` через [`CockpitSurfaceSnapshotBuilder`](../../Cockpit/Cds/CockpitSurfaceSnapshotBuilder.cs) — это уже **язык для агента, тестов и наблюдаемости** ([ADR 0036 п. 2](../adr/0036-cds-channel-compositor-surface-pipeline.md#adr0036-p2)), не дубль «второй источник правды», если снимок **детерминирован** от VM. |
| 39 | |
| 40 | **Улучшать** имеет смысл инкрементально: |
| 41 | |
| 42 | 1. **Читать семантику кабины** в тестах и инструментации прежде всего из **`Build(vm)`** / готового DTO, а не из россыпи полей VM. |
| 43 | 2. **Сужать мутации**: страница shell, топология, хост — через **узкий набор методов**, чтобы после каждого шага снимок CDS оставался согласованным. |
| 44 | 3. **Позже** — выделить явный агрегат «состояние навигации кабины» (один тип), из которого и биндинги, и билдер CDS читают одни и те же поля; полный перенос истины в отдельный сервис с подпиской VM — только при явной потребности (дорого). |
| 45 | |
| 46 | --- |
| 47 | |
| 48 | ## 4. Черновик полей v0 (эволюция) |
| 49 | |
| 50 | Поля **не** обязаны совпадать с текущими именами свойств VM — это целевой контракт для стабилизации. |
| 51 | |
| 52 | ```json |
| 53 | { |
| 54 | "schema_version": "0.3", |
| 55 | "ui_mode": "string", |
| 56 | "presentation_effective_line": "string", |
| 57 | "presentation_parse_success": true, |
| 58 | "topology": { |
| 59 | "surface_kind": "main_window_docked_grid | …", |
| 60 | "mfd_host_window_open": false, |
| 61 | "mfd_column_visible_in_main": true |
| 62 | }, |
| 63 | "mfd_shell": { |
| 64 | "current_page": "IdeHealth | Chat | Terminal | …" |
| 65 | }, |
| 66 | "zones": { |
| 67 | "pfd_visible": true, |
| 68 | "forward_visible": true, |
| 69 | "mfd_visible": true, |
| 70 | "pfd_required_by_presentation": true, |
| 71 | "forward_required_by_presentation": true, |
| 72 | "mfd_required_by_presentation": true |
| 73 | }, |
| 74 | "instruments": [ |
| 75 | { |
| 76 | "instrument_id": "solution_explorer_tree", |
| 77 | "slot_id": "pfd", |
| 78 | "schema_version": "0.2" |
| 79 | } |
| 80 | ] |
| 81 | } |
| 82 | ``` |
| 83 | |
| 84 | **Намеренно узко v0:** без дублирования каналов данных, без геометрии в пикселях (bounds — при необходимости отдельное расширение или слой [0017](../adr/0017-multi-window-workspace-and-agent-surfaces.md)). |
| 85 | |
| 86 | --- |
| 87 | |
| 88 | ## 5. Версионирование |
| 89 | |
| 90 | - **`schema_version`** — семантическое версионирование JSON (например `0.1`, `0.2` при добавлении полей). |
| 91 | - Обратная совместимость для потребителей MCP: явно документировать в [MCP-PROTOCOL.md](../MCP-PROTOCOL.md), когда появится отдельный инструмент или расширение существующего. |
| 92 | |
| 93 | --- |
| 94 | |
| 95 | ## 6. Реализация (статус) |
| 96 | |
| 97 | | Этап | Содержание | |
| 98 | |------|------------| |
| 99 | | **Сейчас** | DTO `CockpitSurfaceState` и вложенные записи в `Cockpit/Cds/CockpitSurfaceState.cs`; сборка — `Cockpit/Cds/CockpitSurfaceSnapshotBuilder.Build(MainWindowViewModel)`; точка входа на VM — `MainWindowViewModel.BuildCockpitSurfaceSnapshot()` (см. также `EffectivePresentationLine`, `IsMfdHostWindowShellOpen`, `IsForwardZoneVisible`). В `schema_version=0.3` добавлен список `instruments` (`instrument_id`, `slot_id`, `schema_version`) как проекция HostSurface-кадра для MCP/наблюдаемости. **MCP:** тот же объект вложен в `ide_get_ide_state` как поле `cockpit_surface` (паритет со Skia/UI). | |
| 100 | | **Дальше** | При необходимости — отдельный тул `ide_get_cockpit_state` (если понадобится без полной сводки); стабилизация полей по обратной связи агента/тестов. | |
| 101 | |
| 102 | --- |
| 103 | |
| 104 | ## 7. Связанные файлы кода (ориентиры) |
| 105 | |
| 106 | - `Cockpit/Cds/CockpitSurfaceState.cs`, `Cockpit/Cds/CockpitSurfaceSnapshotBuilder.cs` — CDS (семантика кабины); `Cockpit/Cds/AttentionLayoutSurfaceKind.cs` — вид топологии в снимке. |
| 107 | - `Cockpit/Composition/CockpitInstrumentDescriptor.cs` — дескриптор инструмента слота (ADR 0047). |
| 108 | - `Cockpit/Composition/Shell/MainWindowShellSurfaceCompositor.cs` — метрики колонок shell. |
| 109 | - `Cockpit/Composition/HostSurface/MainWindowHostSurfaceFrame.cs`, `MainWindowHostSurfaceCompositor.cs`, `CockpitHostSurfaceIds.cs` — кадр для хоста (shell + инструменты); стабильные `instrument_id` / `slot_id`. |
| 110 | - `Cockpit/Surface/MainWindowInstrumentMountRegistry.cs` — реестр монтирования `instrument_id → mount` (хост-слой, вне композитора; Avalonia/Skia backend). |
| 111 | - `Cockpit/Surface/UiLayoutSnapshot.cs` — дерево UI (другой слой, ADR 0036 п.4). |
| 112 | - Каналы и композиторы по ADR 0036 — `Cockpit/Channels/**`, `Cockpit/Composition/**`. |
| 113 | - `Services/Presentation/PresentationParser.cs`, `PresentationLayoutAnalyzer.cs` — презентация. |
| 114 | - `Views/MainWindow.axaml`, `MainWindow.PresentationHostWindows.axaml.cs` — геометрия и жизненный цикл вторичных `TopLevel` (PFD/MFD). |
| 115 | |
| 116 | --- |
| 117 | |
| 118 | **Версия документа:** 2026-04-17 — список файлов UI: `MainWindow.PresentationHostWindows.axaml.cs` для вторичных TopLevel (PFD/MFD). Ранее: 2026-04-16 — подраздел «Источник правды сегодня и как сблизить с CDS» (проекция из VM, инкрементальное улучшение). Ещё ранее: 2026-04-15 — v0.3: список `instruments` в CDS-снимке + реестр монтирования в Surface-слое. |
| 119 | |