ADR 0115: CDS — общий слой graph-backed приборов (реализация в кабине, не IDS)¶
Статус: Accepted
Дата: 2026-05-14
Обновлено: 2026-05-14 — в коде: IGraphDataSource, адаптер workspace navigation map. Подробности — § История.
Связанные ADR¶
| ADR | Роль |
|---|---|
| 0036 | Канал → CDS → композитор → поверхность |
| 0067 | Контракт семейства graph-backed поверхностей |
| 0079 | IDS — оверлеи оболочки (не путать с CDS) |
| 0055 | Skia-этапы композиции |
| 0047 | Слоты и дескрипторы приборов |
| 0065 | Ось graph_kind |
| 0114 | Ось relation_kind |
| 0113 | HCI, edge_provenance |
| 0097 | CCU → DTO канала (§4 в тексте) |
| 0106 | SemanticMapInputSnapshot и интеграция индекса |
Проблема¶
0067 задаёт измерения контракта (модель, взаимодействие, provenance, relation_kind, синхронизация с workspace, …) для всех graph-backed поверхностей, но не фиксирует явно, в каком продуктовом контуре живёт общая реализация: кабина (CDS) vs оверлей IDE (IDS). В дискуссии легко появляется третий «DisplaySystem» (условный GraphDisplaySystem), который размывает границу 0079 § CDS vs IDS.
Нужен ADR уровня размещения: где в архитектуре собирается переиспользуемый код общих частей graph-backed приборов и как он стыкуется с уже принятой цепочкой 0036.
Решение¶
1. Инвариант размещения¶
Общий слой graph-backed приборов — это подсистема внутри контура кабины (CDS), а не параллель IDS и не отдельный верхнеуровневый «Display System».
- Графовые экраны продукта (Semantic Map, GitMap, будущие dependency graphs и т.д.) остаются приборами / регионами поверхности в смысле 0021 и проходят ту же логическую цепочку 0036: данные и намерение — в канале / связанных сервисах; маршрутизация по зонам — CDS; свёртка в разметку слота — композитор; поверхность — Avalonia/Skia-хост в
Cockpit/Surface(или эквивалент), без импортаIdeDisplayизCockpit/(CASCOPE016).
2. Что относится к «общему слою» (целевое разделение)¶
Общий слой (имя в коде — решение реализации; рабочее пространство имён в духе Cockpit.* + суффикс Graph / GraphSurface / GraphBacked):
- общие протоколы документа графа (узел/ребро, ключи сессии, опциональные поля
graph_kind,edge_provenance,relation_kind— см. 0065, 0113, 0114); - абстракция источника данных для поверхности:
IGraphDataSourceвCascadeIDE.Cockpit.Graph— методBuildNavigationJsonпринимаетCodeNavigationMapJsonRequest(v0: wire JSON карты намерений / workspace navigation); конкретные провайдеры — адаптеры (сейчасWorkspaceNavigationMapContextJsonDataSourceвFeatures/WorkspaceNavigation/Application) без привязки generic-каркаса к Roslyn в VM; - повторяемые куски interaction (пан/зум/hit-test policy, лимиты Dark Cockpit), где домен не уникален;
- точка подключения к 0055 (Intent / Declutter / Layout / Render), не дублируя доменную загрузку графа;
- соглашения по command routing и observability для агента, совместимые с таблицей измерений 0067.
Остаётся доменно-специфичным у каждого graph_kind / инструмента:
- реализация источника (реализация
IGraphDataSource/ композиция нескольких источников: Roslyn, Git, HCI-кандидаты, …); - выбор layout engine и визуальная семантика узла (иконки, подписи, цвет по домену);
- обработчики команд «перейти к исходнику» там, где семантика не выводится только из
relation_kind+ стандартной таблицы действий.
Нюанс «поверхности пофиг»: каркасу действительно безразличен конкретный backend, пока документ графа и метаданные рёбер удовлетворяют контракту. Но не на 100%: доверительный UX (подписи/иконки по edge_provenance), дефолтные действия по relation_kind, ограничения навигации — часто оформляются в общем слое политиками и подсказками, а не только внутри адаптера; иначе каждый адаптер дублирует одно и то же.
4. Связь с CCU и внешними входами¶
Свёртка сырья в DTO канала до или вокруг CDS остаётся по 0097. Входы вроде SemanticMapInputSnapshot (0106, 0113) питают канал/композитор graph-backed прибора; не заменяют graph-backed interaction layer.
5. Явное «не делаем»¶
- Не вводим IdeDisplay.Graph и не смешиваем граф кабины с IDS*, пока нет отдельного продукта «граф только как глобальный оверлей» (тогда — отдельный ADR и осознанное исключение).
- Не дублируем текст 0067: этот ADR про где живёт код общего слоя, а не про повторение таблицы измерений.
Последствия¶
- Ревью новых графовых фич: вопрос «куда кладём общий код?» → внутри CDS/Cockpit, ссылка на 0115; «какие измерения соблюсти?» → 0067.
- Поиск дублирования viewer между Semantic Map и GitMap → вынос в общий пакет в границах Cockpit, а не в
IdeDisplay.
Rollout (эскиз)¶
- Документ (этот ADR) как стабильная ссылка для дизайн-ревью.
- Strangler: v0 —
IGraphDataSource+ адаптер на существующийWorkspaceNavigationMapContextJsonBuilder; refresh PFD через интерфейс. Далее — вынос общих частей композитора/политик по мере второго потребителя (0067). - По мере стабилизации — уточнить неймспейс и CASCOPE-правила в
CascadeIDE.ArchitectureAnalyzersпри необходимости (отдельный мини-ADR или правка существующих guardrails).
История изменений¶
| Дата | Изменение |
|---|---|
| 2026-05-14 | абстракция источника графа (IGraphDataSource / эквивалент) в общем слое; адаптеры — доменно. |
| 2026-05-14 | в коде: CascadeIDE.Cockpit.Graph.IGraphDataSource, CodeNavigationMapJsonRequest, адаптер WorkspaceNavigationMapContextJsonDataSource; MainWindowViewModel берёт JSON через интерфейс. |