| 1 | # ADR 0039: Навигация по workspace — несколько представлений и «текущий файл + связанные» |
| 2 | |
| 3 | **Статус:** Accepted · Implemented |
| 4 | **Дата:** 2026-04-16 |
| 5 | **Обновлено:** 2026-04-16 — [область языков](#adr0039-language-scope); [«Продуктовая метафора»](#adr0039-product-metaphor). Подробности — [§ История](#adr0039-history). |
| 6 | **Реализация (MCP-слой):** зафиксирована в коде (2026-04): пресеты в `settings.toml`, эхо фильтра, семантика subgraph; см. [§ Agent/MCP](#adr0039-mcp-workspace-navigation). Полноценная Semantic Map в UI и `ILayoutEngine` — вне этого статуса. |
| 7 | |
| 8 | ## Связанные ADR |
| 9 | |
| 10 | | ADR | Роль | |
| 11 | |-----|------| |
| 12 | | [0021](0021-pfd-mfd-cockpit-attention-model.md) | PFD, якорь «где я» | |
| 13 | | [0037](0037-pfd-surface-invariants-and-roslyn-enforcement.md) | Навигация ≠ строгая PFD-поверхность | |
| 14 | | [0010](0010-ui-modes-toml-configuration.md) | Пресеты UI | |
| 15 | | [0030](0030-command-ids-hotkeys-and-ui-registry-layers.md) | Команды, палитра | |
| 16 | | [0017](0017-multi-window-workspace-and-agent-surfaces.md) | `presentation`, размещение поверхностей | |
| 17 | | [0058](0058-agent-roslyn-mcp-coupling-settings-toml.md) | Агент ↔ Roslyn MCP в `settings.toml` | |
| 18 | | [0059](0059-roslyn-mcp-profiles-manager-tactical-strategic-efb.md) | Профили Roslyn, Manager, EFB | |
| 19 | | [0065](0065-instrument-categories-domain-taxonomy.md) | `graph_kind`, карта намерений | |
| 20 | | [0067](0067-graph-backed-surfaces-contract.md) | Контракт graph-backed поверхностей | |
| 21 | |
| 22 | ### Снимок реализации |
| 23 | |
| 24 | | Элемент | Значение | |
| 25 | |---------|----------| |
| 26 | | — | MCP `get_code_navigation_context`, пресеты и фильтры в `settings.toml` | |
| 27 | | — | полноценный UI Semantic Map / `ILayoutEngine` — по плану, см. текст ADR | |
| 28 | |
| 29 | ## Резюме |
| 30 | |
| 31 | - Навигация **C# / .NET first**: Roslyn и solution — north-star, не «IDE на все языки». |
| 32 | - Несколько представлений workspace + режим **«вокруг активного документа»** вместо одного дерева. |
| 33 | - MCP-слой (пресеты, subgraph, `get_code_navigation_context`) — **implemented**; полный UI Semantic Map — roadmap. |
| 34 | - Ортогонально строгой PFD-поверхности ([0037](0037-pfd-surface-invariants-and-roslyn-enforcement.md)). |
| 35 | |
| 36 | --- |
| 37 | ## Контекст |
| 38 | |
| 39 | Классическое **дерево файлов** (обозреватель решения) в основном **изоморфно** структуре проекта на диске. На **крупных** репозиториях глубокая иерархия даёт высокий **когнитивный налог**: держать в голове путь, многократно раскрывать узлы, промахиваться мимо нужной ветки. При этом разработчик часто думает не «путь в дереве», а **сущностями**: текущий символ, соседний файл по смыслу, тест к классу, граница слоя. |
| 40 | |
| 41 | Cascade IDE позиционируется как **agent-first** кокпит с явной моделью внимания ([0021](0021-pfd-mfd-cockpit-attention-model.md)); **не** обязана копировать паттерн «одно дерево — единственная навигация» из классических IDE. Напротив: предложить **несколько согласованных представлений** workspace и режим **«вокруг активного документа»** — осознанный продуктовый дифференциатор. |
| 42 | |
| 43 | <a id="adr0039-language-scope"></a> |
| 44 | |
| 45 | ### Область языков (north-star) |
| 46 | |
| 47 | **Цель ближайших итераций — C# / экосистема .NET**, а не «IDE на все языки мира». Глубина семантики навигации («связанные» файлы, символы, граф) в первую очередь опирается на **Roslyn** и рабочий цикл `.sln` / проектов. UI самой IDE на **Avalonia**; в продуктовом контуре могут быть сценарии **Blazor** и иной .NET-стек — без обязательства **паритета языковых сервисов** с VS/Rider для Python, Java, Go и т.д. |
| 48 | |
| 49 | После открытия продукта **дополнительные языки** (редактор, LSP, навигация) возможны и не запрещены — но это **не северная звезда** и не критерий успеха v1. Формулировки в этом ADR про «универсальный» вид или «языки без семантики» читаются в свете **C#-first**: универсальность **не** является обязательством команды на этапе зрелости кокпита и агента. |
| 50 | |
| 51 | <a id="adr0039-product-metaphor"></a> |
| 52 | |
| 53 | ### Продуктовая метафора и целевое направление (обсуждение) |
| 54 | |
| 55 | **«Шкаф vs карта боя»:** классическое дерево проекта ближе к **архивному шкафу** (физический адрес на диске), чем к **карте текущего боя**. В голове у разработчика часто живут **логические связи** («сервис — контракт — тесты»), а не путь `src/domain/...`. На больших решениях обозреватель превращается в **длинный скролл** и поиск «иголки в стоге сена» — это аргумент за **альтернативные первичные** представления, а не за отказ от дерева навсегда. |
| 56 | |
| 57 | **Граф связей и situational awareness:** целевой образ — **динамический граф релевантного контекста** вокруг активного файла или задачи: узел «где я» и **лучи** к местам, которые работа затрагивает (зависимости, контракты, тесты, схема данных). В терминах кокпита это ближе к **ситуационной осведомлённости** ([0021](0021-pfd-mfd-cockpit-attention-model.md): устойчивый контур внимания), чем к статичной картинке каталога папок. Полная реализация графа всего решения остаётся вне обязательного scope v1 (см. раздел **Не цели** ниже). |
| 58 | |
| 59 | **Agent-first и «дерево от цели»:** человек и агент в типичном сценарии мыслят **зависимостями и задачей**, а не вложенностью каталогов. Навигация «**от цели / от активного узла**», а не «от корня диска», выравнивает UX с тем, как уже ведут себя инструменты вроде Cursor — при сохранении честной работы с файлами на диске под капотом. |
| 60 | |
| 61 | **PFD vs MFD для вида «шкаф»:** допустима политика: **живой контекст** (связанные узлы, граф, семантическая карта) — в **зоне первичного внимания** ([0021](0021-pfd-mfd-cockpit-attention-model.md) — регион PFD), а **классическое дерево файлов** оставить как **вторичный** инструмент (перемещение файлов, редкий обзор структуры) — в **MFD** или эквиваленте вторичного контура ([0021](0021-pfd-mfd-cockpit-attention-model.md) — MFD). Точное размещение — пресет ([0010](0010-ui-modes-toml-configuration.md)); принцип: **не конкурировать** за один якорь внимания двумя несовместимыми ментальными моделями без явного переключения режима. |
| 62 | |
| 63 | **Semantic Map и размещение:** целевой UX-образ — **семантическая карта** (узлы уровня «Payment Logic», «DB Schema», «API Endpoint» со связями), а не обязательно строка пути `src/.../payment.cs`. **Топология зон** кокпита (где на экранах сидят PFD / Forward / MFD) задаётся строкой **`presentation`** и **`[presentation_grammar]`** — по [EBNF в 0017](0017-multi-window-workspace-and-agent-surfaces.md#adr0017-presentation-ebnf) в ней **только** три якоря зон, **без** отдельного литерала «window». После разбора топология **может** привести ко **второму `TopLevel`** (например **`MfdHostWindow`** на другом дисплее) — это **следствие** якорей и числа экранов ([0017](0017-multi-window-workspace-and-agent-surfaces.md), в т.ч. [п. 8](0017-multi-window-workspace-and-agent-surfaces.md#adr0017-p8-mfd-host-wide)), а не «магический токен в строке». Окна вроде **настроек** и элементы **плавающего хрома** — по **другим** правилам ([0012](0012-floating-workspace-chrome.md), код, [0028](0028-user-settings-toml-localappdata-and-secrets.md)). Пресеты — [0010](0010-ui-modes-toml-configuration.md), [0021](0021-pfd-mfd-cockpit-attention-model.md). Детали полей Semantic Map — вне этого ADR. |
| 64 | |
| 65 | <a id="adr0039-presentation-vs-toplevel"></a> |
| 66 | |
| 67 | *(Сводка: **`presentation` задаёт якоря и экраны** → из этого **вытекает**, будет ли второй `TopLevel` под MFD. **Не** вытекает из неё произвольное «окно настроек» — там нет такого токена в EBNF.)* |
| 68 | |
| 69 | ## Решение (принципы) |
| 70 | |
| 71 | <a id="adr0039-p1"></a> |
| 72 | |
| 73 | ### 1. Дерево файлов — не единственный канон |
| 74 | |
| 75 | **Правило:** продукт **поддерживает** классический обозреватель решения как знакомый и полезный режим (обзор структуры репозитория, операции с файлами там, где уместно), но **не** закрепляет его как **единственный** способ ответить на вопрос «где я и что рядом со мной в работе». |
| 76 | |
| 77 | **Дополняющие** формы навигации (направления реализации; не обязательно всё в одной версии): |
| 78 | |
| 79 | - **«Текущий файл и связанные»** — соседи по папке или namespace, partial-классы, пары код/тест по соглашению, недавние документы в том же срезе задачи; |
| 80 | - навигация по **символам** (типы, члены) и **outline** активного документа; |
| 81 | - **несколько представлений** в одном регионе: вкладки или split (дерево | связанные | символы) с **синхронизацией** выбора с активным документом. |
| 82 | |
| 83 | <a id="adr0039-p2"></a> |
| 84 | |
| 85 | ### 2. Связь с зоной PFD и [0037](0037-pfd-surface-invariants-and-roslyn-enforcement.md) |
| 86 | |
| 87 | Навигационные панели в регионе **PFD** по-прежнему выполняют роль якоря «где я в работе» ([0021](0021-pfd-mfd-cockpit-attention-model.md); [0037 — глоссарий](0037-pfd-surface-invariants-and-roslyn-enforcement.md#adr0037-glossary-pfd-dual)). Они **не** обязаны быть помечены как **строгая PFD-поверхность**: интерактив (клики, раскрытие узлов) остаётся допустимым. Новые виды навигации **не** ослабляют инварианты **приборов** (EICAS, компактное здоровье workspace, статус агента и т.д.), явно помеченных контрактом [0037](0037-pfd-surface-invariants-and-roslyn-enforcement.md). |
| 88 | |
| 89 | <a id="adr0039-p3"></a> |
| 90 | |
| 91 | ### 3. Пресеты, размещение и канон раскладки (зафиксировано) |
| 92 | |
| 93 | <a id="adr0039-layout-canon"></a> |
| 94 | |
| 95 | **Канон варианта раскладки:** **`(PFD)(Forward)(MFD)`** — три региона в **одной** оболочке главного окна: зона первичного внимания (**PFD**), основная рабочая область (**Forward** — редактор, документ), вторичный контур (**MFD**). Порядок слева направо (или эквивалент в вертикальном пресете) задаёт **предсказуемый scan pattern** — устойчивый путь взгляда и руки по кокпиту ([0021](0021-pfd-mfd-cockpit-attention-model.md)). |
| 96 | |
| 97 | **Окна и внимание (продуктовый дефолт, не запрет ОС):** для **навигации по workspace** и смежных **основных** панелей работы **предпочтительно** держать их в регионах **той же** оболочки `(PFD)(Forward)(MFD)`: так сохраняется **scan pattern** — один непрерывный контур «прибор — работа — вторичка». Отдельные **top-level** окна для этого контура **легко разрывают** этот путь взгляда и моторики. |
| 98 | |
| 99 | **Строка `presentation` и `TopLevel`:** в **тексте** строки **нет** токена «window» — только якоря **PFD / Forward / MFD** ([0017 § EBNF](0017-multi-window-workspace-and-agent-surfaces.md#adr0017-presentation-ebnf)). Но **результат разбора** (несколько экранов, MFD на втором) **может** включать открытие **`MfdHostWindow`** — второго `TopLevel` под полным MFD ([0017 п. 8](0017-multi-window-workspace-and-agent-surfaces.md#adr0017-p8-mfd-host-wide)); это **не противоречит** «топология из `presentation`», это её **интерпретация** вместе с мониторами. **Окно настроек**, **плавающий хром** и прочие окна **вне** этой семантики — по коду и [0012](0012-floating-workspace-chrome.md), [0028](0028-user-settings-toml-localappdata-and-secrets.md), [0010](0010-ui-modes-toml-configuration.md). Канон `(PFD)(Forward)(MFD)` в **одном** главном окне остаётся дефолтом для scan pattern; см. также [сводку выше](#adr0039-presentation-vs-toplevel). |
| 100 | |
| 101 | **Мульти-монитор:** предпочтительно **расширять** ту же логическую схему (например перенос целого региона на второй дисплей как **один** связанный фрагмент оболочки), а не плодить **дублирующие** плавающие окна навигации «на втором экране» без жёсткой связи с основным scan path. Детали — пресеты ([0010](0010-ui-modes-toml-configuration.md), [0017](0017-multi-window-workspace-and-agent-surfaces.md)); этот ADR фиксирует **принцип**, не пиксель-в-пиксель. |
| 102 | |
| 103 | Набор и плотность инструментов **внутри** PFD/MFD по-прежнему может зависеть от режима UI / пресета. |
| 104 | |
| 105 | <a id="adr0039-semantic-map-layout"></a> |
| 106 | |
| 107 | ### 4. Semantic Map — стратегия v1 и абстракция укладки (зафиксировано) |
| 108 | |
| 109 | **Гибридная поставка (v1):** |
| 110 | |
| 111 | - Базовый режим — **список «связанные»** (и при необходимости outline) — без обязательного графа. |
| 112 | - **Мини-карта** — граф **ограниченного** подграфа (**капы** = верхние границы по **числу узлов и рёбер**, плюс операционные лимиты вроде таймаута укладки; см. [Не цели](#adr0039-non-goals), [закрыто: определение капов](#adr0039-closed-questions), [открыто: конкретные числа](#adr0039-open-questions) п.3). Смысл — не перегружать внимание в PFD; при проектировании конкретных N уместен ориентир **7±2** одновременно **обозримых** сущностей (Miller), понимая что инженерный порог может быть выше за счёт кластеризации/свёртки. При превышении — **деградация** к списку, а не «ломать» PFD. |
| 113 | - Укладка для мини-карты: на первых итерациях допустим **простой встроенный layout** (например иерархический/силовой на C#) **или** внешний движок (в т.ч. обсуждаемый вариант **Skia + GraphViz**: GraphViz для раскладки, Skia/Avalonia для отрисовки и взаимодействия) — выбор **за реализацией** `ILayoutEngine`, не за UI. |
| 114 | |
| 115 | **Абстракция `ILayoutEngine` (имя — каноническое для кода; в тексте ADR — «движок укладки»):** |
| 116 | |
| 117 | - Вход: нейтральное описание графа (узлы, рёбра, метаданные для подписей). |
| 118 | - Выход: позиции узлов и геометрия рёбер (или эквивалент для рендерера), либо отказ с причиной (таймаут, слишком большой граф). |
| 119 | - **Несколько реализаций** (простая managed-укладка, GraphViz, при необходимости MSAGL и др.) — **взаимозаменяемы** без переписывания панели навигации; сравнение подходов — по мере опыта, не блокер v1. |
| 120 | |
| 121 | **Операционные ограничения:** таймаут на укладку, явный кап по размеру графа, предсказуемый fallback — **обязательны** в контракте использования движка. |
| 122 | |
| 123 | ## Последствия |
| 124 | |
| 125 | - Появляется явное **разрешение** проектировать навигацию как **набор режимов ответа на «где я»**, а не только как копию дерева файлов из других IDE; канон **`(PFD)(Forward)(MFD)`** и **scan pattern** — дефолт для кокпита; связка **`presentation` → топология → возможный `MfdHostWindow`** и окна **вне** EBNF — [§3](#adr0039-layout-canon), [сводка](#adr0039-presentation-vs-toplevel), [0017](0017-multi-window-workspace-and-agent-surfaces.md). |
| 126 | - **MCP:** агент может опираться на **`get_code_navigation_context`** с пресетами, эхом фильтра и явной семантикой рёбер в `subgraph` — см. [§ Agent/MCP](#adr0039-mcp-workspace-navigation); это снижает риск «списка файлов без смысла» в сценариях [0042](0042-pre-flight-planned-changes-and-review-before-apply.md), не заменяя UI-карту. |
| 127 | - Реализация потребует: модель **связанных файлов** (эвристики, соглашения, при наличии — семантика Roslyn для C#), UX **синхронизации** между представлениями, команды переключения вида ([0030](0030-command-ids-hotkeys-and-ui-registry-layers.md)); для Semantic Map — **движок укладки** за абстракцией `ILayoutEngine` и общий контракт рендера (например Skia), см. [§4](#adr0039-semantic-map-layout); **источник истины графа** и слой TOML — [зафиксированы](#adr0039-semantic-map-data-layer). |
| 128 | - Онбординг и discoverability ([0027](0027-small-team-focus-vs-public-maturity.md)) могут объяснять пользователю **зачем** несколько видов навигации, а не один. |
| 129 | - Метафора **PFD = карта боя / живой контекст**, **MFD = шкаф по необходимости** задаёт язык для пресетов и маркетинга; реализация по шагам, без обязательства «убрать дерево» в первом релизе. |
| 130 | |
| 131 | <a id="adr0039-non-goals"></a> |
| 132 | |
| 133 | ## Не цели |
| 134 | |
| 135 | - Полный **граф зависимостей** всего решения как обязательный экран первой версии. |
| 136 | - Замена **поиска по файлам**, **Go to symbol** и **палитры команд** — ортогональны этому ADR. |
| 137 | - **Паритет навигации и языковых сервисов для всех языков**, как у «полного» polyglot IDE: north-star остаётся **C# / .NET** ([область языков](#adr0039-language-scope)); отдельные языки позже — по продуктовой очереди, не как условие успеха v1. |
| 138 | |
| 139 | <a id="adr0039-semantic-map-abstraction-layers"></a> |
| 140 | |
| 141 | ### Semantic Map: уровень абстракции узлов (слои конфигурации) |
| 142 | |
| 143 | **Переключатель** в UI — это **режим представления** панели Semantic Map (аналог «масштаба слоя» карты): он задаёт, *что считается узлом* и как строится граф. Это не обязано дублироваться командной политикой в репозитории. |
| 144 | |
| 145 | **Дефолты и память** — не то же самое, что мгновенный режим «сейчас»: |
| 146 | |
| 147 | - **`settings.toml`** ([0028](0028-user-settings-toml-localappdata-and-secrets.md)) — **личный дефолт** уровня абстракции на этой машине (для всех workspace, если нет командного override). |
| 148 | - **`<repo>/.cascade/workspace.toml`** (merge с бандлом, [0010](0010-ui-modes-toml-configuration.md)) — **опционально**: командное соглашение для этого репо («здесь карту ведём в типах / в фичах»). |
| 149 | - **Сессионное состояние** (и при договорённости — путь как у прочей «памяти» UI по workspace, см. [0017](0017-multi-window-workspace-and-agent-surfaces.md), [0028](0028-user-settings-toml-localappdata-and-secrets.md)) — **последний выбор** на переключателе в UI; **не коммитится**. |
| 150 | |
| 151 | **Приоритет при открытии workspace:** merge `workspace.toml` (команда) → `settings.toml` (личный дефолт) → встроенный дефолт продукта. |
| 152 | |
| 153 | Что именно за **численные капы** (пороги по **числу узлов/рёбер**, плюс таймаут укладки) и **принцип** деградации в список — [закрыты](#adr0039-closed-questions); **конкретные значения N** — [открытый вопрос](#adr0039-open-questions) п.3. Ориентир для «сразу обозримого» подграфа в PFD — порядок **7±2** сущностей (Miller), без фиксации как единственного закона. |
| 154 | |
| 155 | <a id="adr0039-semantic-map-data-layer"></a> |
| 156 | |
| 157 | ### Semantic Map: источник истины и слой конфигурации (зафиксировано) |
| 158 | |
| 159 | **Позиция:** для **C#** структура графа «что с чем связано в коде» — **источник истины в runtime**: **Roslyn + решение** (и эвристики поверх), а не обязательное дублирование узлов и рёбер в TOML — иначе рассинхрон с репозиторием. |
| 160 | |
| 161 | **Пресеты и** `<repo>/.cascade/workspace.toml` **(merge с бандлом,** [0010](0010-ui-modes-toml-configuration.md)**)** — про **раскладку и режимы UI**, не про обязательное ручное перечисление узлов Semantic Map. Строка **`presentation`** ([0017](0017-multi-window-workspace-and-agent-surfaces.md#adr0017-presentation-ebnf)) **не** расширяется семантикой карты. |
| 162 | |
| 163 | **Опционально позже:** закоммиченные **аннотации** (подписи фич, ручные кластеры, то, что из кода не вывести или что команда хочет зафиксировать для агента/онбординга) — **отдельная** секция или файл под `.cascade/`, если появится продуктовая потребность; **v1** может обходиться без этого слоя. |
| 164 | |
| 165 | **Кэш** индекса или подграфа в **`%LocalAppData%`** ([0028](0028-user-settings-toml-localappdata-and-secrets.md)) — **производительность и объём**, не договорённость с командой в Git; сброс без потери истины. |
| 166 | |
| 167 | <a id="adr0039-mcp-workspace-navigation"></a> |
| 168 | |
| 169 | ### Agent/MCP — реализованный контракт (Pareto-слой) |
| 170 | |
| 171 | IDE-команда **`get_code_navigation_context`** (`ide_execute_command`) — режимы **`related`** (список связанных файлов с кратким обоснованием) и **`subgraph`** (узлы и рёбра с численными капами `max_nodes` / `max_edges` и `max_related` для списка). Якорь — активный документ в редакторе или явный **`file_path`**. Источник файлов — дерево загруженного решения; семантика связей — эвристики C# / partial / XAML / тесты / namespace / каталог ([0028](0028-user-settings-toml-localappdata-and-secrets.md) не про граф в TOML, но про канал пользовательских настроек). |
| 172 | |
| 173 | **Базовые пресеты** — один источник в репо (**`CodeNavigation/presets.toml`**): файл копируется рядом с exe (как `UiModes/`, `Hotkeys/`); при отсутствии файла на диске тот же текст подхватывается из **встроенного ресурса** сборки (без дублирующего литерала в коде). Содержимое по умолчанию: `peers_only`, `no_namespace_noise`, `tests_and_peers`, `structure_only`. |
| 174 | |
| 175 | **Репозиторий (команда)** — в **`.cascade/workspace.toml`** в корне открытого решения, секция **`[code_navigation]`** и **`[[code_navigation.presets]]`** (тот же формат, что в `settings.toml`). Merge по **`id`** поверх бандла IDE; приоритет ниже пользовательского слоя (см. ниже). Согласовано с паттерном overlay метрик UI из [0021](0021-pfd-mfd-cockpit-attention-model.md) (`UiWorkspaceToml` + репо). Подписи ветвей IF на control-flow — **`[[code_navigation_map.condition_branch.presets]]`** в том же файле ([0053](0053-semantic-map-control-flow-pfd.md)); порядок слоёв: бандл → репо → settings. |
| 176 | |
| 177 | **Пользовательский overlay** — в **`%LocalAppData%\CascadeIDE\settings.toml`**, **`[[code_navigation.presets]]`**: у каждой таблицы **`id`**, опционально **`include_kinds`** / **`exclude_kinds`**. Запись с тем же **`id`** перекрывает и бандл, и репо. Итоговый порядок: **бандл → `.cascade/workspace.toml` → `settings.toml`**. |
| 178 | |
| 179 | **Аргументы MCP:** помимо режима и путей, поддерживаются **`preset`** (имя из объединённого набора пресетов), **`include_kinds`**, **`exclude_kinds`**. Правило merge: непустой **`include_kinds`** в запросе **заменяет** include пресета; **`exclude_kinds`** из запроса **объединяется** с exclude пресета (дедупликация по каноническому имени вида). Неизвестный пресет или ошибка в данных пресетов → ответ с **`error`: `bad_preset`**. |
| 180 | |
| 181 | **Канон имён видов связей** (стабильный контракт для агента): `partial_peer`, `project_peer`, `xaml_codebehind_pair`, `test_counterpart`, `same_namespace`, `same_directory`. Неизвестные токены в списках игнорируются; пустой белый список после нормализации трактуется как «без ограничения по include» (см. реализацию фильтра). |
| 182 | |
| 183 | **Эхо фильтра в JSON:** в ответах обоих режимов присутствует объект **`kind_filter`**: **`preset`** (запрошенное имя или `null`), **`include_kinds_effective`**, **`exclude_kinds_effective`** — канонические списки после merge, чтобы агент видел эффективный фильтр без повторного чтения настроек. |
| 184 | |
| 185 | **Режим `subgraph`:** узел несёт семантический **`kind`** — вид связи с якорем (не обобщённое «related»). Ребро несёт **`related_kind`** для пары узлов. Так агент различает, например, соседа по проекту и совпадение по namespace. |
| 186 | |
| 187 | Канон вызова и таблица аргументов — **`docs/MCP-PROTOCOL.md`**; пошаговые сценарии для агентов — **[workspace-navigation-mcp-cookbook.md](../design/workspace-navigation-mcp-cookbook.md)**. |
| 188 | |
| 189 | Этот слой **не** заменяет полноценную Semantic Map в UI и **не** фиксирует выбор `ILayoutEngine`; он даёт агенту предсказуемый JSON поверх текущих эвристик. |
| 190 | |
| 191 | <a id="adr0039-closed-questions"></a> |
| 192 | |
| 193 | ## Закрытые вопросы (сняты с повестки открытых) |
| 194 | |
| 195 | Ранее стояли в списке «открытых»; решение перенесено в тело ADR или во внешние ADR. |
| 196 | |
| 197 | 1. **PFD vs MFD / второе окно / `presentation` vs `window`.** Закрыто: канон **`(PFD)(Forward)(MFD)`** и scan pattern для кокпитной навигации; в строке `presentation` **нет** токена `window`, но **`MfdHostWindow`** может **следовать** из топологии и мониторов ([0017](0017-multi-window-workspace-and-agent-surfaces.md)). См. [§3](#adr0039-layout-canon), [сводку](#adr0039-presentation-vs-toplevel). |
| 198 | |
| 199 | 2. **Semantic Map: переключатель уровня абстракции узлов** (файл / тип / «фича») **и где хранить дефолты** (`settings.toml` vs `workspace.toml` vs сессия). Закрыто: переключатель — **режим представления** панели; дефолты и приоритет merge — в [Semantic Map: уровень абстракции узлов](#adr0039-semantic-map-abstraction-layers). *(Какие уровни абстракции войдут в **первую поставку** — остаётся частью [открытого п.1](#adr0039-open-questions), если не уточнено отдельно.)* |
| 200 | |
| 201 | 3. **Semantic Map: что такое «численные капы»** и ориентир **7±2** (Miller). Закрыто как **определение и эвристика**: капы — отсечки по числу узлов/рёбер (и смежные лимиты: таймаут укладки, возможно глубина обхода); выше порога — деградация в список или иной fallback; 7±2 — ориентир обозримости, не жёсткое N в коде. См. [§4](#adr0039-semantic-map-layout). **Конкретные численные значения по умолчанию** — не закрыты, см. [открытый п.3](#adr0039-open-questions). |
| 202 | |
| 203 | 4. **Semantic Map: данные vs пресеты vs `presentation` — где «узлы» (слой конфигурации, не СУБД).** Закрыто: **Roslyn-first** истина в runtime; пресеты / `workspace.toml` — не обязательное хранилище графа; опционально позже — аннотации в `.cascade/`; кэш в `%LocalAppData%` — производительность. См. [Semantic Map: источник истины и слой конфигурации](#adr0039-semantic-map-data-layer). |
| 204 | |
| 205 | 5. **MCP `get_code_navigation_context`: стабильные имена видов связей, пресеты, предсказуемый ответ.** Закрыто для **контракта агента**: канон строковых видов (`partial_peer`, …), базовые пресеты в шипнутом **`CodeNavigation/presets.toml`**, overlay — **`[[code_navigation.presets]]`** в `settings.toml` ([0028](0028-user-settings-toml-localappdata-and-secrets.md)), merge по **`id`** с бандлом и merge аргументов вызова с пресетом, эхо **`kind_filter`**, в **`subgraph`** — **`kind`** на узлах и **`related_kind`** на рёбрах. См. [§ Agent/MCP](#adr0039-mcp-workspace-navigation). Углубление эвристик и новые виды связей — итерации продукта, не ломая канон без мажорной версии контракта. |
| 206 | |
| 207 | <a id="adr0039-open-questions"></a> |
| 208 | |
| 209 | ## Открытые вопросы |
| 210 | |
| 211 | 1. Минимальный набор представлений для **первой** поставки навигации в Cascade (в рамках **C#-first**). *(Частично направлено [гибридом v1 в §4](#adr0039-semantic-map-layout): список «связанные» + опциональная мини-карта; финальный минимум и обязательные вкладки/режимы — TBD.)* |
| 212 | |
| 213 | 2. Канон **«связанных»** для **C#** (Roslyn): полный контракт данных и UX в панелях IDE; для **MCP** зафиксированы **имена видов связей** и ответ с эхом фильтра — см. [§ Agent/MCP](#adr0039-mcp-workspace-navigation). Расширение на другие языки — **отдельная фаза**, вне north-star. |
| 214 | |
| 215 | 3. **Semantic Map: численные значения по умолчанию** — конкретные пороги по числу **узлов** и **рёбер** в подграфе мини-карты, таймаут укладки, при необходимости глубина обхода; пороги **деградации** в список; **профилирование** на очень больших решениях. *(Принцип капов и эвристика 7±2 — [закрыты](#adr0039-closed-questions) п.3; `ILayoutEngine` — [§4](#adr0039-semantic-map-layout). Слой данных и пресеты — [закрыты](#adr0039-closed-questions) п.4.)* |
| 216 | |
| 217 | --- |
| 218 | |
| 219 | ## История изменений |
| 220 | |
| 221 | <a id="adr0039-history"></a> |
| 222 | |
| 223 | | Дата | Изменение | |
| 224 | |------|-----------| |
| 225 | | — | [Agent/MCP: `get_code_navigation_context`](#adr0039-mcp-workspace-navigation). | |
| 226 | | — | блок [открытые vs закрытые вопросы](#adr0039-open-questions); [канон `(PFD)(Forward)(MFD)`](#adr0039-layout-canon) (scan pattern; уточнение: [строка `presentation` ≠ токен `window`](#adr0039-presentation-vs-toplevel)); [Semantic Map: `ILayoutEngine`](#adr0039-semantic-map-layout). Ещё | |
| 227 | | 2026-04-11 | [Semantic Map: источник истины и слой конфигурации](#adr0039-semantic-map-data-layer) (зафиксировано). | |
| 228 | | 2026-04-13 | расширен контракт MCP: [именованные пресеты](#adr0039-mcp-workspace-navigation), [`kind_filter`](#adr0039-mcp-workspace-navigation), [subgraph: `kind` / `related_kind`](#adr0039-mcp-workspace-navigation); cookbook: [workspace-navigation-mcp-cookbook.md](../design/workspace-navigation-mcp-cookbook.md). | |
| 229 | | 2026-04-16 | [область языков](#adr0039-language-scope); [«Продуктовая метафора»](#adr0039-product-metaphor). | |
| 230 | |