| 1 | # ADR 0095: Три уровня Health — Workspace, Solution, IDE (таксономия каналов) |
| 2 | |
| 3 | **Статус:** Accepted (частично: WorkspaceHealth MFD + каналы; полная трёхуровневая таксономия — по ADR) |
| 4 | **Дата:** 2026-04-24 |
| 5 | **Обновлено:** 2026-04-25 — TOML-ключи IDE Health: `ide_health_*`. Подробности — [§ История](#adr0095-history). |
| 6 | ## Связанные ADR |
| 7 | |
| 8 | | ADR | Роль | |
| 9 | |-----|------| |
| 10 | | [0089](0089-ide-omnibus-naming-and-ide-health-channel-rename.md) | продуктовое имя **IDE Health** и типы `IdeHealth*`; **не** снимает смешение сигналов по смыслу | |
| 11 | | [0097](0097-cockpit-compute-units-transport-to-channel-dto.md) | **CCU / вычислительный блок**: где живёт свёртка входов в DTO при сохранении `stratum` | |
| 12 | | [0102](0102-data-acquisition-layer-boundary-and-contract.md) | **DAL**: где добываются внешние данные до CCU | |
| 13 | | [0021](0021-pfd-mfd-cockpit-attention-model.md) | канал vs слот презентации; глоссарий | |
| 14 | | [0036](0036-cds-channel-compositor-surface-pipeline.md) | канал → CDS → композитор → поверхность | |
| 15 | | [0023](0023-environment-readiness-glance.md) | Канал «готовность окружения» (glance) — отдельно от IDE Health | |
| 16 | | [0022](0022-workspace-health-lexicon.md) | лексикон и эволюция имён | |
| 17 | | [0019](0019-shared-git-core-ide-and-git-mcp.md) | Git как сквозной контур | |
| 18 | | [0062](0062-git-submodules-semantic-map-subgraph.md) | GitMap — файловая/git-геометрия отдельно от кода решения | |
| 19 | | [0052](0052-agent-contract-cli-and-snapshot-tests.md) | снапшоты MCP — при сплите уровней потребуются явные секции или версия схемы | |
| 20 | |
| 21 | ## Резюме |
| 22 | |
| 23 | - Три уровня Health: **Workspace** · **Solution** · **IDE**; поле `stratum`. |
| 24 | - Strangler от монолитного «workspace health»; TOML `ide_health_*` ([0010](0010-ui-modes-toml-configuration.md)). |
| 25 | |
| 26 | ### Вне ADR |
| 27 | |
| 28 | | Документ | Роль | |
| 29 | |----------|------| |
| 30 | | [`environment-readiness-glance-v1.md`](../design/environment-readiness-glance-v1.md) | канал **готовности окружения** — уже ближе к уровню IDE | |
| 31 | | [`workspace-health-implementation-map-v1.md`](../design/workspace-health-implementation-map-v1.md) | текущая карта полосы IDE Health | |
| 32 | |
| 33 | --- |
| 34 | ## Контекст |
| 35 | |
| 36 | После [0089](0089-ide-omnibus-naming-and-ide-health-channel-rename.md) канал в продукте называется **IDE Health**, но **по смыслу** в один пользовательский образ (полоса, кокпит, снапшот для агента) по-прежнему попадают сигналы **разной природы**: |
| 37 | |
| 38 | 1. **Файловая и VCS-стихия** — корень открытого workspace, git status/ветка/удалённость, субмодули, «грязь» дерева; часть этого **не исчезает** при смене solution внутри того же каталога и **не** является диагностикой компилятора. |
| 39 | 2. **Жизнь решения / проекта** — результат **MSBuild**, счётчики/статус тестов, ошибки компиляции, Roslyn-диагностики **в привязке к открытому solution**; меняется при смене `.sln` / конфигурации / целевого фреймворка. |
| 40 | 3. **Жизнь процесса IDE и окружения** — LSP (C#, Markdown, …), MCP-транспорты, выбранный режим AI, доступность `dotnet`/инструментов из [0023](0023-environment-readiness-glance.md); остаётся **истинным**, если закрыть solution, но не переустанавливать IDE. |
| 41 | |
| 42 | Смешение уровней мешает: |
| 43 | |
| 44 | - **агенту и MCP** — в одном JSON легко принять «состояние папки» за «состояние сборки» или наоборот; |
| 45 | - **CDS и будущим каналам** — один «health» без тега уровня плохо масштабируется на новые инструменты ([0036](0036-cds-channel-compositor-surface-pipeline.md)); |
| 46 | - **UX** — оператору нужны разные **контексты внимания** (см. [0021](0021-pfd-mfd-cockpit-attention-model.md)): «что на диске», «что с билдом», «что с хостом IDE». |
| 47 | |
| 48 | Этот ADR **вводит нормативную таксономию трёх уровней** и направление на **разведение каналов / секций данных**; он **не** обязан в одном коммите переписать всю реализацию `IdeHealth*` (ключи TOML контура в UiModes — **`ide_health_*`**, [0010](0010-ui-modes-toml-configuration.md)). |
| 49 | |
| 50 | --- |
| 51 | |
| 52 | <a id="adr0095-three-levels"></a> |
| 53 | |
| 54 | ## Решение: три уровня (семантика) |
| 55 | |
| 56 | Зафиксировать **три оси смысла** для Health и **аналогичных** каналов наблюдаемости: |
| 57 | |
| 58 | | Уровень | Рабочее имя в текстах | Вопрос «о чём речь?» | Типичные сигналы (примеры, не исчерпывающе) | |
| 59 | |--------|------------------------|----------------------|---------------------------------------------| |
| 60 | | **A** | **Workspace** | Каталог(и) workspace на диске и **VCS** вокруг него | путь корня, git branch/ahead/behind, чистота рабочего дерева, субмодули ([0062](0062-git-submodules-semantic-map-subgraph.md)), конфликты merge | |
| 61 | | **B** | **Solution** (или *Solution / project*) | **Открытое решение и артефакты сборки/тестов** | статус/текст сборки, тесты (пройдено/упало), ошибки компиляции, целевая TFM/конфигурация, при необходимости — выбранный startup project | |
| 62 | | **C** | **IDE** | **Процесс IDE, хосты и окружение**, не дерево исходников | LSP alive, MCP подключения, режим AI, проверки PATH/EXE из [0023](0023-environment-readiness-glance.md), внутренние сервисы | |
| 63 | |
| 64 | **Инвариант:** любой новый «health» или канал наблюдаемости **объявляет**, к какому уровню (A/B/C) он относится; **запрещено** silently смешивать уровни в одном DTO без явной структуры или дискриминатора. |
| 65 | |
| 66 | **Имя поля в машинных контрактах** (JSON, MCP, CDS): рекомендуется ключ **`stratum`** со значениями `workspace` | `solution` | `ide` **в паре** с дискриминатором источника сигнала (например **`diagnostic_source`** для Roslyn-ветки). Ось A/B/C **не** называть в контракте **`level`**: слово чаще читается как приоритет, глубина стека или severity и хуже дискриминируется в логах и UI. |
| 67 | |
| 68 | **Представление (UI):** три уровня **не** означают автоматически **три отдельные полосы** на экране. Допустимы: одна **составная** полоса с **внутренней** группировкой по уровням; несколько инструментов в одном якоре ([0063](0063-instrument-deck-named-composition-one-anchor.md)); отдельные страницы MFD. Норматив — **семантика данных**, а не конкретная вёрстка v1. |
| 69 | |
| 70 | --- |
| 71 | |
| 72 | ## Направление на реализацию (strangler) |
| 73 | |
| 74 | 1. **CDS / снапшоты:** при эволюции контракта кабины ([`cds-contract-v0.md`](../design/cds-contract-v0.md)) — секции или подканалы с полем **`stratum`** (`workspace` | `solution` | `ide`) либо **отдельные** каналы с явными именами; детальный JSON **не** фиксируется этим ADR. |
| 75 | 2. **MCP / `get_ide_state`:** при расширении ответа — **не** добавлять поля «в общую кучу»; новые блоки должны быть помечены **`stratum`** (и при необходимости источником, например `diagnostic_source`) или вынесены в отдельные тулы, если смешение сохраняет путаницу ([0089](0089-ide-omnibus-naming-and-ide-health-channel-rename.md), [0052](0052-agent-contract-cli-and-snapshot-tests.md)). |
| 76 | 3. **Код текущего IDE Health:** поэтапно разнести сборку входного снимка ([`workspace-health-implementation-map-v1.md`](../design/workspace-health-implementation-map-v1.md)) на провайдеры по уровням A/B/C с **одной** точкой композиции для UI; wire-ключи режимов для контура — **`ide_health_*`** ([0010](0010-ui-modes-toml-configuration.md)). Архитектурная роль «свёртки» в снимок/DTO — см. [0097](0097-cockpit-compute-units-transport-to-channel-dto.md). |
| 77 | |
| 78 | <a id="adr0095-stratum-ccu-examples"></a> |
| 79 | |
| 80 | ### Пример: отдельные вычислители по стратам (не God-object) |
| 81 | |
| 82 | Один **God-object**, который тянет и Git, и MSBuild, и LSP в одном методе, **не** целевой паттерн. Нормативное направление — **несколько [cockpit compute units](0097-cockpit-compute-units-transport-to-channel-dto.md) (CCU)** с узким контрактом входа/выхода и **одна** точка композиции для канала/UI. Ниже — **рабочие инженерные** имена-сокращения (обсуждения, ревью, комментарии); **не** требование так назвать типы в C# в ближайшем коммите. |
| 83 | |
| 84 | | Уровень | Рабочее имя (англ.) | Сокращение | Типичный смысл свёртки | |
| 85 | |--------|----------------------|------------|-------------------------| |
| 86 | | **A** | Workspace Status Computation Unit | **WSCU** | каталог(и) workspace, VCS, субмодули, «грязь» дерева | |
| 87 | | **B** | Solution Status Computation Unit | **SSCU** | открытое решение, сборка, тесты, TFM/конфигурация | |
| 88 | | **C** | IDE Status Computation Unit | **ISCU** | процесс IDE, LSP, MCP, окружение ([0023](0023-environment-readiness-glance.md)) | |
| 89 | |
| 90 | **ISCU** — про **уровень C** и *статус хоста/IDE*; **не** путать с **IDS** ([0079](0079-ide-display-system-ids-overlay-pipeline.md) — *Ide Display System*, оверлеи). При письме «в одном предложении с IDS» лучше писать **ISCU** полностью или явно дискриминировать аббревиатуру. |
| 91 | |
| 92 | --- |
| 93 | |
| 94 | ## Границы и открытые вопросы |
| 95 | |
| 96 | **Границы (не цели этого ADR):** |
| 97 | |
| 98 | - Конкретные имена типов (`IWorkspaceHealthChannel` vs три интерфейса), дальнейшая эволюция схемы DTO, немедленный сплит AXAML на три контрола. |
| 99 | - **Отладка** как отдельный **продуктовый** контур ([0002](0002-debug-human-agent-parity.md)) — ортогональна; связь с уровнем B/C (сессия решения vs процесс IDE) уточняется при моделировании, **без** подмены этого ADR полным debug-ADR. |
| 100 | |
| 101 | **Открытые вопросы:** |
| 102 | |
| 103 | - **Git** одновременно относится к A (ветка, ahead/behind) и может отражать **состояние билда** в смешанных сценариях — нужны правила приоритета и дубликатов в UI. |
| 104 | - **Roslyn:** часть диагностик — про решение (B), часть — про анализаторы/окружение (C); см. [уточнение ниже](#adr0095-roslyn-b-vs-c). |
| 105 | - **Несколько корней на диске** — как сопоставить уровень A (VCS/файлы), когда в одном окне не один смысл «папка на диске»; см. уточнение ниже. |
| 106 | |
| 107 | <a id="adr0095-roslyn-b-vs-c"></a> |
| 108 | |
| 109 | ### Уточнение: Roslyn — B vs C и единый вывод в UI |
| 110 | |
| 111 | **Сводный UI для пользователя** (одна полоса, один список диагностик) **ничему не противоречит** и согласуется с абзацем **«Представление (UI)»** в [таблице уровней](#adr0095-three-levels): три уровня A/B/C — про **семантику данных**, а не обязанность трёх отдельных визуальных полос. |
| 112 | |
| 113 | **Для реализации** граница B/C по Roslyn **часто извлекаема** из модели (компилятор vs идентификатор анализатора, проект, правила), но **не всегда однозначна по смыслу**: одна и та же ошибка в UI может отражать и код, и окружение (восстановление пакетов, TFM, SDK); анализаторы из пакетов решения формально относятся к B, а ощущаются как «политика/настройка»; сбой загрузки анализатора — уже явный C. |
| 114 | |
| 115 | **Для пользователя** граница **когнитивно** часто неочевидна: всё сливается в «IDE ругается», растёт риск **неправильной атрибуции** (чинить код вместо среды). Поэтому в контрактах снимка для CDS/MCP/агента полезно **сохранять** **`stratum`** и источник (например **`diagnostic_source`**), даже если в штатном UI показ **объединённый**; при необходимости — лёгкие маркеры в UI (группа «среда» vs «код») или раскрытие «подробности». |
| 116 | |
| 117 | <a id="adr0095-umbrella-vs-multiroot"></a> |
| 118 | |
| 119 | ### Уточнение: «зонтичное» решение и настоящий multi-root |
| 120 | |
| 121 | **Один файл** `.sln` / `.slnx` как точка входа, в котором перечислены проекты с **относительными** путями, выходящими **за каталог** этого файла, — для **уровня B** штатная ситуация: граф сборки и тестов задаётся **манифестом решения** целиком, независимо от того, что часть исходников физически лежит «сбоку» от каталога файла решения. |
| 122 | |
| 123 | Для **уровня A** тот же сценарий **не** подменяет собой multi-root окна: вопрос сводится к **геометрии git** — один репозиторий, охватывающий все задействованные пути (тогда A **один**: один worktree и одна картина «грязи»), либо **несколько** вложенных/соседних репозиториев по разным корням (тогда возможны **несколько источников A** и нужна явная политика: приоритетный корень сессии, вторичные, агрегат **без** silent merge в одно поле). |
| 124 | |
| 125 | **Multi-root окна** в смысле «несколько независимых корней **без** единого файла решения как точки входа» — **другой** продуктовый режим; он остаётся открытым по UX и по тому, **какой** каталог считать единственным «корнем» для снимка A, но **не смешивается** в этом ADR с зонтичным решением выше. |
| 126 | |
| 127 | --- |
| 128 | |
| 129 | ## Отклонённые альтернативы |
| 130 | |
| 131 | - **Оставить один канал «IDE Health» без внутренней таксономии** — отклонено как накопление технического долга для CDS, MCP и новых каналов. |
| 132 | - **Переименовать уровни в «Workspace Health / Solution Health / IDE Health» как три продукта** — отклонено: слово *workspace* в пользовательском имени снова тянет путаницу с каталогом ([0089](0089-ide-omnibus-naming-and-ide-health-channel-rename.md)); в продуктовых строках предпочтительны формулировки вроде «состояние папки и Git», «сборка и тесты», «среда IDE» при сохранении **уровней A/B/C** как **внутренних** идентификаторов и ключей контракта. |
| 133 | |
| 134 | --- |
| 135 | |
| 136 | ## Последствия |
| 137 | |
| 138 | - Новые фичи и ADR, затрагивающие наблюдаемость, **ссылаются** на этот ADR и явно указывают уровень A/B/C (или осознанное нарушение с обоснованием). |
| 139 | - Рефакторинг `IdeHealth*` становится **планируемым** с трекингом по уровням, а не только косметическим переименованием. |
| 140 | |
| 141 | --- |
| 142 | |
| 143 | ## История изменений |
| 144 | |
| 145 | <a id="adr0095-history"></a> |
| 146 | |
| 147 | | Дата | Изменение | |
| 148 | |------|-----------| |
| 149 | | 2026-04-25 | ссылки на TOML: ключи **IDE Health** в `UiModes` — **`ide_health_*`** ([0010](0010-ui-modes-toml-configuration.md)); формулировки про миграцию `workspace_health_*` приведены в соответствие с репозиторием. | |
| 150 | |