| 1 | # Capability diagnostics |
| 2 | |
| 3 | <a href="./CAPABILITY_DIAGNOSTICS.zh-CN.md">简体中文</a> |
| 4 | · |
| 5 | <a href="./GUIDE.md">Guide</a> |
| 6 | · |
| 7 | <a href="./PLUGIN_PACKAGES.md">Plugin packages</a> |
| 8 | |
| 9 | Reasonix ships a read-only capability diagnostics model shared by the CLI and |
| 10 | desktop **Settings → Diagnostics**. It reports Skills, Commands, Hooks, plugin |
| 11 | packages, MCP servers, and instruction docs (`AGENTS.md` / `REASONIX.md` / |
| 12 | `CLAUDE.md`). |
| 13 | |
| 14 | **Write policy** |
| 15 | |
| 16 | | Mode | Config files | MCP stats / schema cache | Network / MCP processes | |
| 17 | | --- | --- | --- | --- | |
| 18 | | Static (default) + desktop | Never written (`LoadForRootReadOnly`) | Never written | None | |
| 19 | | CLI `--live` | Never written | **Not written** (`SkipPersistence`) | Starts automatic MCP in an isolated Host | |
| 20 | |
| 21 | ## How to use (quick start) |
| 22 | |
| 23 | | Goal | What to run | |
| 24 | | --- | --- | |
| 25 | | Check this workspace’s skills / hooks / MCP / plugins | `reasonix doctor capabilities` | |
| 26 | | Machine-readable report (CI / support) | `reasonix doctor capabilities --json` | |
| 27 | | Another project root | `reasonix doctor capabilities --root /path/to/project` | |
| 28 | | Probe MCP startup for real (starts third-party servers) | `reasonix doctor capabilities --live --timeout 5s` | |
| 29 | | Ask the agent to walk through config / fix guidance | `/reasonix-guide` in chat, or ask naturally | |
| 30 | | GUI health view | Desktop **Settings → Diagnostics** | |
| 31 | |
| 32 | **Default is static and safe:** no network, no MCP child processes. Use `--live` |
| 33 | only when you explicitly want to start automatic MCP servers. |
| 34 | |
| 35 | Related doctor commands: |
| 36 | |
| 37 | ```bash |
| 38 | reasonix doctor # env / providers / sandbox snapshot |
| 39 | reasonix doctor session <id> # support session bundle |
| 40 | reasonix doctor redact-sessions # redact secrets in session files |
| 41 | ``` |
| 42 | |
| 43 | ## Skill tool references |
| 44 | |
| 45 | Both `doctor` and `doctor capabilities` check `allowed-tools` on effective |
| 46 | skills using the same configured paths, exclusions, disabled names, and source |
| 47 | precedence. The inventory combines compile-time tools with host-managed tool |
| 48 | identities. `use_capability` is a known host tool even with no MCP servers; |
| 49 | there is no need to disable or override the built-in review skills. |
| 50 | |
| 51 | Recognition means the reference names a known tool, not that the tool is |
| 52 | registered, permitted, or ready in every session. Hidden tools callable through |
| 53 | the proxy are included. MCP dependency configuration remains a separate check. |
| 54 | |
| 55 | | Capability issue code | Meaning | |
| 56 | | --- | --- | |
| 57 | | `skill.tool_reference_unknown` | An ordinary name is not in the known inventory; check spelling | |
| 58 | | `skill.tool_reference_invalid` | Invalid glob syntax or an incomplete MCP reference | |
| 59 | | `skill.tool_reference_ambiguous` | Supplied MCP bindings resolve a literal to multiple tools | |
| 60 | | `skill.tool_reference_unverified` | A dynamic reference or unmatched pattern cannot be verified offline | |
| 61 | | `skill.mcp_dependency_missing` | An auto-use required skill depends on an unconfigured MCP server | |
| 62 | | `skill.mcp_dependency_failed` | The required server has an observed host failure | |
| 63 | |
| 64 | Unverified references are informational in capability diagnostics. Ordinary |
| 65 | doctor retains its warning-list format and explicitly labels these references |
| 66 | as unverified. Neither result grants tool access or proves a server is broken. |
| 67 | Static checks do not start MCP servers or call a model provider. |
| 68 | When an existing runtime host or an explicit `--live` probe supplies MCP tools, |
| 69 | capability diagnostics use that observed inventory to resolve portable aliases. |
| 70 | Alias resolution follows runtime plugin ownership: a plugin skill can use aliases |
| 71 | from its own package, while an ordinary local skill needs a concrete callable |
| 72 | name or capability ID. Diagnostics preserve the adapter's original and visible |
| 73 | names, including configured prefix stripping. |
| 74 | |
| 75 | ## Everyday workflows |
| 76 | |
| 77 | ### 1. “Skill / command is missing or wrong” |
| 78 | |
| 79 | ```bash |
| 80 | reasonix doctor capabilities --json | jq '.skills.entries, .commands.entries, .issues' |
| 81 | ``` |
| 82 | |
| 83 | Look for: |
| 84 | |
| 85 | - `skill.shadowed` / `command.shadowed` — a higher-priority path won |
| 86 | - `skill.disabled` — name is in `[skills].disabled_skills` |
| 87 | - `skill.missing_description` — skill loads but index quality is weak |
| 88 | - `command.read_failed` — unreadable or broken markdown |
| 89 | |
| 90 | Then open **Settings → Skills** (or fix the file under `.reasonix/skills` / |
| 91 | `.reasonix/commands`). |
| 92 | |
| 93 | ### 2. “Project hooks never fire” |
| 94 | |
| 95 | ```bash |
| 96 | reasonix doctor capabilities | sed -n '/Hooks/,/Plugins/p' |
| 97 | ``` |
| 98 | |
| 99 | Project hooks load automatically from `.reasonix/settings.json`. If they do not |
| 100 | fire, confirm the active workspace and restart Reasonix after saving. Matchers |
| 101 | are **anchored** regexes: `file` does not match `read_file`. |
| 102 | |
| 103 | ### 3. “MCP tools don’t show up” |
| 104 | |
| 105 | 1. Static first (no side effects): |
| 106 | |
| 107 | ```bash |
| 108 | reasonix doctor capabilities --json | jq '.mcp.servers, .issues[] | select(.subsystem=="mcp")' |
| 109 | ``` |
| 110 | |
| 111 | 2. Only if you accept starting third-party servers: |
| 112 | |
| 113 | ```bash |
| 114 | reasonix doctor capabilities --live --timeout 10s --json |
| 115 | ``` |
| 116 | |
| 117 | Common codes: `mcp.command_not_found`, `mcp.invalid_transport`, |
| 118 | `mcp.start_failed`, `mcp.no_tools`. On desktop, prefer **Settings → Diagnostics** |
| 119 | with “Include current session runtime” to read the **active tab Host** without |
| 120 | starting a second Host. |
| 121 | |
| 122 | Each MCP entry identifies the exact winning configuration with `source`, |
| 123 | `source_path`, and `effective`. Startup failures also report `startup_stage` |
| 124 | (`launch`, `authorization`, `initialize`, or `tools/list`), |
| 125 | `startup_elapsed_ms`, and a bounded, credential-redacted `stderr` tail. This |
| 126 | distinguishes duplicate/shadowed registration from a genuinely slow or broken |
| 127 | handshake without exposing full process output. |
| 128 | |
| 129 | ### 4. Ask the agent (`reasonix-guide`) |
| 130 | |
| 131 | In an interactive session: |
| 132 | |
| 133 | ```text |
| 134 | /reasonix-guide |
| 135 | ``` |
| 136 | |
| 137 | or: |
| 138 | |
| 139 | ```text |
| 140 | My MCP server X is configured but the model never sees its tools — diagnose. |
| 141 | ``` |
| 142 | |
| 143 | The built-in skill is **inline** (`runAs: inline`). It tells the model to prefer: |
| 144 | |
| 145 | ```bash |
| 146 | reasonix doctor capabilities --json |
| 147 | ``` |
| 148 | |
| 149 | and to use `--live` only after you explicitly allow external MCP. Project or |
| 150 | global skills named `reasonix-guide` override the builtin; you can also hide it |
| 151 | with `[skills].disabled_skills = ["reasonix-guide"]`. |
| 152 | |
| 153 | The guide loads a short router first. Skills, commands, hooks, MCP, plugins, |
| 154 | and instruction resolution have separate pages embedded in the binary. Read only |
| 155 | the relevant page with `read_skill`; for a tool hidden behind the capability |
| 156 | dispatcher, use: |
| 157 | |
| 158 | ```json |
| 159 | {"action":"call","capability_id":"tool:read_skill","arguments":{"name":"reasonix-guide","reference":"references/hooks.md"}} |
| 160 | ``` |
| 161 | |
| 162 | Omit `reference` to retain the existing full skill-body read. Reference reads |
| 163 | are limited to `references/*.md` in the selected embedded skill package; they |
| 164 | do not read arbitrary host paths or fall back to a builtin behind a project |
| 165 | override or disabled skill. File-backed skills continue to use their source |
| 166 | files for references. No user data format or migration changes. |
| 167 | |
| 168 | The session skills catalog shares its fixed character budget across descriptions |
| 169 | before omitting entries. If names alone exceed the budget, it lists complete |
| 170 | entries with an omitted count and a discovery hint. Omitted entries remain |
| 171 | available through `use_capability` search/inspect/call; the preview is not the |
| 172 | authoritative inventory. Skill selection uses actual task relevance rather than |
| 173 | mandatory invocation on weak keyword matches. |
| 174 | |
| 175 | ## CLI reference |
| 176 | |
| 177 | ```bash |
| 178 | reasonix doctor capabilities [--root PATH] [--json] [--live] [--timeout 5s] |
| 179 | ``` |
| 180 | |
| 181 | | Flag | Meaning | |
| 182 | | --- | --- | |
| 183 | | `--root` | Workspace root (default: current directory). Uses `config.LoadForRoot`. | |
| 184 | | `--json` | Write one JSON object to **stdout** only (warnings go to stderr). | |
| 185 | | `--live` | Start **automatic** MCP servers in an isolated Host (may network). | |
| 186 | | `--timeout` | Per-server live timeout, **1s–60s**, default `5s`. Requires `--live`. | |
| 187 | |
| 188 | ### Modes |
| 189 | |
| 190 | | Mode | Behavior | |
| 191 | | --- | --- | |
| 192 | | **Static (default)** | No network; no stdio / HTTP / SSE MCP child processes. | |
| 193 | | **Live (`--live`)** | Stderr risk banner; only servers with automatic start intent; `auto_start=false` → `skipped`; concurrency 4; Host always closed. | |
| 194 | |
| 195 | Desktop “include current session runtime” is **not** CLI `--live`: the desktop |
| 196 | only **reads** the active tab Host and never starts MCP. |
| 197 | |
| 198 | ### Exit codes |
| 199 | |
| 200 | | Code | Meaning | |
| 201 | | --- | --- | |
| 202 | | `0` | No `error`-severity issues (warnings/info are allowed) | |
| 203 | | `1` | One or more `error` issues, or live MCP start failures | |
| 204 | | `2` | Bad flags / usage | |
| 205 | |
| 206 | Examples: |
| 207 | |
| 208 | ```bash |
| 209 | # Human-readable, current directory |
| 210 | reasonix doctor capabilities |
| 211 | |
| 212 | # Fail CI only on hard errors |
| 213 | reasonix doctor capabilities --json |
| 214 | # shell: exit code 1 if summary.errors > 0 |
| 215 | |
| 216 | # Live probe with a longer timeout |
| 217 | reasonix doctor capabilities --live --timeout 15s --json 2>live-warn.txt |
| 218 | ``` |
| 219 | |
| 220 | Existing `reasonix doctor`, `doctor session`, and `doctor redact-sessions` |
| 221 | commands keep their own JSON schemas — capability fields are **not** mixed into |
| 222 | those reports. |
| 223 | |
| 224 | ## Desktop |
| 225 | |
| 226 | Open **Settings → Diagnostics**: |
| 227 | |
| 228 | | Control | Behavior | |
| 229 | | --- | --- | |
| 230 | | Open page | Loads a **static** report for the active workspace root | |
| 231 | | Refresh | Re-runs collection with the current runtime toggle | |
| 232 | | Copy redacted JSON | Clipboard paste-safe report (paths already redacted) | |
| 233 | | Include current session runtime | Merge connected / failed / deferred / disabled from the **active tab Host** only | |
| 234 | | Open settings (on an issue) | Jumps to MCP / Skills / Plugins / Hooks when `settings_tab` is set | |
| 235 | |
| 236 | The page never edits config, executes hooks, auto-enables packages, or |
| 237 | reconnects MCP. Opening Diagnostics does not rebuild the controller or snapshot |
| 238 | the session. |
| 239 | |
| 240 | ## JSON schema (version 1) |
| 241 | |
| 242 | Top-level fields: |
| 243 | |
| 244 | - `schema_version` (always `1`) |
| 245 | - `root` (display path) |
| 246 | - `live` (bool) |
| 247 | - `summary` — error/warning/info counts and resource counts |
| 248 | - `instructions`, `skills`, `commands`, `hooks`, `plugins`, `mcp` |
| 249 | - `issues[]` — ordered list of findings |
| 250 | |
| 251 | Plugin package entries are additive for Manifest v2: each package also |
| 252 | reports `prompts` and `themes` counts and a `runtime` flag when the plugin |
| 253 | declares a code runtime (see |
| 254 | <a href="./PLUGIN_PACKAGES.md">Plugin packages</a>). Older readers can ignore |
| 255 | these fields; `schema_version` stays `1`. |
| 256 | |
| 257 | Issue shape: |
| 258 | |
| 259 | ```json |
| 260 | { |
| 261 | "severity": "error|warning|info", |
| 262 | "code": "skill.shadowed", |
| 263 | "subsystem": "skills", |
| 264 | "name": "demo", |
| 265 | "source": "<workspace>/.reasonix/skills/demo/SKILL.md", |
| 266 | "message": "...", |
| 267 | "remediation": "...", |
| 268 | "settings_tab": "skills" |
| 269 | } |
| 270 | ``` |
| 271 | |
| 272 | Stable codes include: |
| 273 | |
| 274 | - `skill.shadowed`, `skill.missing_description`, `skill.disabled` |
| 275 | - `command.shadowed`, `command.read_failed` |
| 276 | - `hook.invalid_matcher`, `hook.missing_command`, `hook.malformed_settings` |
| 277 | - `plugin.missing_root`, `plugin.invalid_manifest`, `plugin.compatibility` |
| 278 | - `mcp.invalid_transport`, `mcp.command_not_found`, `mcp.missing_command`, `mcp.missing_url` |
| 279 | - `mcp.start_failed`, `mcp.no_tools`, `mcp.runtime_unavailable` |
| 280 | |
| 281 | Array and issue order is deterministic for scripting and tests. |
| 282 | |
| 283 | ### Severity |
| 284 | |
| 285 | | Severity | Meaning | CLI exit | |
| 286 | | --- | --- | --- | |
| 287 | | `error` | Broken config or failed live start | `1` | |
| 288 | | `warning` | Actionable but non-fatal (e.g. a missing hook command) | `0` | |
| 289 | | `info` | Shadowing, disabled assets, runtime unavailable | `0` | |
| 290 | |
| 291 | ## Path and secret safety |
| 292 | |
| 293 | Reports rewrite paths as: |
| 294 | |
| 295 | - `<workspace>/...` under the diagnosis root |
| 296 | - `~/...` under the user home |
| 297 | - `<external>/basename` for other absolute paths (no full external path) |
| 298 | |
| 299 | They never intentionally emit usernames, full external paths, environment |
| 300 | variable **values**, header **values**, tokens, or URL query strings. MCP |
| 301 | entries list env/header **keys** only. Error text that may carry raw HTTP |
| 302 | response bodies or MCP stderr passes through the product-wide secret redactor |
| 303 | (Authorization schemes, Bearer/JWT/vendor tokens, `KEY=value` and JSON |
| 304 | `"key":"value"` credential forms, Cookie/Set-Cookie values) and is truncated to |
| 305 | 400 characters. Prefer copying report JSON into issues or chat over pasting raw |
| 306 | config files. |
| 307 | |
| 308 | ## What is *not* diagnosed here |
| 309 | |
| 310 | | Need | Use instead | |
| 311 | | --- | --- | |
| 312 | | Provider keys, proxy, sandbox OS support | `reasonix doctor` | |
| 313 | | Full session transcript for support | `reasonix doctor session <id>` | |
| 314 | | One plugin package only | `reasonix plugin doctor <name>` | |
| 315 | | Interactive MCP list in a chat session | `/mcp` | |
| 316 | |
| 317 | ## Cache impact |
| 318 | |
| 319 | Adding the built-in `reasonix-guide` skill appends one line to the next changed |
| 320 | `session-context` Skills catalog. The skill body is loaded only on invocation. |
| 321 | Diagnostics itself is not part of the provider prompt. |
| 322 | |
| 323 | Changing the static invocation policy or tool description/schema changes the |
| 324 | prefix used by newly assembled sessions and can require cache warming. Reading |
| 325 | a guide or reference page adds a tool result without rewriting the current |
| 326 | system prefix or tool schemas. Catalog rendering is deterministic for the same |
| 327 | inventory. Prompt wording should be evaluated on the actual deployed providers; |
| 328 | deterministic integration tests do not measure model selection quality. |
| 329 |