| 1 | # ADR 0114: Тип отношения на рёбрах графа (`relation_kind`) — семантика связи |
| 2 | |
| 3 | **Статус:** Proposed |
| 4 | **Дата:** 2026-05-14 |
| 5 | |
| 6 | ## Связанные ADR |
| 7 | |
| 8 | | ADR | Роль | |
| 9 | |-----|------| |
| 10 | | [0065 §6](0065-instrument-categories-domain-taxonomy.md#adr0065-p6) | `graph_kind` — *какой* доменный граф (ортогонально) | |
| 11 | | [0067](0067-graph-backed-surfaces-contract.md#adr0067-dimensions) | Измерение edge / node **provenance** | |
| 12 | | [0113 § оси](0113-hci-semantic-map-orientation-layer.md#adr0113-axes) | Сводка трёх осей и HCI | |
| 13 | | [0039](0039-workspace-navigation-affordances.md) | Навигация workspace, related files | |
| 14 | | [0105](0105-hybrid-codebase-index-for-csharp-web.md) | Hybrid index, `hit_kind` | |
| 15 | |
| 16 | ## Резюме |
| 17 | |
| 18 | - Ось **`relation_kind`** на рёбрах графа («наследует», partial peer, …). |
| 19 | - Ортогонально `graph_kind` и provenance ([0113](0113-hci-semantic-map-orientation-layer.md)). |
| 20 | |
| 21 | |
| 22 | ## Проблема |
| 23 | |
| 24 | Для graph-backed поверхностей мы уже разводим: |
| 25 | |
| 26 | - **`graph_kind`** — форма доменного графа (карта намерений, related files, дерево модулей Git, …); |
| 27 | - **`edge_provenance`** — источник вычисления связи (Roslyn, MSBuild workspace navigation, HCI FTS/vec, композит). |
| 28 | |
| 29 | Этого **недостаточно**, чтобы пользователь и агент одинаково понимали **смысл ребра**: «наследник», «реализует интерфейс», «ссылается на тип», «тот же partial», «просто встречается в тексте рядом с именем» — разные **отношения**, и смешение их в одном безымянном «ребро есть» ломает доверие к карте, подсказкам MCP и авто-действиям. |
| 30 | |
| 31 | Нужен явный словарь **типа отношения** на ребре (или на логической связи узел→узел), независимый от того, *кто* его построил и *в каком* `graph_kind` экране оно показано. |
| 32 | |
| 33 | --- |
| 34 | |
| 35 | ## Решение |
| 36 | |
| 37 | ### 1. Понятие: `relation_kind` (рабочее имя) |
| 38 | |
| 39 | Ввести ось **`relation_kind`** (или эквивалент в wire-модели / MCP): **какую семантику отношения** мы утверждаем между двумя сущностями (или узлом и внешним якорем). |
| 40 | |
| 41 | **Инвариант:** `relation_kind` отвечает на вопрос **«что это за связь по смыслу?»**, а не «кто посчитал» (`edge_provenance`) и не «какой это экран графа» (`graph_kind`). |
| 42 | |
| 43 | <a id="adr0114-three-axes"></a> |
| 44 | |
| 45 | ### 2. Три оси (кратко) |
| 46 | |
| 47 | | Ось | Вопрос | |
| 48 | |-----|--------| |
| 49 | | **`graph_kind`** | В каком **доменном** графе мы работаем ([0065](0065-instrument-categories-domain-taxonomy.md#adr0065-p6)). | |
| 50 | | **`edge_provenance`** | **На какой модели/индексе** основана связь ([0113](0113-hci-semantic-map-orientation-layer.md#adr0113-axes), [0067](0067-graph-backed-surfaces-contract.md#adr0067-dimensions)). | |
| 51 | | **`relation_kind`** | **Какое отношение** между сущностями мы показываем или передаём в MCP (**этот ADR**). | |
| 52 | |
| 53 | Три значения **взаимно не подменяют** друг друга: одно и то же `relation_kind` (например «ссылка на тип») может встречаться при разном `edge_provenance` (Roslyn vs черновой HCI-кандидат — тогда **разный доверительный вес**, но **тот же смысл метки**, если мы сознательно маппим HCI-hit в «кандидат ссылается на»). |
| 54 | |
| 55 | ### 3. Черновой каталог `relation_kind` (расширяемо, не исчерпывающий enum в v1) |
| 56 | |
| 57 | Группы ниже — **ориентир для контракта**; точные строковые идентификаторы и набор фиксируются при появлении поля в DTO/MCP. |
| 58 | |
| 59 | **A. Символьные отношения (C# / Roslyn как источник истины для смысла)** |
| 60 | Примеры смыслов (имена условные до кодификации): |
| 61 | |
| 62 | - наследование / реализация (`inherits`, `implements`); |
| 63 | - ссылка на тип или член (`references_type`, `references_member`); |
| 64 | - вызов (`calls`); |
| 65 | - импорт пространства имён / сборки (`imports`, `assembly_reference` — если отражается на графе). |
| 66 | |
| 67 | **B. Отношения навигации по workspace (эвристики MSBuild / пресеты related)** |
| 68 | Согласовать с **[0039](0039-workspace-navigation-affordances.md)** и видами related: |
| 69 | |
| 70 | - «тот же тип partial» (`partial_peer`); |
| 71 | - «сосед по проекту / peer» (`project_peer`); |
| 72 | - «тест к коду» (`tests_peer`); |
| 73 | - иные виды из пресетов workspace navigation — как отдельные `relation_kind`, а не «просто edge без имени». |
| 74 | |
| 75 | **C. Корпусные отношения (HCI / FTS / vec)** |
| 76 | Здесь важно **не называть** связь символьными именами из группы A, если источник только текст: |
| 77 | |
| 78 | - «текстовое совпадение / вхождение имени» (`textual_name_match`); |
| 79 | - «похожий фрагмент по embedding» (`vector_similarity`); |
| 80 | - при явном сценарии «кандидат под символьное referenced-by» — отдельный маркер уровня **кандидат** (например `candidate_symbol_reference`), если продукт вводит двухшаговый контур **HCI → Roslyn** ([0113](0113-hci-semantic-map-orientation-layer.md)). |
| 81 | |
| 82 | **D. Структурные / не-код** (другие `graph_kind`) |
| 83 | Например для `repository_module_tree`: `submodule_parent_of`, `contains_path` — **другой словарь**, но та же ось `relation_kind` по смыслу «что означает ребро». |
| 84 | |
| 85 | ### 4. Связь с `hit_kind` (0105) |
| 86 | |
| 87 | Поле **`hit_kind`** в ответе HCI описывает **канал попадания** в индексе (`text_fts`, `text_vector`, …), а **не** обязательно отношение между двумя узлами графа. Маппинг «hit → ребро с `relation_kind`» — отдельный слой (CCU / композитор), где **`relation_kind`** выбирается осознанно (часто группа C), а не копируется из `hit_kind`. |
| 88 | |
| 89 | ### 5. Последствия для контракта |
| 90 | |
| 91 | - В wire-моделях subgraph / MCP, когда передаётся ребро или логическая связь, **рекомендуется** явное поле **`relation_kind`** (или вложенный объект «семантика связи»), если смысл не выводится однозначно из `graph_kind` + доменных типов узлов. |
| 92 | - Агентские подсказки и «следующий шаг» (go-to-def, usages) должны учитывать **`relation_kind`**: для `textual_name_match` — иной дефолт действия, чем для `references_member` при `symbolic_roslyn`. |
| 93 | - Полный закрытый enum на все языки и домены **не** цель этого ADR — только **ось** и черновой каталог; расширение по мере сценариев. |
| 94 | |
| 95 | ### 6. Не цели (v1 документа) |
| 96 | |
| 97 | - Онтология уровня RDF/OWL для всего IDE. |
| 98 | - Замена существующих доменных полей узла там, где они уже однозначно кодируют то же отношение — дублирование не требуется, но при экспорте в MCP агенту полезна **стабильная** проекция в `relation_kind`. |
| 99 | |
| 100 | --- |
| 101 | |
| 102 | ## Связь с предыдущими правками 0113 / 0067 |
| 103 | |
| 104 | **[0113 §1a](0113-hci-semantic-map-orientation-layer.md#adr0113-axes)** — таблица трёх осей; третья строка ссылается на этот ADR. |
| 105 | **[0067](0067-graph-backed-surfaces-contract.md#adr0067-dimensions)** — в таблице измерений graph-backed surface добавлена строка **Relation kind** со ссылкой сюда. |
| 106 | |
| 107 | --- |
| 108 | |
| 109 | ## Rollout (эскиз) |
| 110 | |
| 111 | 1. Документ (этот ADR) как общий язык для ревью UI и MCP. |
| 112 | 2. Первое поле в JSON/DTO для одного инструмента (например related-files или semantic map export) с минимальным набором `relation_kind`. |
| 113 | 3. Расширение каталога и выравнивание с Roslyn API / workspace presets — итеративно. |
| 114 | |