rigortype 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +41 -14
  3. data/docs/handbook/01-getting-started.md +311 -0
  4. data/docs/handbook/02-everyday-types.md +337 -0
  5. data/docs/handbook/03-narrowing.md +359 -0
  6. data/docs/handbook/04-tuples-and-shapes.md +321 -0
  7. data/docs/handbook/05-methods-and-blocks.md +339 -0
  8. data/docs/handbook/06-classes.md +305 -0
  9. data/docs/handbook/07-rbs-and-extended.md +427 -0
  10. data/docs/handbook/08-understanding-errors.md +373 -0
  11. data/docs/handbook/09-plugins.md +241 -0
  12. data/docs/handbook/10-sorbet.md +347 -0
  13. data/docs/handbook/11-sig-gen.md +312 -0
  14. data/docs/handbook/12-lightweight-hkt.md +333 -0
  15. data/docs/handbook/README.md +275 -0
  16. data/docs/handbook/appendix-elixir.md +370 -0
  17. data/docs/handbook/appendix-go.md +399 -0
  18. data/docs/handbook/appendix-java-csharp.md +470 -0
  19. data/docs/handbook/appendix-liskov.md +580 -0
  20. data/docs/handbook/appendix-mypy.md +370 -0
  21. data/docs/handbook/appendix-phpstan.md +338 -0
  22. data/docs/handbook/appendix-protocols-and-structural-typing.md +292 -0
  23. data/docs/handbook/appendix-rust.md +446 -0
  24. data/docs/handbook/appendix-steep.md +336 -0
  25. data/docs/handbook/appendix-type-theory.md +1662 -0
  26. data/docs/handbook/appendix-typeprof.md +416 -0
  27. data/docs/handbook/appendix-typescript.md +332 -0
  28. data/docs/install.md +189 -0
  29. data/docs/llms.txt +72 -0
  30. data/docs/manual/01-installation.md +342 -0
  31. data/docs/manual/02-cli-reference.md +569 -0
  32. data/docs/manual/03-configuration.md +152 -0
  33. data/docs/manual/04-diagnostics.md +206 -0
  34. data/docs/manual/05-inspecting-types.md +109 -0
  35. data/docs/manual/06-baseline.md +104 -0
  36. data/docs/manual/07-plugins.md +92 -0
  37. data/docs/manual/08-skills.md +143 -0
  38. data/docs/manual/09-editor-integration.md +245 -0
  39. data/docs/manual/10-mcp-server.md +539 -0
  40. data/docs/manual/11-ci.md +274 -0
  41. data/docs/manual/12-caching.md +116 -0
  42. data/docs/manual/13-troubleshooting.md +120 -0
  43. data/docs/manual/14-rails-quickstart.md +332 -0
  44. data/docs/manual/15-type-protection-coverage.md +204 -0
  45. data/docs/manual/16-rbs-extended-annotations.md +190 -0
  46. data/docs/manual/17-driving-improvement.md +160 -0
  47. data/docs/manual/README.md +87 -0
  48. data/docs/manual/ci-templates/README.md +58 -0
  49. data/docs/manual/plugins/README.md +86 -0
  50. data/docs/manual/plugins/rigor-actioncable.md +78 -0
  51. data/docs/manual/plugins/rigor-actionmailer.md +74 -0
  52. data/docs/manual/plugins/rigor-actionpack.md +80 -0
  53. data/docs/manual/plugins/rigor-activejob.md +58 -0
  54. data/docs/manual/plugins/rigor-activerecord.md +102 -0
  55. data/docs/manual/plugins/rigor-activestorage.md +74 -0
  56. data/docs/manual/plugins/rigor-activesupport-core-ext.md +86 -0
  57. data/docs/manual/plugins/rigor-devise.md +70 -0
  58. data/docs/manual/plugins/rigor-dry-schema.md +56 -0
  59. data/docs/manual/plugins/rigor-dry-struct.md +60 -0
  60. data/docs/manual/plugins/rigor-dry-types.md +59 -0
  61. data/docs/manual/plugins/rigor-dry-validation.md +62 -0
  62. data/docs/manual/plugins/rigor-factorybot.md +76 -0
  63. data/docs/manual/plugins/rigor-graphql.md +89 -0
  64. data/docs/manual/plugins/rigor-hanami.md +83 -0
  65. data/docs/manual/plugins/rigor-mangrove.md +73 -0
  66. data/docs/manual/plugins/rigor-minitest.md +86 -0
  67. data/docs/manual/plugins/rigor-pundit.md +72 -0
  68. data/docs/manual/plugins/rigor-rails-i18n.md +92 -0
  69. data/docs/manual/plugins/rigor-rails-routes.md +94 -0
  70. data/docs/manual/plugins/rigor-rails.md +44 -0
  71. data/docs/manual/plugins/rigor-rbs-inline.md +83 -0
  72. data/docs/manual/plugins/rigor-rspec-rails.md +72 -0
  73. data/docs/manual/plugins/rigor-rspec.md +86 -0
  74. data/docs/manual/plugins/rigor-shoulda-matchers.md +78 -0
  75. data/docs/manual/plugins/rigor-sidekiq.md +78 -0
  76. data/docs/manual/plugins/rigor-sinatra.md +61 -0
  77. data/docs/manual/plugins/rigor-sorbet.md +63 -0
  78. data/docs/manual/plugins/rigor-statesman.md +75 -0
  79. data/docs/manual/plugins/rigor-typescript-utility-types.md +71 -0
  80. data/exe/rigor +1 -1
  81. data/lib/rigor/analysis/incremental_session.rb +4 -2
  82. data/lib/rigor/analysis/run_stats.rb +13 -1
  83. data/lib/rigor/analysis/runner.rb +54 -12
  84. data/lib/rigor/cli/check_command.rb +1 -1
  85. data/lib/rigor/cli/docs_command.rb +248 -0
  86. data/lib/rigor/cli/skill_command.rb +103 -41
  87. data/lib/rigor/cli/skill_describe.rb +346 -0
  88. data/lib/rigor/cli/triage_command.rb +8 -2
  89. data/lib/rigor/cli/triage_renderer.rb +4 -0
  90. data/lib/rigor/cli.rb +25 -3
  91. data/lib/rigor/inference/method_dispatcher/constant_folding.rb +124 -32
  92. data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +37 -6
  93. data/lib/rigor/inference/scope_indexer.rb +87 -89
  94. data/lib/rigor/plugin/isolation.rb +5 -5
  95. data/lib/rigor/plugin/loader.rb +4 -2
  96. data/lib/rigor/triage/catalogue.rb +16 -1
  97. data/lib/rigor/triage.rb +30 -7
  98. data/lib/rigor/version.rb +1 -1
  99. data/skills/rigor-ask/SKILL.md +172 -0
  100. data/skills/rigor-doctor/SKILL.md +87 -0
  101. data/skills/rigor-editor-setup/SKILL.md +114 -0
  102. data/skills/rigor-mcp-setup/SKILL.md +117 -0
  103. data/skills/rigor-monkeypatch-resolve/SKILL.md +79 -0
  104. data/skills/rigor-next-steps/SKILL.md +113 -0
  105. data/skills/rigor-plugin-tune/SKILL.md +79 -0
  106. data/skills/rigor-protection-uplift/SKILL.md +133 -0
  107. data/skills/rigor-rbs-setup/SKILL.md +128 -0
  108. data/skills/rigor-upgrade/SKILL.md +79 -0
  109. metadata +90 -1
