| 1 | # ADR 0018: Каноничные XML-доки для `IdeCommands` и ProtocolDocGen |
| 2 | |
| 3 | **Статус:** Accepted (частично: ProtocolDocGen + generated summaries; полный XML на IdeCommands — по миграции) |
| 4 | **Дата:** 2026-04-05 |
| 5 | ## Связанные ADR |
| 6 | |
| 7 | | ADR | Роль | |
| 8 | |-----|------| |
| 9 | | [0013](0013-command-surface-and-discoverability.md) | единый реестр `command_id` | |
| 10 | | [0008](0008-mcp-contracts-and-testable-infrastructure.md) | контракты MCP | |
| 11 | |
| 12 | ### Вне ADR |
| 13 | |
| 14 | | Документ | Роль | |
| 15 | |----------|------| |
| 16 | | [ide-commands-protocol-docgen-contract.md](../dev/ide-commands-protocol-docgen-contract.md) | текущий контракт парсера | |
| 17 | |
| 18 | --- |
| 19 | ## Контекст |
| 20 | |
| 21 | Реестр команд **`IdeCommands`** (частичный класс, `Services/IdeCommands.cs` + `Services/IdeCommands.*.cs`) снабжается XML-комментариями; **`tools/CascadeIDE.ProtocolDocGen`** генерирует `IdeCommandsDoc`, `IdeCommandsArgs`, `IdeCommandsContract`, фрагмент **`MCP-PROTOCOL.md`** и прогоняет линт контракта. |
| 22 | |
| 23 | Сейчас машиночитаемые части контракта (**`returns:`**, **`args:`**, **`example:`**) вложены **в текст `<summary>`** — см. [ide-commands-protocol-docgen-contract.md](../dev/ide-commands-protocol-docgen-contract.md). Это упростило первый построчный парсер, но: |
| 24 | |
| 25 | - для **открытого репозитория и новых контрибьюторов** привычнее **стандартная** структура C# XML documentation (`<summary>`, `<param>`, `<returns>`, `<example>` / `<code>`); |
| 26 | - **IDE** и привычные инструменты ожидают человеческое описание в summary, а тип возврата и параметры — в отведённых тегах. |
| 27 | |
| 28 | ## Решение (целевое состояние) |
| 29 | |
| 30 | **Базовая идея:** опираться на **привычные** теги (`<summary>`, при необходимости `<param>` / `<returns>` для человека), а **машинный контракт** для ProtocolDocGen выражать **отдельно** — либо внутри стандартных тегов по соглашению, либо через **свои (расширенные) XML-теги**, не подменяя ими базовые. |
| 31 | |
| 32 | ### Вариант A — только стандартные теги + соглашения |
| 33 | |
| 34 | 1. **`<summary>`** — краткое описание для человека; машинные части при необходимости в **`<returns>`** и **`<param>`** по явным правилам (см. ниже вариант B для смешения). |
| 35 | |
| 36 | 2. **`<param name="…">`** — человекочитаемое описание; для схемы `IdeCommandsArgs` — **соглашение** (первая строка — мини-грамматика `name:type`, остальное — текст) **или** одна строка схемы в **`<remarks>`**. |
| 37 | |
| 38 | 3. **`<example>`** + **`<code language="json">`** — пример для линта. |
| 39 | |
| 40 | ### Вариант B — стандартные теги + **свои** теги (предпочтительно обсуждать) |
| 41 | |
| 42 | Не «ломать» семантику стандартных тегов жёсткой машинной строкой, а **добавить** элементы с **фиксированными именами** под Cascade/ProtocolDocGen, например (имена на этапе Accepted зафиксировать в dev-доке): |
| 43 | |
| 44 | - отдельный тег для **схемы аргументов** (одна строка в прежней грамматике или структурированный XML внутри); |
| 45 | - отдельный тег для **вида возврата** контракта (`json` / `text` / `none`); |
| 46 | - при необходимости отдельный тег для **примера JSON** (если не хочется дублировать логику с `<example>`). |
| 47 | |
| 48 | **Почему это естественно:** компилятор C# **сохраняет** нестандартные теги в выходном XML документации; **IDE** по умолчанию показывает в Quick Info в основном `<summary>` / `<param>` / `<returns>` — кастомные теги не «ломают» подсказки, а **ProtocolDocGen** читает полный блок и извлекает и стандартные, и свои элементы. Так делают многие **SDK и генераторы доков** (Sandcastle/DocFX — свои теги; у проекта — свой контролируемый набор). |
| 49 | |
| 50 | **Имена тегов:** лучше **стабильный префикс** или неймспейсоподобная схема (`cascadeArgs`, `cascadeReturns` — или одно согласованное имя блока), чтобы не пересечься с будущими расширениями инструментов. |
| 51 | |
| 52 | ### Общее для обоих вариантов |
| 53 | |
| 54 | 4. **Реализация парсера:** разбор **XML-документа к символу** (предпочтительно **Roslyn** + полный XML комментария к `const`); склейка `IdeCommands*.cs` как сейчас. |
| 55 | |
| 56 | 5. **Миграция:** перевести `IdeCommands.*.cs` на выбранный шаблон; при необходимости короткая **совместимость** линта со старым форматом в `<summary>` или один крупный коммит. |
| 57 | |
| 58 | ### Выбор A vs B |
| 59 | |
| 60 | Оставить на финализацию ADR: если **B** — меньше компромиссов в формулировках стандартных тегов и яснее граница «человек / машина»; цена — **документировать список кастомных тегов** и один раз встроить их в парсер. |
| 61 | |
| 62 | ## Последствия |
| 63 | |
| 64 | - **Плюсы:** ближе к экосистеме C#, проще onboarding; **вариант B** дополнительно отделяет «прозу для людей» от «полей для генератора» без наслоения грамматики на `<summary>`. |
| 65 | - **Минусы:** разовая **стоимость** рефакторинга парсера и комментариев; для **A** — жёсткое соглашение по тексту внутри `<param>` / `remarks`; для **B** — **каталог кастомных тегов** и поддержка в ProtocolDocGen (зато контракт явный). |
| 66 | - **Документация:** обновить [ide-commands-protocol-docgen-contract.md](../dev/ide-commands-protocol-docgen-contract.md) после принятия реализации (или в том же PR, что и парсер). |
| 67 | |
| 68 | ## Отклонённые альтернативы |
| 69 | |
| 70 | - **Оставить навсегда только мини-язык в `<summary>`** — отклонено как долгосрочная цель для открытого репозитория: работает, но хуже для контрибьюторов и стандартных ожиданий. |
| 71 | |
| 72 | ## Статус |
| 73 | |
| 74 | До перехода на **Accepted** — после выбора **варианта A или B**, точных имён тегов (в т.ч. кастомных), соглашения по args и реализации парсера (и по желанию пилот на одном файле `IdeCommands.*.cs`). |
| 75 | |