Перейти к содержанию

ADR 0067: Graph-backed surfaces — общий контракт для семейства графовых экранов

Статус: Accepted
Дата: 2026-04-19
Обновлено: 2026-05-14 — ссылка на размещение общего слоя реализации в CDS (0115), не IDS. Подробности — § История.

Связанные ADR

ADR Роль
0065 Ось graph_kind, категории инструментов
0113 Оси provenance, сводка трёх осей
0114 Каталог relation_kind на рёбрах
0115 Общий слой реализации в CDS, не IDS
0062 GitMap — домен данных, общий pipeline
0053 Semantic Map, control flow
0056 Внедрение Skia pipeline в карту
0055 Intent → Declutter → Layout → Render
0039 Навигация, MCP, subgraph
0047 Instrument, слот, поверхность
0021 Зоны внимания PFD/MFD
0066 Поверхность прибора vs хром IDE (ModalOverlay)

Резюме

  • Общий контракт graph-backed поверхностей: данные, взаимодействие, layout, sync.
  • Семейство: карта намерений, GitMap, будущие графы; реализация — 0115.
  • Оси graph_kind, provenance, relation_kind — в 0065, 0114.

Контекст

В IDE появляется не один графовый экран, а семейство поверхностей, где пользователь и агент работают с графом как с главным объектом: Semantic Map (намерения кода / control flow), GitMap / submodules (0062), возможные будущие графы (зависимости, топология сервисов и т.д.).

Если каждый сценарий вести отдельным ad-hoc viewer, неизбежно дублируются:

  • модель данных и идентичность узла/ребра в workspace;
  • взаимодействие (масштаб, прокрутка, hit-test, жесты);
  • семантика навигации («перейти к символу», «раскрыть subgraph», «синхронизировать с редактором»);
  • абстракция раскладки (чтобы не копировать layout между доменами);
  • выделение, фокус, клавиатурный контур;
  • согласование с остальным workspace (дерево решения, открытые файлы, MCP, инвалидация при смене ветки/git).

Нужен общий архитектурный класс UIgraph-backed surface — и явный контракт по измерениям ниже; различаются домен графа и источник данных, а не заново изобрётся колесо для каждого use case.

Задача уровня архитектуры платформы, а не просьба «нарисуй узлы и рёбра».

Ключевая мысль: граф — не только визуализация

Graph в этой IDE — это не синоним картинки для отчёта.

Graph-backed surface — это навигационная поверхность IDE на тех же правах, что редактор, терминал, диагностики, обозреватель решения: не декоративная диаграмма и не export-only preview, а операционный surface, через который и человек, и агент могут исследовать структуру, выбирать узлы, переходить к исходникам, фильтровать, фокусироваться и выполнять действия. Визуализация — следствие модели и контракта, а не наоборот.


Решение

Зафиксировать понятие graph-backed surface (рабочее имя): инструмент или фрагмент UI, в котором первична работа с ориентированным (или помеченным) графом как с объектом навигации и действий, согласованная с кокпитом и workspace по единым правилам; отрисовка — один из слоёв, не определение поверхности. Размещение общей реализации переиспользуемых частей этого класса в продукте — в контуре CDS / Cockpit, не в IDS; см. 0115.

Ограничения: что это не является

Чтобы реализация и внешние агенты не «уезжали» в одноразовый viewer:

  • это не «diagram control» как полный ответ (диаграмма без модели навигации и синхронизации с workspace);
  • это не слой только rendering;
  • это не фича под один CFG / один use case;
  • это расширяемая платформа для нескольких graph-backed инструментов (Semantic Map, GitMap, будущие графы зависимостей / связей и т.д.).

Дополнительные требования к платформе

Помимо таблицы измерений, к целевому контракту относятся:

  • Единая абстракция документа графа (например GraphDocument или эквивалент): узлы/рёбра, метаданные, привязка к домену и graph_kind (0065).
  • Единая семантика навигационных команд: из узла — к исходникам, деталям, связанному подграфу / related graph (формулировки могут отличаться по домену, канал действий — один).
  • Сериализуемое состояние surface: выделение, viewport, фильтры — для восстановления сессии, тестов и согласования с остальными панелями.
  • Agent introspection: состояние surface читаемо агентом и командами (MCP / ide_*), без единственной опоры на пиксели.
  • Разные layout engines как подключаемые стратегии без поломки модели документа (см. Layout abstraction и 0055).

Инвариант: Semantic Map, GitMap и последующие графовые экраны — представления одного класса в смысле контракта; они не обязаны делить один instrument_id или один JSON wire-формат, но обязаны быть сопоставимы по измерениям §2, чтобы команда и агент могли переносить ожидания между экранами.

Реализация допускается поэтапно (strangler): сначала два потребителя (например Semantic Map + GitMap) выявляют общий минимум; контракт в коде (interface / набор протоколов) расширяется без нарушения ADR.

Измерения контракта (что явно согласовывается)

