Forge
markdowndeeb25a2
1<!-- English translation of adr/0018-ide-commands-canonical-xml-documentation.md. Canonical Russian: ../../adr/0018-ide-commands-canonical-xml-documentation.md -->
2
3# ADR 0018: Canonical XML docs for `IdeCommands` and ProtocolDocGen
4
5**Status:** Accepted (partially: ProtocolDocGen + generated summaries; full XML on IdeCommands - on migration)
6**Date:** 2026-04-05
7## Related ADRs
8
9| ADR | Role |
10|-----|------|
11| [0013](0013-command-surface-and-discoverability.md) | single registry `command_id` |
12| [0008](0008-mcp-contracts-and-testable-infrastructure.md) | MCP contracts |
13
14### Outside ADR
15
16| Document | Role |
17|----------|------|
18| [ide-commands-protocol-docgen-contract.md](../dev/ide-commands-protocol-docgen-contract.md) | current parser contract |
19
20---
21## Context
22
23The command registry **`IdeCommands`** (partial class, `Services/IdeCommands.cs` + `Services/IdeCommands.*.cs`) is supplied with XML comments; **`tools/CascadeIDE.ProtocolDocGen`** generates `IdeCommandsDoc`, `IdeCommandsArgs`, `IdeCommandsContract`, **`MCP-PROTOCOL.md`** fragment and lints the contract.
24
25Currently, the machine-readable parts of the contract (**`returns:`**, **`args:`**, **`example:`**) are nested **in the text `<summary>`** - see [ide-commands-protocol-docgen-contract.md](../dev/ide-commands-protocol-docgen-contract.md). This simplified the first line parser, but:
26
27- for **an open repository and new contributors** the **standard** structure of C# XML documentation (`<summary>`, `<param>`, `<returns>`, `<example>` / `<code>`) is more common;
28- **IDE** and familiar tools expect a human description in the summary, and a return type and parameters in the designated tags.
29
30## Solution (target state)
31
32**Basic idea:** rely on **familiar** tags (`<summary>`, if necessary `<param>` / `<returns>` for a person), and express the **machine contract** for ProtocolDocGen **separately** - either inside standard tags by agreement, or through **your own (extended) XML tags**, without replacing the base ones with them.
33
34### Option A - standard tags + conventions only
35
361. **`<summary>`** - brief description for the person; machine parts if necessary in **`<returns>`** and **`<param>`** by explicit rules (see option B below for mixing).
37
382. **`<param name="…">`** - human-readable description; for the `IdeCommandsArgs` scheme - **convention** (the first line is the `name:type` mini-grammar, the rest is text) **or** one line of the scheme in **`<remarks>`**.
39
403. **`<example>`** + **`<code language="json">`** - example for linting.
41
42### Option B - standard tags + **custom** tags (preferably discussed)
43
44Do not “break” the semantics of standard tags with a hard machine string, but **add** elements with **fixed names** under Cascade/ProtocolDocGen, for example (fix the names at the Accepted stage in the dev-doc):
45
46- a separate tag for **argument schema** (one line in the old grammar or structured XML inside);
47- a separate tag for the **return type** of the contract (`json` / `text` / `none`);
48- if necessary, a separate tag for **JSON example** (if you don’t want to duplicate the logic with `<example>`).
49
50**Why this is natural:** the C# compiler **preserves** non-standard tags in the output XML documentation; **IDE** by default shows in Quick Info mainly `<summary>` / `<param>` / `<returns>` - custom tags do not “break” tooltips, and **ProtocolDocGen** reads the full block and extracts both standard and custom elements. Many **SDKs and dock generators** do this (Sandcastle/DocFX have their own tags; the project has its own controlled set).
51
52**Tag names:** It is better to have a **stable prefix** or a namespace-like scheme (`cascadeArgs`, `cascadeReturns` - or one consistent block name) so as not to interfere with future tool extensions.
53
54### Common to both options
55
564. **Parser implementation:** parsing **XML document to symbol** (preferably **Roslyn** + full XML comment to `const`); gluing `IdeCommands*.cs` as it is now.
57
585. **Migration:** translate `IdeCommands.*.cs` to the selected template; if necessary, a short **compatibility** lint with the old format in `<summary>` or one major commit.
59
60### Select A vs B
61
62Leave for ADR finalization: if **B** - there are fewer compromises in the wording of standard tags and the “man/machine” boundary is clearer; price - **document the list of custom tags** and embed them into the parser once.
63
64## Consequences
65- **Pros:** closer to the C# ecosystem, easier onboarding; **option B** further separates "prose for people" from "fields for generator" without layering grammar on `<summary>`.
66- **Disadvantages:** one-time **cost** of refactoring the parser and comments; for **A** - strict convention on the text inside `<param>` / `remarks`; for **B** - **catalog of custom tags** and support in ProtocolDocGen (but the contract is explicit).
67- **Documentation:** update [ide-commands-protocol-docgen-contract.md](../dev/ide-commands-protocol-docgen-contract.md) after accepting the implementation (or in the same PR as the parser).
68
69## Rejected alternatives
70
71- **Keep only the minilanguage in `<summary>` forever** - rejected as a long-term goal for an open repository: works, but worse for contributors and standard expectations.
72
73## Status
74
75Before switching to **Accepted** - after choosing **option A or B**, exact tag names (including custom ones), agreement on args and parser implementation (and, if desired, a pilot on one file `IdeCommands.*.cs`).
View only · write via MCP/CIDE