IDE Health — полоса и страница (реализация: IdeHealth*) — implementation map (v1)
Статус: живой чертёж (не ADR). Обновлено: 2026-04-25 — ссылка на ADR 0097: цепочка IdeHealthInputSnapshot → IdeHealthFormattingUnit / IdeHealthSurfaceCompositor — пример вычислительных юнитов (CCU) между источниками и UI. 2026-04-25 — в коде VM: IdeHealthSegments, метод RebuildIdeHealth() (ранее WorkspaceHealthSegments / RebuildWorkspaceHealth). 2026-04-24 — продуктовое имя и типы в документе выровнены с ADR 0089 (IDE Health, IdeHealth*); ключи TOML ide_health_* (см. 0010, UiModeCapabilities). Ранее: 2026-04-17 — legacy-слой удалён; канон IIdeHealthChannel.Build(...) -> IdeHealthSurfaceCompositor.Compose(...). Ранее: 2026-04-11 — имя файла: workspace-health-implementation-map-v1.md (ранее workspace-health-compositor-implementation-v1.md — переименовано: документ про канал IDE Health и карту намерений, а не про «композитор стекла» IDE целиком). Ранее: 2026-04-11 — каноническое имя контура: IDE Health (ранее Workspace Health); §1: «слот презентации vs канал»; ссылка на ADR 0021 §1.2. Ранее: 2026-04-06 — WorkspaceHealthSecondaryPageView (ныне IdeHealthMfdPageView) + строка в §3/§4; отсылка к ADR: содержимое якоря PFD/MFD vs Page канала. Ранее: 2026-04-05 — §7.1: решение v1 = вариант A (отдельный контур EICAS); ранее — union types / вариант B, углубление, фазы.
Решения и термины — в ADR 0021 (PFD/MFD/EICAS, ARINC 661-идеи); канонический словарь «канал / слой представления / имена в коде» — §1.1. Лексикон и эволюция имён — ADR 0022, переименование канала — ADR 0089. Слой свёртки сырья в снимок/DTO канала (LRU-подобный модуль) — ADR 0097. Здесь — где в коде и что дальше, чтобы не раздувать ADR.
1. Термины (глоссарий)
| Термин | Смысл |
|---|---|
| Зона PFD / MFD / EICAS | Семантическая роль участка UI из ADR 0021: первичный контекст, вторичные потоки, канал оповещений. Где на экране задаётся пресетом (TOML/capabilities), не перетаскиванием в сессии. |
| Снимок IDE Health | IdeHealthInputSnapshot: нормализованные входы (build/tests/debug/git) до компоновки поверхности. Не привязан к форме «полоски». |
| Композиция поверхности канала | IdeHealthSurfaceCompositor: из снимка собирает упорядоченные IdeHealthSegment (порядок, флаги вроде IsBuildRunning). Отвечает за состав канала IDE Health, не за пиксели и не за зону PFD/MFD. |
| Раскладка зоны / страницы (chrome layout) | Куда на экране попадают блоки: полоса снизу, сетка на странице MFD, карточка в PFD. Задаётся пресетом и шаблонами (AXAML) и/или отдельным слоем в коде; рабочее имя в дизайне — layout страницы зоны / display page layout. Только геометрия контейнера в зоне, не дублирует порядок build/tests — тот уже зафиксирован IdeHealthSurfaceCompositor. |
| Поверхность (surface) | Слой представления: как показать те же сегменты (полоса, страница, карточка в хроме). Выбор Strip vs Page (ide_health_surface, enum IdeHealthUiSurface) — пресет и разметка; снимок и IdeHealthSurfaceCompositor не зависят от этого слоя. Это не «хост событий» и не шина сообщений — только UI. Каноническое имя оси «форма» в ADR: ContentRepresentation (Strip / Page); см. ADR 0063 § две оси. |
| Strip (полоса) | Конкретная поверхность представления: узкая горизонтальная полоса — IdeHealthStripView (CLR-класс в AXAML может ещё называться WorkspaceHealthStripView до полной зачистки). |
| Page (страница) | Другая поверхность представления только для канала IDE Health (ide_health_surface): те же сегменты в регионе PFD/MFD вместо полосы. Это не определение всего содержимого якоря — см. ADR 0021. |
| Канал EICAS | Оповещения W/C/A — отдельный семантический контур от IDE Health (ADR §5). Визуально — полоса, список, оверлей и т.д.; контейнер в текущей разметке: EicasAlertsBarView, TOML eicas_alerts_bar. Не путать со Strip/Page: те относятся к представлению build/tests/debug/git, а не к каналу CAS. |
Типы IdeHealth* задают смысл сегментов (build/tests/debug/git); IdeHealthStripView — одна из поверхностей представления; при странице MFD / блоке PFD те же данные идут в другую разметку без смены IdeHealthSurfaceCompositor.
Показ и данные развязаны: Strip или Page — это только слой представления (настройки пресета), не ветвление логики снимка и не хост событий. Strip отнимает высоту у лобового; Page не отнимает ту же полосу, но требует перехода взгляда — пользователь сам решает, что важнее, не меняя источники данных и IdeHealthSurfaceCompositor.
| Уровень | Смысл | Заметка |
|---|---|---|
| Слот презентации | Геометрия и роль поверхности: полоса vs полная страница региона MFD/PFD и т.д. | Разговорное «dedicated page» как «отдельная страница» часто про этот уровень. |
| Канал содержимого | Какой поток данных заполняет слот | IDE Health (этот документ), EICAS, статус окружения, другие инструменты — разные каналы. |
DedicatedPage в пресете IDE Health (ide_health_surface, enum IdeHealthUiSurface) относится только к каналу IDE Health: те же IdeHealthSegments, другая разметка (IdeHealthMfdPageView). Это не имя для «любой» полноэкранной страницы оболочки Mfd. Полное разведение терминов и рекомендуемые формулировки — ADR 0021 §1.2.
2. Идея в одном абзаце
Несколько источников (сборка, тесты, отладка, git) подают состояние и строки; один слой (IdeHealthSurfaceCompositor) задаёт порядок и состав сегментов — независимо от слоя представления (Strip или Page). Текущая разметка полосы: IdeHealthStripView (Balanced/Focus vs Power cockpit).
3. Карта файлов
| Компонент | Путь | Роль |
|---|---|---|
| Снимок входов | Cockpit/ComputingUnits/IdeHealth/IdeHealthInputSnapshot.cs |
IdeHealthInputSnapshot + IdeHealthSegmentInput (build/tests/debug/git + Stratum по ADR 0095). Точка расширения без раздувания сигнатур. |
| Композитор поверхности | Cockpit/Composition/IdeHealth/IdeHealthSurfaceCompositor.cs |
Compose(ObservableCollection<IdeHealthSegment>, IdeHealthInputSnapshot, IdeHealthSurfaceDecision); порядок: Build → Tests → Debug → Git; IsBuildRunning только на сегменте Build. |
| Модель сегмента | Cockpit/Channels/IdeHealth/IdeHealthSegment.cs |
LineText (полная строка), CockpitShort (Power), флаги для шаблона. |
| Источник enum | Cockpit/Channels/IdeHealth/IdeHealthSource.cs |
Build, Tests, Debug, Git. |
| Форматирование строк | Cockpit/ComputingUnits/IdeHealth/IdeHealthFormattingUnit.cs |
CCU: IdeHealthFormattingUnit : ICockpitComputeUnit, singleton Default; сегменты BuildSegment / TestsSegment / DebugSegment / GitSegment и Compose(...) — чистая логика без VM/DAP; удобно для юнит-тестов. |
| Канал снимка | Cockpit/Channels/IdeHealth/IIdeHealthChannel.cs, Cockpit/ComputingUnits/IdeHealth/IdeHealthSnapshotUnit.cs |
Build(IdeHealthChannelContext) собирает входы из делегатов и DAP (строки git и счётчики отладки подставляет MainWindowViewModel с Chrome / InstrumentationPanel). Сам канал не ссылается на UiChromeViewModel. |
| VM | ViewModels/MainWindowViewModel.IdeHealth.cs |
RebuildIdeHealth() вызывает _workspaceHealth.Build(...) и _workspaceHealthSurfaceCompositor.Compose(...). |
| Инвалидация | ViewModels/MainWindowViewModel.LayoutNotifications.cs |
RebuildIdeHealth при смене данных build/tests/debug. |
| Git-строки | Features/UiChrome/UiChromeViewModel.cs |
WorkspaceHealthGitText, WorkspaceHealthGitCockpitShort; подписка в MainWindowViewModel на Chrome.PropertyChanged. |
| Свойства для UI | ViewModels/MainWindowViewModel.Presentation.cs |
IdeHealthBuild* / IdeHealthTests* / IdeHealthDebug* — строки из кэша _lastIdeHealthInputSnapshot (один IIdeHealthChannel.Build на RebuildIdeHealth); Skia mount — IdeHealthMountPayload с тем же тиком. Флаги сессии отладки — из DAP. |
| Полоса хрома над нижним доком | Views/WorkspaceChromeBandView.axaml |
Сетка колонок как у MainGrid (0–4); слот EicasAlertsBarView и вложенный IdeHealthStripView. Включение полосы IDE Health: ShowIdeHealthStrip (ide_health_strip + IdeHealthUiSurface.BottomStrip в capabilities). По смыслу — контейнер представления нижней зоны (EICAS + Strip), не «хост событий». |
| UI полосы | Views/IdeHealthStripView.axaml |
ItemsControl по IdeHealthSegments; разные шаблоны для Power vs остальные режимы. |
| Страница оболочки Mfd (v1 — зона Mfd) | Views/IdeHealthMfdPageView.axaml |
Тот же IdeHealthSegments при ShowIdeHealthMfdPage (ide_health_strip + DedicatedPage); в MainWindow — над ChatPanelView в колонке зоны Mfd. |
| Тесты | CascadeIDE.Tests/IdeHealthSurfaceCompositorTests.cs, IdeHealthFormattingUnitTests.cs |
Композитор поверхности: порядок, IsBuildRunning. Формат: сегменты и Compose для снимка (IdeHealthFormattingUnitTests). |
4. Поток данных (кратко)
- Состояние меняется (сборка, тесты, DAP, git, …).
- Свойства
WorkspaceHealth*/IdeHealth*уведомляют UI (частично через[NotifyPropertyChangedFor], частично явныйOnPropertyChangedдля отладки). RebuildIdeHealth()берёт снимок через_workspaceHealth.Build(...)(внутри — делегаты/DAP/UiChromeViewModel+IdeHealthFormattingUnit) и вызывает_workspaceHealthSurfaceCompositor.Compose(...).IdeHealthSegmentsобновляется; привязка кIdeHealthStripView(черезWorkspaceChromeBandView) или кIdeHealthMfdPageViewв колонке зоны Mfd приDedicatedPage.
Альтернативная реализация канала (агент, MCP, моки в тестах VM) подменяет только сбор снимка, не IdeHealthSurfaceCompositor и не разметку полосы.
5. Статус vs ADR 0021 (первая строка таблицы ARINC)
| Идея ADR | В коде сейчас |
|---|---|
| Принцип ADR: единый слой смысла над источниками (не разрозненные toast) | Да: канал IDE Health — _workspaceHealth.Build(...) + _workspaceHealthSurfaceCompositor.Compose(...) + IdeHealthInputSnapshot. |
| Источники не владеют отдельным слоем toast без правил | Частично: строки централизованы; отдельные toast-цепочки не сводились сюда. |
| EICAS / Warning–Caution–Advisory | Нет: сегменты без уровня приоритета; полоса не EICAS-лента. |
| Декларативный merge из TOML | Частично: видимость полосы через capabilities/режимы; порядок/состав сегментов пока не из конфига. |
6. Краткий backlog (приоритет на усмотрение продукта)
- Пустые / placeholder-сегменты — см. §7.2; согласовать с Dark Cockpit (ADR 0021 §6).
- Приоритет / EICAS — отдельный контур оповещений и уровни W/C/A (ADR §5); см. §7.1 и §7.3.
- Конфиг — порядок/видимость сегментов IDE Health по режиму (TOML / capabilities); §7.4.
- Раскладка без нижней полосы — Page / карточка PFD; тот же снимок +
IdeHealthSurfaceCompositor, другой слой представления (§1, §7.5). - Канал снимка — сделано:
IIdeHealthChannel,IdeHealthSnapshotUnit,IdeHealthFormattingUnit.
7. Углубление: два контура, приоритет, Dark Cockpit
Ниже — рабочая модель для реализации без смешения «статуса работы» (сборка, тесты, отладка, git) и оповещений EICAS (Warning / Caution / Advisory). ADR уже разводит их по смыслу; в коде это стоит закрепить явно.
7.1 Два контура данных
| Контур | Назначение | Примеры | Приоритет W/C/A |
|---|---|---|---|
| IDE Health | Ориентир «что происходит с задачей» (build/tests/debug/git) | Сборка, тесты, сессия отладки, git | Не применяется — фиксированный канонический порядок в IdeHealthSurfaceCompositor (Build → Tests → Debug → Git) |
| EICAS / CAS | Оповещения, требующие внимания или действия | Падение MCP при L3, блокировка агента, критичная ошибка по файлу в фокусе | Да — сортировка и отсечение по уровню (ADR §5) |
Почему «просто один список» опасен без дисциплины: смешение в одной коллекции без явного тега «work vs alert» ведёт к спецслучаям в шаблонах и к риску раздуть полосу (Dark Cockpit). Это не запрет на один ItemsControl: при явном дискриминаторе проблема «полуслучайного порядка» снимается на уровне типов.
- Вариант A:
IdeHealthSurfaceCompositorостаётся только про IDE Health. EICAS — отдельная модель (EicasMessage, коллекция для UI), упорядочивание для UI —EicasMessageSorter(поSeverityи времени); размещение и представление (MainWindow/ зонаeicasпо пресету) задают, рисовать ли полосу над доком, оверлей или компактный список (ADR §5 уже допускает варианты). Это не тот же выбор, что Strip/Page для IDE Health. - Вариант B: дискриминированное объединение — один список элементов ленты, каждый элемент знает вариант: работа (build/tests/…) или EICAS; один
ItemsControlс шаблоном по типу/варианту;Rebuildстроит упорядоченную последовательность с разными правилами сортировки для каждой группы (сначала канон работы, внутри EICAS — по W/C/A), без смешения в одну «кучу».
Решение для v1: принят вариант A — отдельный контур EICAS в коде и в источниках данных. Это сознательная цена за ясность двух смыслов (работа vs оповещение), простые границы тестов и соответствие ADR; не избегание объединённого списка ради осторожности. Вариант B остаётся запасной траекторией для последующих версий (в т.ч. при зрелом C# union types и явном продуктовом решении о «одном ментальном канале»).
C# и union types: в языке появляются union types (union / закрытый набор кейсов, исчерпывающий pattern matching) — удобный носитель для варианта B на уровне модели. На .NET 11 Preview 2 атрибуты/интерфейс для unions в BCL ещё не обязательны в рантайме; в документации указано объявлять их в проекте до стабилизации превью. Пока целевой LangVersion репо ниже — тот же смысл можно выразить вручную через [Union]/ручной union-шаблон из спеки или остаться на record-иерархии + общий интерфейс, с пониманием, что компилятор не выгонит за забытую ветку так же жёстко.
Вариант B после принятия union types в toolchain становится существенно привлекательнее: меньше страха перед «if в разметке», больше ответственности за то, должен ли пользователь видеть работу и оповещения в одном ментальном канале (продукт/ADR), а не только за типобезопасность.
Текущий код (IdeHealthSegment без уровня приоритета) соответствует только первому контуру; расширение под EICAS — новые типы, а не «добавить поле Priority в Build».
flowchart LR
subgraph work [IDE Health]
Snap[IdeHealthInputSnapshot]
Comp[IdeHealthSurfaceCompositor]
Seg[IdeHealthSegments]
end
subgraph eicas [EICAS]
Feed[EicasFeed / провайдер]
Rank[EicasMessageSorter]
Cas[Eicas UI]
end
Snap --> Comp --> Seg
Feed --> Rank --> Cas
Визуально слои могут быть рядом (полоса IDE Health + узкая EICAS под/над ней по пресету), но логика и источники остаются раздельными.
7.2 Пустые сегменты и Dark Cockpit
Проблема: при пустых строках (нет git, тесты не запускались) либо пропадают «слоты», либо остаётся шум из placeholder’ов.
| Политика | Поведение | Плюсы / минусы |
|---|---|---|
| Compact | В полосу попадают только сегменты с непустым LineText (после trim) |
Меньше шума, соответствует «не показывать лишнее» (Dark Cockpit §6); меняется длина полосы |
| Fixed slots | Всегда 4 (или N) ячеек; пустые — «—» / приглушённый placeholder | Стабильный scan pattern; риск визуального мусора в тихом режиме |
| Режим-зависимый | Focus/Balanced — compact; Power — fixed для нижнего ряда кокпита | Согласуется с разными шаблонами в IdeHealthStripView |
Рекомендация для первой итерации: ввести флаг политики на уровне VM или пресета (StripEmptySegmentPolicy: Compact | FixedFour), реализовать фильтрацию или placeholder в одном месте — либо внутри IdeHealthSurfaceCompositor (не добавлять пустые), либо в отдельном шаге после Compose (нормализация коллекции). Не размазывать условия по AXAML.
7.3 Приоритет и сортировка
- IDE Health: порядок не конфигурируется приоритетом опасности — только фиксированная пермутация (при необходимости единственный конфиг: массив enum порядка в TOML, без W/C/A).
- EICAS: сортировка по уровню и времени/идентификатору; дубликаты сообщений — политика слияния (одна строка на источник). Связь с escalation и таймерами — в ADR §5, не в
IdeHealthFormattingUnit.
7.4 Конфиг сегментов IDE Health
Цель: какие источники включены в каком UiMode / capability, без смешения с EICAS.
- Минимум: расширение capabilities (например скрыть git в Focus).
- Полный вариант: в
workspace.tomlопциональный блок в духеattention_strip_order = ["build", "tests", "debug", "git"]и/илиattention_strip_enabled = { git = false }— парсится в структуру рядом сUiWorkspaceToml, merge с бандлом (ADR 0021 §2.1 / §17). IdeHealthSurfaceCompositor: читает не сырой TOML, а уже слитыйIdeHealthLayoutPolicy(immutable) на один вызовCompose, чтобы тестировать без файлов.
7.5 Page и нижняя полоса
Тот же IdeHealthInputSnapshot и тот же порядок сегментов подаются в другую разметку представления (Page): полноэкранная страница MFD или блок в PFD. Меняются только шаблоны (не одна строка на сегмент, допускается многострочный вывод). IdeHealthSurfaceCompositor не ветвится по Strip/Page.
7.6 Фазы внедрения (предложение)
| Фаза | Содержание | Критерий готовности |
|---|---|---|
| F1 | Политика пустых сегментов + тесты на IdeHealthSurfaceCompositor / нормализацию |
Предсказуемое поведение в Focus vs Power |
| F2 | Модель EicasMessage, провайдер, представление канала EICAS в зоне пресета (хотя бы список + цвет W/C/A) |
Один Warning виден без охоты по вкладкам (§18 / EICAS в ADR) |
| F3 | Dark Cockpit transition: из «тихо» в Warning (бейдж/полоса/оверлей по пресету) | Нет постоянной четвёртой колонки |
| F4 | TOML / merge для порядка и включения сегментов IDE Health | Согласовано с roadmap .cascade/workspace.toml |
| F5 | Страница IDE Health (Page) как альтернатива Strip | Тот же снимок, другой AXAML |
8. Связанные документы
environment-readiness-glance-v1.md— канал готовности окружения (LSP, инструменты, glance); не IDE Health. ADR: 0023.- ADR 0021 — модель внимания, зоны, EICAS (§5), Dark Cockpit (§6), метрики.
- ADR 0010 — режимы UI и capabilities.
cascade-ide-ui-layout-v1.md— раскладка окон.