Измерение Вопрос, на который отвечает слой Примечание
Data model Что такое узел и ребро в этом домене; стабильный ключ в пределах сессии; связь с graph_kind и категорией инструмента (0065). Домены ортогональны: код vs git-топология — разные графы, один класс поверхности.
Edge / node provenance На каком источнике правды держатся связи и узлы для этого экрана: символьная модель (Roslyn), эвристика workspace (MSBuild), полнотекст/vec по корпусу (HCI), композит (например HCI → Roslyn). Ортогонально graph_kind: тот же вид карты может сочетать слои с разным provenance; таблица и имена — 0113 § оси.
Relation kind Какое отношение между сущностями утверждает ребро (наследует, ссылается на, partial peer, текстовое совпадение, …). 0114; ортогонально graph_kind и provenance.
Interaction model Пан, зум, «перетаскивание» вида, hit-test, ограничения FPS/Dark Cockpit (0021 §6). Общие паттерны; детали могут отличаться по инструменту.
Navigation semantics Что значит «перейти», «открыть», «запросить subgraph», как это стыкуется с MCP и агентом (0039). Семантика действий, не только отрисовка.
Layout abstraction Где граница между данными графа и геометрией: этапы 0055; сменяемые layout engines под вид графа без дублирования Render. GitMap и CFG не обязаны иметь один layout engine; обязаны иметь одинаковую точку подключения в pipeline.
Selection / focus model Один или несколько выбранных узлов; фокус клавиатуры; связь с «текущим» узлом для агента и UI. Нужна согласованность с остальным кокпитом.
Command routing Команды IDE, контекстное меню, хоткеи доходят до surface предсказуемо; не дублировать разрозненные обработчики без политики. Связь с 0013, 0030.
Deep-linking / воспроизводимость Переход по ссылке на узел/фильтр/view state; согласование с сериализуемым состоянием. Не обязательно в v1 полностью; направление зафиксировано.
Sync with workspace Связь выделения с редактором, деревом решения, git-состоянием; инвалидация при смене файла, ветки, решения; без второго источника правды. Явные события или снимки, не скрытые глобалы.
Observability (agent) Снимок состояния surface для агента и автоматизации; не только «что нарисовано», но и выделение, фокус, доменные ключи узлов. См. доп. требования.

Контракт не требует одного общего типа Graph в памяти для всех доменов — требует сопоставимости протоколов и отсутствия несогласованных one-off viewer без обоснования.

Стартовый prompt для агента (English)

Текст ниже можно использовать как единую отправную точку для проектирования и ревью (Cursor и др.):

We need to design a reusable graph-surface architecture for the IDE, not a one-off graph viewer. Existing and upcoming features such as Semantic Map (CFG), Git submodules, and future dependency / relationship graphs should all fit the same conceptual model.

A graph in this IDE is not just a visualization; it is an interactive workspace surface with navigation, focus, selection, commands, synchronization with other panes, and agent-readable state — on par with the editor, terminal, diagnostics, and solution explorer.

This is not: only a diagram control; only a rendering layer; a single feature for one CFG use case. It should be an extensible platform for multiple graph-backed tools.

Please propose an architecture for a generic graph-surface framework, including where appropriate:

  • graph document model and node/edge metadata;
  • layout abstraction and pluggable layout engines without breaking the document model;
  • interaction contract (pan/zoom/hit-test as needed);
  • command routing and unified navigation semantics (e.g. node → source / details / related graph);
  • selection/focus and synchronization with the rest of the IDE workspace;
  • deep-linking and serializable surface state;
  • agent introspection over surface state.

Cross-check with ADR 0067 (graph-backed surfaces) and related ADRs on graph_kind, Semantic Map, GitMap, and the Skia pipeline.


Последствия

  • Новые графовые фичи проходят проверку: какое измерение уже покрыто общим слоем, что доменно-специфично.
  • Документация и ревью могут ссылаться на graph-backed surface и таблицу измерений вместо «ещё одна карта».
  • Пайплайн 0055 остаётся общим местом для Layout/Render; источники графа подключаются как адаптеры, а не форки viewer.

Не-цели (текущая фаза)

  • Единый универсальный layout для всех видов графов в одном релизе.
  • Полная реализация всех измерений в коде до появления второго и третьего потребителя контракта — допустим минимальный v0 и расширение.
  • Замена 0062 или 0065: они уточняют домен; этот ADR уточняет класс UI.

Альтернативы (кратко)

Вариант Минус
Отдельный viewer на каждый граф Дублирование, расхождение навигации и синхронизации с workspace
Один жёсткий GraphView control на все данные Не гнётся под разные домены и layout; тормозит эволюцию
Только гайд в Markdown без ADR Нет стабильной ссылки для ревью и онбординга

История изменений

Дата Изменение
2026-04-19 ключевая мысль «операционная surface», ограничения, доп. требования, seed для агента (EN).
2026-05-14 измерения Edge / node provenance (0113 § оси) и Relation kind (0114); обе ортогональны graph_kind.
2026-05-14 ссылка на размещение общего слоя реализации в CDS (0115), не IDS.