@@ -0,0 +1,539 @@
1
+ # Rigor MCP Server — AI Agent Integration
2
+
3
+ `rigor mcp` is the Model Context Protocol (MCP) server bundled with the
4
+ `rigortype` gem. It exposes Rigor's analysis tools as JSON-RPC 2.0 tool
5
+ calls over a newline-delimited stdio stream, so AI coding assistants —
6
+ Claude Code, Cursor, Cline, VS Code Copilot Chat, and any other
7
+ MCP-aware agent — can call Rigor directly during a session.
8
+
9
+ ## MCP vs LSP — choosing the right integration
10
+
11
+ Both `rigor lsp` and `rigor mcp` expose the same underlying engine.
12
+ The difference is the consumer.
13
+
14
+ | | `rigor lsp` | `rigor mcp` |
15
+ |---|---|---|
16
+ | Protocol | Language Server Protocol | Model Context Protocol |
17
+ | Consumer | Your editor | An AI coding agent |
18
+ | Interaction | Continuous (push diagnostics on every save) | On-demand (agent calls a tool when it decides to) |
19
+ | Transport | stdio (TCP queued) | stdio (HTTP queued) |
20
+ | When to use | Editor integration | AI-assisted development |
21
+
22
+ Use `rigor lsp` to get inline diagnostics and hover in Neovim, VS Code,
23
+ Helix, or Emacs. Use `rigor mcp` to let an AI agent check types before
24
+ suggesting a refactor, look up the type at a cursor position, or triage
25
+ a project's diagnostic set as context for a code-review session.
26
+
27
+ There is no conflict in running both simultaneously.
28
+
29
+ ## Tools at a glance
30
+
31
+ | Tool | Underlying command | Returns |
32
+ |---|---|---|
33
+ | `rigor_check` | `rigor check --format json` | JSON diagnostic report |
34
+ | `rigor_type_of` | `rigor type-of --format json` | JSON type at `FILE:LINE:COL` |
35
+ | `rigor_triage` | `rigor triage --format json` | JSON distribution + class/method selectors + hotspots + hints |
36
+ | `rigor_annotate` | `rigor annotate --no-color` | Annotated Ruby source |
37
+ | `rigor_sig_gen` | `rigor sig-gen --print --format json` | JSON RBS skeleton candidates |
38
+ | `rigor_explain` | `rigor explain --format json` | JSON rule catalog entries |
39
+ | `rigor_coverage` | `rigor coverage --format json` | JSON precision-tier breakdown |
40
+
41
+ All tools are read-only. Write-side operations (`rigor init`,
42
+ `rigor baseline generate`, `rigor sig-gen --write`) are intentionally
43
+ excluded — modifying project files is the developer's call, not an
44
+ agent's tool call.
45
+
46
+ ## Prerequisites
47
+
48
+ The single prerequisite is **`rigor` on your `PATH`** — the same
49
+ executable `rigor check` and `rigor lsp` already use. Any install
50
+ channel in [Installing Rigor](01-installation.md) provides it; `mise`
51
+ is the recommended channel because its shims make `rigor` available to
52
+ processes (and AI agents) that do not inherit your shell environment.
53
+
54
+ Do **not** add `rigortype` to your project's `Gemfile`. Rigor is a
55
+ tool, not a library. See
56
+ [Installing Rigor § Recommended — a runtime version manager](01-installation.md#recommended--a-runtime-version-manager).
57
+
58
+ ## CLI
59
+
60
+ ```sh
61
+ rigor mcp [--transport=stdio] [--config=PATH]
62
+ ```
63
+
64
+ - `--transport=stdio` — default; only value accepted in v1. HTTP
65
+ transport is queued for v2.
66
+ - `--config=PATH` — session-level default config path. Individual tool
67
+ calls may supply their own `config` argument, which takes precedence.
68
+ Without either, `Configuration.discover` walks `.rigor.yml` /
69
+ `.rigor.dist.yml` from the working directory.
70
+
71
+ Exit codes: 0 (clean shutdown — stdin EOF), 64 (unknown
72
+ `--transport`).
73
+
74
+ ## Client wiring
75
+
76
+ ### Claude Desktop
77
+
78
+ Add an entry to `~/Library/Application Support/Claude/claude_desktop_config.json`
79
+ (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
80
+
81
+ ```json
82
+ {
83
+ "mcpServers": {
84
+ "rigor": {
85
+ "command": "rigor",
86
+ "args": ["mcp"]
87
+ }
88
+ }
89
+ }
90
+ ```
91
+
92
+ Restart Claude Desktop. The `rigor_check`, `rigor_type_of`, and other
93
+ tools will appear in the model's tool palette. To pin the analysis to a
94
+ specific project config:
95
+
96
+ ```json
97
+ {
98
+ "mcpServers": {
99
+ "rigor": {
100
+ "command": "rigor",
101
+ "args": ["mcp", "--config=/path/to/project/.rigor.yml"]
102
+ }
103
+ }
104
+ }
105
+ ```
106
+
107
+ ### Claude Code CLI
108
+
109
+ Claude Code reads MCP server definitions from its project-level
110
+ settings. Add to `.claude/settings.json` in your project root:
111
+
112
+ ```json
113
+ {
114
+ "mcpServers": {
115
+ "rigor": {
116
+ "command": "rigor",
117
+ "args": ["mcp"]
118
+ }
119
+ }
120
+ }
121
+ ```
122
+
123
+ Or register it globally in `~/.claude/settings.json` so it is
124
+ available in every project. Once registered, Claude Code can call
125
+ `rigor_check` on files it is about to edit, use `rigor_type_of` to
126
+ ground a suggestion, and run `rigor_triage` to understand a project's
127
+ diagnostic shape before proposing a cleanup plan.
128
+
129
+ ### Cursor
130
+
131
+ Add to `.cursor/mcp.json` (project root) or `~/.cursor/mcp.json`
132
+ (user-level):
133
+
134
+ ```json
135
+ {
136
+ "mcpServers": {
137
+ "rigor": {
138
+ "command": "rigor",
139
+ "args": ["mcp"]
140
+ }
141
+ }
142
+ }
143
+ ```
144
+
145
+ Cursor's Composer will then offer Rigor tools alongside its built-in
146
+ capabilities. `rigor_check` is especially useful before a Composer
147
+ refactor — run it first so the agent knows the current diagnostic
148
+ baseline, then compare after.
149
+
150
+ ### Cline (VS Code extension)
151
+
152
+ Open the Cline panel → MCP Servers → Add Server → Custom, and fill in:
153
+
154
+ | Field | Value |
155
+ |---|---|
156
+ | Name | `rigor` |
157
+ | Command | `rigor` |
158
+ | Args | `["mcp"]` |
159
+
160
+ Or add directly to Cline's `cline_mcp_settings.json`:
161
+
162
+ ```json
163
+ {
164
+ "mcpServers": {
165
+ "rigor": {
166
+ "command": "rigor",
167
+ "args": ["mcp"]
168
+ }
169
+ }
170
+ }
171
+ ```
172
+
173
+ ### Generic / custom MCP client
174
+
175
+ `rigor mcp` speaks the [MCP stdio transport](https://spec.modelcontextprotocol.io/specification/basic/transports/#stdio):
176
+ one JSON-RPC 2.0 message per line, `\n`-terminated, no
177
+ `Content-Length` framing. Any client that follows this convention
178
+ works. The initialization sequence:
179
+
180
+ ```
181
+ → {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"my-agent","version":"1.0"}}}
182
+ ← {"jsonrpc":"2.0","id":0,"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{"listChanged":false}},"serverInfo":{"name":"rigor","version":"0.2.1"}}}
183
+ → {"jsonrpc":"2.0","method":"notifications/initialized"}
184
+ → {"jsonrpc":"2.0","id":1,"method":"tools/list"}
185
+ ← {"jsonrpc":"2.0","id":1,"result":{"tools":[...]}}
186
+ ```
187
+
188
+ All messages except `notifications/*` require a response.
189
+ `notifications/*` carry no `id` and are silently consumed.
190
+
191
+ ## Tool reference
192
+
193
+ ### rigor_check
194
+
195
+ Analyze one or more Ruby files or directories for type errors,
196
+ undefined methods, arity mismatches, and nil-receiver risks.
197
+
198
+ **Input:**
199
+
200
+ | Argument | Type | Required | Default |
201
+ |---|---|---|---|
202
+ | `paths` | `string[]` | yes | — |
203
+ | `config` | `string` | no | session default |
204
+
205
+ **Returns:** JSON — the same structure as `rigor check --format json`.
206
+
207
+ ```json
208
+ {
209
+ "diagnostics": [
210
+ {
211
+ "path": "app/models/user.rb",
212
+ "line": 42,
213
+ "column": 5,
214
+ "rule": "call.undefined-method",
215
+ "severity": "error",
216
+ "message": "undefined method `naem` for String"
217
+ }
218
+ ]
219
+ }
220
+ ```
221
+
222
+ `isError` is `false` when the run completes normally, even if
223
+ diagnostics were found. `isError: true` signals a configuration or
224
+ runtime failure (bad path, unreadable config, etc.).
225
+
226
+ **Typical agent use:** call `rigor_check` on the files an agent is
227
+ about to edit, record the baseline, apply the edit, call again, diff
228
+ the two diagnostic arrays to see whether the change introduced or
229
+ resolved issues.
230
+
231
+ ---
232
+
233
+ ### rigor_type_of
234
+
235
+ Get the inferred type of the expression at a specific source location.
236
+
237
+ **Input:**
238
+
239
+ | Argument | Type | Required |
240
+ |---|---|---|
241
+ | `file` | `string` | yes |
242
+ | `line` | `integer` (1-based) | yes |
243
+ | `col` | `integer` (1-based) | yes |
244
+ | `config` | `string` | no |
245
+
246
+ **Returns:** JSON — the same as `rigor type-of --format json`.
247
+
248
+ ```json
249
+ {
250
+ "file": "lib/order.rb",
251
+ "line": 17,
252
+ "column": 10,
253
+ "node": "LocalVariableReadNode",
254
+ "type": "Integer | nil",
255
+ "erased": "Integer?"
256
+ }
257
+ ```
258
+
259
+ **Typical agent use:** ground a hover explanation ("what type is `x`
260
+ at this cursor position?") or validate a type assumption before
261
+ generating a signature.
262
+
263
+ ---
264
+
265
+ ### rigor_triage
266
+
267
+ Summarize a project's diagnostic stream: rule distribution,
268
+ class/method selectors, per-file hotspots, and heuristic hints for
269
+ the most common error clusters.
270
+
271
+ **Input:**
272
+
273
+ | Argument | Type | Required | Default |
274
+ |---|---|---|---|
275
+ | `paths` | `string[]` | no | configured paths |
276
+ | `top` | `integer` | no | `10` |
277
+ | `config` | `string` | no | session default |
278
+
279
+ **Returns:** JSON — the same as `rigor triage --format json`.
280
+
281
+ ```json
282
+ {
283
+ "summary": { "total": 488, "error": 480, "warning": 8, "info": 0 },
284
+ "distribution": [
285
+ { "rule": "call.possible-nil-receiver", "count": 212 }
286
+ ],
287
+ "selectors": [
288
+ { "receiver": "String", "method": "squish", "count": 31, "files": 12,
289
+ "rules": { "call.undefined-method": 31 } }
290
+ ],
291
+ "hotspots": [
292
+ { "file": "app/models/account.rb", "count": 38,
293
+ "by_rule": { "call.possible-nil-receiver": 30 } }
294
+ ],
295
+ "hints": [
296
+ { "id": "activesupport-core-ext", "confidence": "likely",
297
+ "diagnostic_count": 365, "summary": "...", "action": "..." }
298
+ ],
299
+ "include_info": false
300
+ }
301
+ ```
302
+
303
+ By default the `distribution` / `selectors` / `hotspots` arrays count
304
+ only the actionable diagnostics (`error` + `warning`); `info` (mostly
305
+ plugin recognition trace) is excluded, so those counts do not sum to
306
+ `summary.total` and `include_info` is `false`. `summary.info` still
307
+ reports the full info count, and the hints still see every diagnostic.
308
+
309
+ The `selectors` array is the by-(class, method) axis: each row is a
310
+ dispatch target with its `count`, distinct-`files` spread, and
311
+ per-`rule` breakdown, keyed on a normalised receiver class — so an
312
+ agent answers "which method concentrates the diagnostics?" from
313
+ structured fields, never by parsing a `message`.
314
+
315
+ **Typical agent use:** run `rigor_triage` at the start of a code
316
+ review or cleanup session to understand the diagnostic landscape
317
+ before deciding which rules and files to focus on — sort `selectors`
318
+ by `count` for the highest-leverage class/method, or filter by
319
+ `files` to separate systemic clusters from one-off bugs.
320
+
321
+ ---
322
+
323
+ ### rigor_annotate
324
+
325
+ Return the given Ruby source file with each line's last-expression
326
+ type appended as a `#=>` comment. `def` header lines show
327
+ the method's inferred return type.
328
+
329
+ **Input:**
330
+
331
+ | Argument | Type | Required |
332
+ |---|---|---|
333
+ | `file` | `string` | yes |
334
+ | `config` | `string` | no |
335
+
336
+ **Returns:** Plain text (annotated Ruby source). Not JSON.
337
+
338
+ ```ruby
339
+ module Rigor
340
+ VERSION = "0.2.1" #=> "0.2.1"
341
+ end
342
+ ```
343
+
344
+ **Typical agent use:** understand how Rigor infers types through a
345
+ specific file without having to call `rigor_type_of` line by line.
346
+
347
+ ---
348
+
349
+ ### rigor_sig_gen
350
+
351
+ Generate RBS skeleton signatures inferred from Ruby source files.
352
+
353
+ **Input:**
354
+
355
+ | Argument | Type | Required | Default |
356
+ |---|---|---|---|
357
+ | `paths` | `string[]` | no | configured paths |
358
+ | `params` | `"untyped"` \| `"observed"` | no | `"untyped"` |
359
+ | `config` | `string` | no | session default |
360
+
361
+ `params: "observed"` harvests call-site argument types from `spec/`
362
+ (or a directory named via `--observe=PATH` in the underlying CLI).
363
+
364
+ **Returns:** JSON — the same as `rigor sig-gen --print --format json`.
365
+
366
+ ```json
367
+ {
368
+ "candidates": [
369
+ {
370
+ "class_name": "Order",
371
+ "method_name": "total",
372
+ "kind": "instance",
373
+ "classification": "new-method",
374
+ "rbs": "def total: () -> Integer"
375
+ }
376
+ ]
377
+ }
378
+ ```
379
+
380
+ Classifications: `new-file`, `new-method`, `tighter-return`,
381
+ `equivalent`, `skipped`.
382
+
383
+ **Typical agent use:** call `rigor_sig_gen` to see which methods have
384
+ precise enough returns to be worth writing into `sig/`, then generate
385
+ and insert the RBS. The agent should NOT write signatures
386
+ automatically — present the candidates for human review, then apply
387
+ confirmed entries via `rigor sig-gen --write`.
388
+
389
+ ---
390
+
391
+ ### rigor_explain
392
+
393
+ Look up the description of one or all Rigor diagnostic rules.
394
+
395
+ **Input:**
396
+
397
+ | Argument | Type | Required | Notes |
398
+ |---|---|---|---|
399
+ | `rule` | `string` | no | Omit to get the full catalog |
400
+
401
+ Accepted values: a canonical rule ID (`call.undefined-method`), a
402
+ legacy alias (`undefined-method`), or a family prefix (`call`, `flow`,
403
+ `assert`, `dump`, `def`).
404
+
405
+ **Returns:** JSON — an array of rule catalog entries.
406
+
407
+ ```json
408
+ [
409
+ {
410
+ "id": "call.undefined-method",
411
+ "summary": "Method not found on the inferred receiver type.",
412
+ "severity_authored": "error",
413
+ "since": "0.0.1",
414
+ "fires_when": ["..."],
415
+ "does_not_fire_when": ["..."],
416
+ "suppression": "# rigor:disable call.undefined-method"
417
+ }
418
+ ]
419
+ ```
420
+
421
+ **Typical agent use:** explain a diagnostic to the user, or look up
422
+ whether a rule fires in a specific situation before deciding whether a
423
+ finding is a real bug.
424
+
425
+ ---
426
+
427
+ ### rigor_coverage
428
+
429
+ Report type-precision coverage: the ratio of expressions Rigor types
430
+ as `Constant` / `Nominal` / shaped / refined (precise) versus
431
+ `Dynamic[top]` or `top` (opaque).
432
+
433
+ **Input:**
434
+
435
+ | Argument | Type | Required |
436
+ |---|---|---|
437
+ | `paths` | `string[]` | yes |
438
+ | `config` | `string` | no |
439
+
440
+ **Returns:** JSON — the same as `rigor coverage --format json`.
441
+
442
+ ```json
443
+ {
444
+ "summary": {
445
+ "files_processed": 12,
446
+ "expressions_typed": 3841,
447
+ "precision_ratio": 0.447
448
+ },
449
+ "tiers": {
450
+ "constant": 312, "nominal": 903, "shaped": 46,
451
+ "refined": 71, "bot": 381,
452
+ "dynamic_specific": 512, "dynamic_top": 1498, "top": 118
453
+ },
454
+ "files": [
455
+ {
456
+ "path": "lib/order.rb",
457
+ "expressions_typed": 214,
458
+ "precision_ratio": 0.612
459
+ }
460
+ ]
461
+ }
462
+ ```
463
+
464
+ **Typical agent use:** measure the impact of adding a fold rule or RBS
465
+ annotation — call `rigor_coverage` before and after, compare the
466
+ `precision_ratio` delta.
467
+
468
+ ---
469
+
470
+ ## Troubleshooting
471
+
472
+ **The MCP server starts but the client shows no tools.**
473
+
474
+ Run `rigor mcp` manually in a terminal and send the handshake:
475
+
476
+ ```sh
477
+ echo '{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"0"}}}' | rigor mcp
478
+ ```
479
+
480
+ You should get a JSON response. If you get nothing or a shell error,
481
+ `rigor` is not on your `PATH` — fix the install path first (see
482
+ [Installing Rigor](01-installation.md)).
483
+
484
+ **`rigor_check` / `rigor_triage` return an empty diagnostics array on a project that has errors.**
485
+
486
+ The tool uses `Configuration.discover` from the working directory the
487
+ MCP server was started in. If the client launches `rigor mcp` from a
488
+ home or temp directory, no `.rigor.yml` is found and the configured
489
+ paths default to the empty set. Mitigations:
490
+
491
+ - Pass `--config=/path/to/project/.rigor.yml` when launching:
492
+ `"args": ["mcp", "--config=/path/to/project/.rigor.yml"]`
493
+ - Or pass an absolute `paths` argument in the tool call:
494
+ `{ "name": "rigor_check", "arguments": { "paths": ["/path/to/project/lib"] } }`
495
+
496
+ **`rigor_type_of` reports `isError: true`.**
497
+
498
+ The file path must be the exact on-disk path readable from the server
499
+ process. Relative paths are resolved from the server's working
500
+ directory. Use absolute paths from AI agents to avoid ambiguity.
501
+
502
+ **Tool calls are slow on first call, fast afterward.**
503
+
504
+ The first call in a session cold-boots the Ruby `require` cache;
505
+ subsequent calls reuse it. Expected warm-path latency:
506
+
507
+ | Tool | Cold (first call) | Warm (subsequent calls) |
508
+ |---|---|---|
509
+ | `rigor_explain` | < 200 ms | < 5 ms |
510
+ | `rigor_type_of` | ~1.5 s | ~200 ms |
511
+ | `rigor_check` (small project) | ~2 s | ~500 ms |
512
+ | `rigor_triage` (small project) | ~2 s | ~700 ms |
513
+
514
+ Cold-start is dominated by RBS environment build. A `.rigor/cache`
515
+ warmed by a prior `rigor check` run reduces it significantly.
516
+
517
+ ## Status and roadmap
518
+
519
+ `rigor mcp` shipped in v0.1.10 with all seven tools and stdio
520
+ transport. Queued follow-ups are demand-driven:
521
+
522
+ - **HTTP transport** (slice 2) — `--transport=http` for CI / remote
523
+ agent use; a minimal Rack endpoint.
524
+ - **Across-call environment caching** (slice 3) — hold a warm
525
+ `Environment` + `Cache::Store` in the server between calls,
526
+ invalidated by an `mtime`-based check; reduces warm-path latency
527
+ to near-zero for repeated calls against the same project.
528
+ - **`rigor_check` buffer mode** — accept an in-memory source buffer
529
+ instead of (or alongside) a file path; mirrors the `--tmp-file` /
530
+ `--instead-of` editor-mode flags. Useful when an AI agent has
531
+ edited a file's content in-memory and wants to check the modified
532
+ version before writing it.
533
+ - **`rigor_baseline_generate` (write-side, gated)** — explicitly
534
+ opt-in write tool for agents operating with confirmed write
535
+ permissions. Deferred until there is a clear demand signal.
536
+
537
+ To request a queued feature or report an issue, open a GitHub issue
538
+ with: the MCP client + version, the Rigor version (`rigor version`),
539
+ and the JSON-RPC exchange that triggered the problem.