Forge
markdowndeeb25a2
1# CascadeIDE.ArchitectureAnalyzers
2
3Roslyn-анализаторы для границ [ADR 0036](../docs/adr/0036-cds-channel-compositor-surface-pipeline.md) (CDS / кабина) и [ADR 0079](../docs/adr/0079-ide-display-system-ids-overlay-pipeline.md) (IDS / `IdeDisplay/`). Норматив по **вычислительным юнитам (CCU)** между транспортом и каналом — [ADR 0097](../docs/adr/0097-cockpit-compute-units-transport-to-channel-dto.md); для IDE Health закреплено **CASCOPE019** ([ADR 0099](../docs/adr/0099-ide-databus-typed-events-and-projections.md)); прочие диагностики под CCU — по мере выделения устойчивых анти-паттернов (см. §3–4 в 0097). Подключён к `CascadeIDE.csproj` как `Analyzer` (`ReferenceOutputAssembly=false`), **кроме** загрузки через **RoslynMcp**: при `RoslynMcpWorkspace=true` ссылка на этот проект отключается, чтобы процесс MCP не блокировал `bin\…\CascadeIDE.ArchitectureAnalyzers.dll` во время `dotnet build` (общий механизм — раздел «RoslynMcpWorkspace» в [roslyn-mcp README](../../roslyn-mcp/README.md)).
4
5**Поведение:** обычный `dotnet build` / CI без `RoslynMcpWorkspace` по-прежнему получают CASCOPE*; в MCP по главному приложению эти диагностики из локального проекта анализатора не подмешиваются — для проверки правил ориентируйся на **`dotnet build`** или на этот проект отдельно. Если в тулы передаётся полный **`CascadeIDE.sln`**, проект анализатора всё ещё может подгружаться; для MCP достаточно контекста приложения — предпочтительнее путь к **`CascadeIDE.csproj`**.
6
7| ID | Уровень | Смысл |
8|----|---------|--------|
9| **CASCOPE001** | Error | В `Cockpit/Channels`, `Cockpit/Cds`, `Cockpit/Composition` запрещены ссылки на типы Avalonia UI (включая `using Avalonia…` и типы в сигнатурах). `Cockpit/Surface` и `Views` не затрагиваются. |
10| **CASCOPE002** | Error | В тех же трёх папках запрещён `using CascadeIDE.Features.UiChrome` (семантика зон для MCP — на границе Surface). |
11| **CASCOPE003** | Error | Прямые присваивания `IsPfdRegionExpanded` / `IsMfdRegionExpanded` (и полям `_is*`) у `MainWindowViewModel` только в белом списке файлов (`PresentationLayoutAuthority`, relay-команды, ctor / `ShellConstruction`, `ShellState`, `UiGitWorkspace`); иначе — дрейф от ADR 0046 (используй `Apply*` / relay). |
12| **CASCOPE011** | Error | В `Features/UiChrome/` запрещён `using CascadeIDE.Cockpit.PrimitivesKit` (ADR 0066: хром IDE отдельно от отрисовки deck/кабины). |
13| **CASCOPE012** | Error | В `Cockpit/PrimitivesKit/` запрещён `using CascadeIDE.Features.UiChrome` (ADR 0066: примитивы кабины не тянут зоны/хром). |
14| **CASCOPE013** | Error | В `IdeDisplay/` запрещён `using CascadeIDE.Cockpit…` и типы из `CascadeIDE.Cockpit` в сигнатурах членов (ADR 0079: IDS ортогонален CDS/кабине). |
15| **CASCOPE014** | Error | В `IdeDisplay/` запрещены Avalonia UI (как у CASCOPE001: `using Avalonia…` и типы в членах). |
16| **CASCOPE015** | Error | В `IdeDisplay/` запрещён `using CascadeIDE.Features.UiChrome` и типы из этого пространства в членах (семантика оверлея отдельно от хрома shell). |
17| **CASCOPE016** | Error | В `Cockpit/` запрещён `using CascadeIDE.IdeDisplay…` (кабина не зависит от IDS). |
18| **CASCOPE017** | Error | Лимит строк: `Views/MfdShellView.axaml` (каркас EICAS + `MfdContourStackHost` + `MfdShellPageStack`) — см. `MaxLineCountMfdShellView` в анализаторе; `Views/MfdShellPageStack.axaml` (набор страниц Mfd) — `MaxLineCountMfdShellPageStack`. Детальная вёрстка — в *MfdPageView. |
19| **CASCOPE018** | Error | В обоих файлах (см. **CASCOPE017**) запрещены тяжёлые inline-паттерны (`ListBox`, `TextBox`, `ItemsControl`, `GridSplitter`, `DataTemplate`, многостолбцовая `ColumnDefinitions=…`) — вынос в *MfdPageView. |
20| **CASCOPE019** | Error | Во всех `MainWindowViewModel*.cs`, кроме `MainWindowViewModel.IdeHealth.cs`, запрещён вызов `_workspaceHealth.Build(...)` (единая точка свёртки в `RebuildIdeHealth`, строки в UI — из кэша; см. [ADR 0099](../docs/adr/0099-ide-databus-typed-events-and-projections.md)). |
21| **CASCOPE020** | Warning | В `Cockpit/ComputingUnits/*` запрещён прямой доступ к внешним источникам (`File`, `Directory`, `Process`, `HttpClient`, `JsonDocument/Serializer` и др.): добыча данных — в DAL ([ADR 0102](../docs/adr/0102-data-acquisition-layer-boundary-and-contract.md)). |
22| **CASCOPE021** | Warning | В `Cockpit/ComputingUnits/*` запрещены UI-зависимости через `using` (`CascadeIDE.ViewModels`, `CascadeIDE.Views`, `CascadeIDE.Features.Ui*`, `Avalonia*`). |
23| **CASCOPE030** | Error | В `Features/*/Application` у типа с `[ApplicationOrchestrator]` запрещены static-поля (состояние процесса — в host/DAL/CCU). |
24| **CASCOPE031** | Error | Статический orchestrator в `Features/Application` не вызывает `File`/`Process`/`HttpClient` и др. напрямую — I/O в DAL/instance service. |
25| **CASCOPE032** | Info | `*Orchestrator` в `Features/*/Application` без `[ApplicationOrchestrator]`. |
26| **CASCOPE033** | Info | `ICockpitComputeUnit` в `Cockpit/ComputingUnits` без `[ComputingUnit]`. |
27| **CASCOPE034** | Info | `*PresentationProjection` без `[PresentationProjection]` / `[ComputingUnit]`. |
28| **CASCOPE035** | Warning | `[ApplicationOrchestrator]` на типе, имя которого не оканчивается на `Orchestrator`. |
29| **CASCOPE036** | Error | `[ComputingUnit]` на типе с суффиксом `Orchestrator` — используйте `[ApplicationOrchestrator]`. |
30| **CASCOPE037** | Error | `[ApplicationOrchestrator]` в `Cockpit/ComputingUnits` (роли не смешивать). |
31| **CASCOPE038** | Info | Статический helper в `Features/Application` без суффикса `Orchestrator`/`Projection` и **без** `[ComputingUnit]` / `[PresentationProjection]` / `[ApplicationOrchestrator]` — рассмотрите явную роль. |
32| **CASCOPE039** | Warning | `*Orchestrator` похож на чистую projection (нет async/Task, координации) — рассмотрите `*PresentationProjection`. Не срабатывает на `[ApplicationOrchestrator]` с делегированием в `*Service`/`*Runner`/`*Session` или входом `JsonElement`/`GraphDocument`. |
33| **CASCOPE040** | Warning | Только `[PresentationProjection]`: прямой I/O (`File`, `Process`, `HttpClient`, …) — вынести в DAL/orchestrator. Типы с `[ComputingUnit]` в Application не проверяются (I/O-исключения вроде markdown-export). |
34| **CASCOPE041** | Info | `*Projection` в `ViewModels` — перенос в `Features/*/Application`. |
35| **CASCOPE042** | Info | `*Projection` (не `*PresentationProjection`) в `Features/Application` без маркера роли. |
36
37Маркеры ролей в `CascadeIDE.Contracts`: `[ApplicationOrchestrator]`, `[ComputingUnit]` (CCU), `[PresentationProjection]` (биндинг из снимка). См. [ADR 0097](../docs/adr/0097-cockpit-compute-units-transport-to-channel-dto.md), [architecture-migration](../docs/architecture-migration.md).
38
39### Черновые направления (правила пока не вводим)
40
41- **HCI: JSON MCP против события DataBus.** Ответы `SerializeStatus(IndexStatus)` в `Features/HybridIndex/McpParity/` содержат полный снимок ядра; типизированное `HybridIndexStateChanged` после CCU узже (см. ADR 0106 и XML на `HybridIndexStateChangedUnit` / `CodebaseIndexIdeJsonResponses.SerializeStatus`). Возможное жёсткое CASCOPE-правило на подмножество полей — только после того, как стабилизируем контракт шины для UI и MCP parity.
42
43`MfdShellView.axaml` и `MfdShellPageStack.axaml` — в `<AdditionalFiles>` в `CascadeIDE.csproj` (**CASCOPE017**/**018**). Без записи проверка не сработает.
44
45Расширение правил: новые диагностики в этом проекте, версии `Microsoft.CodeAnalysis.CSharp` держать совместимыми с SDK.
46
47Rollout для новых правил границ DAL/CCU: сначала `Warning` (baseline и очистка), затем перевод в `Error` после стабилизации.
48
View only · write via MCP/CIDE