rigortype 0.2.1 → 0.2.2

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 (105) 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 +557 -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 +532 -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.rb +25 -3
  89. data/lib/rigor/inference/method_dispatcher/constant_folding.rb +124 -32
  90. data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +37 -6
  91. data/lib/rigor/inference/scope_indexer.rb +87 -89
  92. data/lib/rigor/plugin/isolation.rb +5 -5
  93. data/lib/rigor/plugin/loader.rb +4 -2
  94. data/lib/rigor/version.rb +1 -1
  95. data/skills/rigor-ask/SKILL.md +172 -0
  96. data/skills/rigor-doctor/SKILL.md +87 -0
  97. data/skills/rigor-editor-setup/SKILL.md +114 -0
  98. data/skills/rigor-mcp-setup/SKILL.md +117 -0
  99. data/skills/rigor-monkeypatch-resolve/SKILL.md +79 -0
  100. data/skills/rigor-next-steps/SKILL.md +113 -0
  101. data/skills/rigor-plugin-tune/SKILL.md +79 -0
  102. data/skills/rigor-protection-uplift/SKILL.md +133 -0
  103. data/skills/rigor-rbs-setup/SKILL.md +128 -0
  104. data/skills/rigor-upgrade/SKILL.md +79 -0
  105. metadata +90 -1
@@ -0,0 +1,274 @@
1
+ # Running Rigor in CI
2
+
3
+ Rigor runs on Ruby 4.0 (see
4
+ [Installing Rigor](01-installation.md)). In CI that
5
+ has one consequence worth stating up front; the rest of this page
6
+ follows from it.
7
+
8
+ ## Run Rigor in its own job
9
+
10
+ Run Rigor in a **separate CI job** from your test suite — better
11
+ still, a separate workflow file. The reason is concrete:
12
+ `ruby/setup-ruby` sets the *job's* active Ruby. A test job
13
+ provisions the Ruby your project runs (often a 3.x version, or a
14
+ matrix of several); Rigor needs Ruby 4.0. The two cannot share a job
15
+ without the second `setup-ruby` call clobbering the first.
16
+
17
+ A separate job gives Rigor a clean runner where provisioning Ruby
18
+ 4.0 conflicts with nothing. A separate workflow file additionally
19
+ gets its own triggers, concurrency group, and status badge — and
20
+ keeps the analyser out of the test workflow, which is good practice
21
+ regardless.
22
+
23
+ ## A minimal GitHub Actions workflow
24
+
25
+ ```yaml
26
+ # .github/workflows/rigor.yml
27
+ name: rigor
28
+ on: [push, pull_request]
29
+ jobs:
30
+ rigor:
31
+ runs-on: ubuntu-latest
32
+ steps:
33
+ - uses: actions/checkout@v4
34
+ - uses: ruby/setup-ruby@v1
35
+ with:
36
+ ruby-version: "4.0"
37
+ - run: gem install rigortype
38
+ - run: rigor check
39
+ ```
40
+
41
+ Those four steps check out the project, provision Ruby 4.0, install
42
+ Rigor, and run it. That workflow surfaces diagnostics only in the job
43
+ log. To put them **inline on the changed code** (a PR annotation, a
44
+ code-scanning alert, a merge-request widget) use one of the CI-native
45
+ output formats below.
46
+
47
+ ## It already works on GitHub Actions (auto-detection)
48
+
49
+ `rigor check` detects the CI it runs in and, on its default output, surfaces
50
+ diagnostics the platform-native way **without any `--format`** — modelled on
51
+ PHPStan's CI auto-detection. So the minimal workflow at the top of this page
52
+ already produces inline PR annotations on GitHub Actions: the human log stays,
53
+ and `::error` annotations are added on top.
54
+
55
+ - **GitHub Actions** and **TeamCity** (first-class): native annotations are
56
+ emitted on top of the text output automatically.
57
+ - **GitLab CI** (native, but artifact-based): a one-line hint reminds you to
58
+ run `--format gitlab` and publish the `codequality` artifact (below).
59
+ - **Other CIs** (CircleCI, Jenkins, Travis, Azure, Bitbucket, Buildkite,
60
+ Drone, …): a one-line hint points you at the reviewdog or `--format junit`
61
+ path.
62
+
63
+ Auto-detection only augments the default human output — an explicit
64
+ `--format` is never touched. Turn it off with `--no-ci-detect` or
65
+ `RIGOR_CI_DETECT=0`. The sections below are for when you want a *specific*
66
+ surface (code scanning, the GitLab widget, review comments) rather than the
67
+ auto default.
68
+
69
+ ## Surfacing diagnostics inline in the PR / MR
70
+
71
+ `rigor check --format` renders the same diagnostics in a format your CI
72
+ platform reads to annotate the diff directly, instead of leaving them in
73
+ the job log ([ADR-51](../adr/51-ci-diagnostic-output-formats.md)). These
74
+ layer on the generic `--format json` stream; they add no new diagnostics,
75
+ only a platform-native rendering. Ready-to-copy template files live under
76
+ [`ci-templates/`](ci-templates/).
77
+
78
+ ### GitHub — inline annotations (the default)
79
+
80
+ `--format github` emits GitHub Actions workflow commands
81
+ (`::error file=…,line=…::`) that the runner turns into inline annotations
82
+ on the PR — no upload step, no code-scanning setup, no extra permissions.
83
+ Because it works on **every** repository (public or private, no paid
84
+ features), it is the recommended default for GitHub:
85
+
86
+ ```yaml
87
+ - run: gem install rigortype
88
+ - run: rigor check --format github
89
+ ```
90
+
91
+ ### GitHub — code scanning (SARIF)
92
+
93
+ Upgrade to SARIF for the Security tab, deduped + persistent alerts, and
94
+ richer PR alerts — **when code scanning is available**: a public repo
95
+ (free), or a private repo with GitHub Advanced Security / Code Security
96
+ enabled. (Without it, `upload-sarif` fails with *"GitHub Advanced Security
97
+ must be enabled for this repository"* — use the annotations form above.)
98
+ The check step uses `continue-on-error` (and the upload runs `if: always()`)
99
+ so a non-zero Rigor exit still publishes the report:
100
+
101
+ ```yaml
102
+ # .github/workflows/rigor.yml
103
+ name: rigor
104
+ on: [push, pull_request]
105
+ permissions:
106
+ contents: read
107
+ security-events: write # required by upload-sarif
108
+ jobs:
109
+ rigor:
110
+ runs-on: ubuntu-latest
111
+ steps:
112
+ - uses: actions/checkout@v4
113
+ - uses: ruby/setup-ruby@v1
114
+ with:
115
+ ruby-version: "4.0"
116
+ - run: gem install rigortype
117
+ - run: rigor check --format sarif > rigor.sarif
118
+ continue-on-error: true
119
+ - uses: github/codeql-action/upload-sarif@v3
120
+ if: always()
121
+ with:
122
+ sarif_file: rigor.sarif
123
+ ```
124
+
125
+ SARIF is the cross-platform option: the same report is consumed by any
126
+ SARIF-aware tool, not only GitHub.
127
+
128
+ ### GitLab — Code Quality widget
129
+
130
+ `--format gitlab` emits a GitLab Code Quality (CodeClimate-subset) report.
131
+ Publish it as a `codequality` report artifact and GitLab renders the
132
+ findings in the merge-request widget:
133
+
134
+ ```yaml
135
+ # .gitlab-ci.yml
136
+ rigor:
137
+ image: ruby:4.0
138
+ script:
139
+ - gem install rigortype
140
+ - rigor check --format gitlab > gl-code-quality-report.json
141
+ artifacts:
142
+ reports:
143
+ codequality: gl-code-quality-report.json
144
+ when: always
145
+ ```
146
+
147
+ ### Any platform — reviewdog
148
+
149
+ [reviewdog](https://github.com/reviewdog/reviewdog) posts findings as PR/MR
150
+ review comments on GitHub, GitLab, Gerrit, Bitbucket, and Gitea. It reads
151
+ Rigor's `sarif` or `checkstyle` output, so one of those formats reaches
152
+ *all* of its reporters. Install it with
153
+ [`reviewdog/action-setup`](https://github.com/reviewdog/action-setup) and
154
+ pipe Rigor into it:
155
+
156
+ ```yaml
157
+ - uses: reviewdog/action-setup@v1
158
+ - run: rigor check --format checkstyle | reviewdog -f=checkstyle -reporter=github-pr-review -fail-level=error
159
+ env:
160
+ REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
161
+ ```
162
+
163
+ `github-pr-review` needs `permissions: pull-requests: write`. The
164
+ `rigor-ci-setup` skill (`rigor skill rigor-ci-setup`) walks through
165
+ the reporter and `-fail-level` choices.
166
+
167
+ ### Other test-report CI — JUnit
168
+
169
+ `--format junit` emits JUnit XML, which GitHub test reporting, GitLab,
170
+ CircleCI, and Jenkins render. Every diagnostic becomes a `testcase` with a
171
+ `failure` typed by its severity:
172
+
173
+ ```sh
174
+ rigor check --format junit > rigor-junit.xml
175
+ ```
176
+
177
+ ### Severity mapping
178
+
179
+ Rigor's severities map per format ([ADR-51](../adr/51-ci-diagnostic-output-formats.md) WD2):
180
+
181
+ | Rigor | SARIF | GitHub | GitLab | Checkstyle | JUnit | TeamCity |
182
+ | --- | --- | --- | --- | --- | --- | --- |
183
+ | error | `error` | `::error` | `major` | `error` | `error` | `ERROR` |
184
+ | warning | `warning` | `::warning` | `minor` | `warning` | `warning` | `WARNING` |
185
+ | info | `note` | `::notice` | `info` | `info` | `info` | `INFO` |
186
+
187
+ The exit code is unchanged by `--format` — `0` when there are no errors,
188
+ `1` otherwise — so the job still gates the pipeline. `--format json`
189
+ remains available for any other tool that wants the raw diagnostic stream.
190
+
191
+ ## Pinning Rigor's version
192
+
193
+ The workflow above installs whatever `rigortype` is current at run
194
+ time. To pin a version — and keep CI reproducible — choose one of the
195
+ options below. While the `0.1.x` line is in preview the surface is
196
+ still settling, so pinning is recommended; what Rigor commits to
197
+ keeping stable (and from which release) is enumerated in
198
+ [`docs/compatibility.md`](../compatibility.md).
199
+
200
+ ### A CI-only `Gemfile` (recommended)
201
+
202
+ Commit a two-line `.github/rigor/Gemfile`:
203
+
204
+ ```ruby
205
+ source "https://rubygems.org"
206
+ gem "rigortype", "~> 0.1"
207
+ ```
208
+
209
+ plus its `Gemfile.lock`, and point the Rigor job at it through
210
+ `BUNDLE_GEMFILE`:
211
+
212
+ ```yaml
213
+ jobs:
214
+ rigor:
215
+ runs-on: ubuntu-latest
216
+ env:
217
+ BUNDLE_GEMFILE: .github/rigor/Gemfile
218
+ steps:
219
+ - uses: actions/checkout@v4
220
+ - uses: ruby/setup-ruby@v1
221
+ with:
222
+ ruby-version: "4.0"
223
+ bundler-cache: true
224
+ - run: bundle exec rigor check
225
+ ```
226
+
227
+ This `Gemfile` is read only by the Rigor job — it never enters your
228
+ application's dependency resolution, and the committed lockfile
229
+ pins Rigor and its dependencies for a reproducible run. Because it
230
+ is an ordinary Bundler `Gemfile`, Dependabot can keep it current:
231
+ add a `bundler` entry scoped to its directory in
232
+ `.github/dependabot.yml`:
233
+
234
+ ```yaml
235
+ version: 2
236
+ updates:
237
+ - package-ecosystem: bundler
238
+ directory: /.github/rigor
239
+ schedule:
240
+ interval: weekly
241
+ ```
242
+
243
+ ### A pinned `gem install`
244
+
245
+ `gem install rigortype -v "0.1.15"` in the workflow. Simpler, with no
246
+ extra files — but Dependabot does not see a version inside a `run:`
247
+ step, so updates to the pin are manual.
248
+
249
+ ## Container image
250
+
251
+ A standalone image is published to GHCR with Ruby 4.0 and Rigor
252
+ baked in. It suits CI runners with no Ruby toolchain — mount the
253
+ project on `/src`:
254
+
255
+ ```sh
256
+ docker run --rm -v "$PWD:/src" ghcr.io/rigortype/rigor check
257
+ ```
258
+
259
+ `rigor` is the image entrypoint, so subcommands and flags follow the
260
+ image name. Pin a version with an explicit tag —
261
+ `ghcr.io/rigortype/rigor:0.1.15`.
262
+
263
+ ## Nix
264
+
265
+ For CI that already runs Nix, the flake exposes Rigor as a package
266
+ with Ruby 4.0 in its closure — a fully hermetic run with nothing
267
+ else on the runner:
268
+
269
+ ```sh
270
+ nix run github:rigortype/rigor#rigor -- check
271
+ ```
272
+
273
+ See [ADR-27](../adr/27-tool-distribution-model.md) for the
274
+ distribution model behind this page.
@@ -0,0 +1,116 @@
1
+ # Caching
2
+
3
+ Rigor caches expensive intermediate results — parsed RBS
4
+ environments, per-file analysis products — so a second run
5
+ over an unchanged project is fast. The cache is correct by
6
+ construction: you should never need to clear it to fix a stale
7
+ result. This page is for the times you are curious where it
8
+ lives or want to reclaim the space.
9
+
10
+ ## Where it lives
11
+
12
+ The cache is an on-disk directory, `.rigor/cache` by default,
13
+ relative to the project root. Change it with the `cache.path`
14
+ config key:
15
+
16
+ ```yaml
17
+ cache:
18
+ path: tmp/rigor-cache
19
+ ```
20
+
21
+ Add the cache directory to your `.gitignore`.
22
+
23
+ ## What invalidates an entry
24
+
25
+ Each entry is keyed by a hash of everything its result depends
26
+ on:
27
+
28
+ - the **content** of the source and `.rbs` files that fed it,
29
+ - the **gems** in play, by name and locked version,
30
+ - the active **plugins**, by ID and version,
31
+ - the relevant **configuration**.
32
+
33
+ Change any of those and the dependent entries are recomputed
34
+ automatically. A corrupt or unreadable entry is treated as a
35
+ miss and overwritten — bad cache state cannot wedge a run.
36
+
37
+ The cache is also schema-versioned: after a Rigor upgrade that
38
+ changes the cache format, the stale cache is purged on the
39
+ first writable run.
40
+
41
+ ## Controlling the cache
42
+
43
+ | Flag | Effect |
44
+ | --- | --- |
45
+ | `rigor check --no-cache` | Run without reading or writing the persistent cache. |
46
+ | `rigor check --clear-cache` | Delete the cache directory, then run. |
47
+ | `rigor check --cache-stats` | Print the on-disk cache inventory when the run finishes. |
48
+ | `rigor check --incremental` | Re-analyse only what changed; serve the rest from the incremental snapshot (see below). |
49
+
50
+ There is no config key to disable caching permanently — the
51
+ flags are per-run toggles. To run without a persistent cache
52
+ habitually, point `cache.path` at a disposable directory.
53
+
54
+ ## Size and eviction
55
+
56
+ A project's active cache set is small (around 2 MB). Entries
57
+ are content-keyed, so events like a gem upgrade or an `.rbs`
58
+ edit write fresh entries and leave the old ones *orphaned* —
59
+ nothing references them, and no run would otherwise delete
60
+ them. To reap those, Rigor evicts least-recently-used entries
61
+ at the end of a run once the cache directory exceeds
62
+ `cache.max_bytes` (default **256 MB** — far above any active
63
+ set, so eviction only ever touches orphans):
64
+
65
+ ```yaml
66
+ cache:
67
+ max_bytes: 67108864 # tighten the cap to 64 MB…
68
+ ```
69
+
70
+ ```yaml
71
+ cache:
72
+ max_bytes: null # …or disable eviction entirely
73
+ ```
74
+
75
+ ## Incremental analysis
76
+
77
+ The cache above makes an *unchanged* project fast — a second
78
+ run over the same files reuses the whole result. `rigor check
79
+ --incremental` goes further: when you have edited a few files,
80
+ it re-analyses **only those files plus the files that depend on
81
+ them**, and serves every other file's diagnostics from a
82
+ snapshot of the previous run. Editing a leaf controller
83
+ re-checks one file; editing a model re-checks the model and its
84
+ callers — not the whole project.
85
+
86
+ The diagnostics are identical to a full run. Rigor records, per
87
+ file, which other files its analysis read from, so it knows
88
+ exactly which files an edit can affect. A continuous-integration
89
+ gate, `rigor check --verify-incremental`, asserts this on every
90
+ build: it runs the incremental analyzer and a full analysis and
91
+ fails if they disagree on a single diagnostic.
92
+
93
+ The snapshot lives under the cache directory (`.rigor/cache`)
94
+ and is keyed by a fingerprint of your configuration, your locked
95
+ gems, your project's own `sig/` RBS, and the Rigor version.
96
+ Change any of those and the snapshot is dropped and the next run
97
+ is a full one, so an incremental run can never serve a stale
98
+ result. (The fingerprint keys on the analysis *roots* — e.g.
99
+ `["lib"]` — not the expanded file list, so adding or removing a
100
+ file *under* those roots does **not** drop the snapshot: the
101
+ incremental session re-analyzes the added files and the
102
+ dependents of removed ones.) As with the rest of the cache, a
103
+ missing or corrupt snapshot is simply a full run; it can never
104
+ wedge analysis.
105
+
106
+ `--incremental` is most useful for fast local re-checks and CI
107
+ on a changed branch. For a one-shot run on an unchanged project,
108
+ the ordinary cache already serves the whole result in one step.
109
+
110
+ ## Concurrency
111
+
112
+ The cache is safe to share. Parallel worker processes
113
+ (`--workers=N`) and multiple editor LSP sessions against the
114
+ same project coordinate through atomic, locked writes; the LSP
115
+ opens the cache read-only, so it never races a `rigor check`
116
+ running alongside it.
@@ -0,0 +1,120 @@
1
+ # Troubleshooting
2
+
3
+ Common problems and their fixes. For editor-specific issues,
4
+ see [Editor integration](09-editor-integration.md); for "why
5
+ did this diagnostic (not) fire", see
6
+ [handbook chapter 8](../handbook/08-understanding-errors.md).
7
+
8
+ ## `rigor: command not found`
9
+
10
+ Rigor is installed but not on your `PATH`. With a version
11
+ manager this usually means the shell is not activated — see
12
+ [Installing Rigor](01-installation.md). As a stop-gap,
13
+ `mise exec gem:rigortype -- rigor …` runs it explicitly.
14
+
15
+ ## `rigor check` analyses nothing
16
+
17
+ Rigor checks the `paths:` from the configuration file when no
18
+ paths are given on the command line. If `paths:` is wrong, or
19
+ no config file was found, the run is empty. Confirm a
20
+ `.rigor.yml` or `.rigor.dist.yml` exists at the project root,
21
+ or pass paths explicitly: `rigor check lib app`.
22
+
23
+ ## Everything is `untyped` / `Dynamic[top]`
24
+
25
+ Rigor has no type information for the code in question. The
26
+ usual causes:
27
+
28
+ - **A gem ships no RBS.** Install signatures with
29
+ `rbs collection install`, or opt into
30
+ `dependencies.source_inference` (see
31
+ [Configuration](03-configuration.md)).
32
+ - **A framework needs a plugin.** Rails, RSpec, dry-rb and
33
+ others are only legible to Rigor through a
34
+ [plugin](07-plugins.md).
35
+ - **A project monkey-patch is invisible.** List the patching
36
+ files under `pre_eval:` so Rigor walks them first.
37
+
38
+ `rigor type-of FILE:LINE:COL` reports the exact type at a
39
+ point, which narrows down where the information is lost.
40
+
41
+ ## Too many diagnostics to act on
42
+
43
+ A first run on a large, untyped project can report hundreds of
44
+ diagnostics. Do not start by suppressing them one by one:
45
+
46
+ 1. `rigor triage` — see which rules and files dominate, with
47
+ hints about likely causes.
48
+ 2. Fix the systemic causes triage points at — a missing
49
+ plugin, a missing RBS bundle.
50
+ 3. `rigor baseline generate` — snapshot the rest so CI tracks
51
+ only new diagnostics. See [Baselines](06-baseline.md).
52
+
53
+ The [`rigor-project-init` skill](08-skills.md) automates this
54
+ sequence.
55
+
56
+ ## A diagnostic is wrong (a false positive)
57
+
58
+ Rigor aims never to flag working code, so a genuine false
59
+ positive is a bug worth reporting. In the meantime, suppress
60
+ the single site with a `# rigor:disable <rule>` comment (see
61
+ [Diagnostics](04-diagnostics.md)) — prefer that over a
62
+ project-wide `disable:`, which also hides real instances.
63
+
64
+ Before reporting, rule out a missing RBS source. A burst of
65
+ `call.undefined-method` on calls you know exist usually means
66
+ Rigor never loaded their signatures. Check `rigor check`'s
67
+ STDERR for a `rigor: …` config-validation warning — a typo'd
68
+ or moved `signature_paths:` / `libraries:` entry (or an
69
+ explicit `bundler` / `rbs_collection` path that no longer
70
+ exists) loads zero signatures silently, and every call into
71
+ the types it was meant to cover then fires at
72
+ `evidence_tier: high`. Correct the configured value and the
73
+ false positives clear. (The same warnings cover an inert
74
+ `disable:` / `severity_overrides:` rule id — a typo there
75
+ leaves the rule firing as if you never suppressed it.) See
76
+ [Configuration § Config validation warnings](03-configuration.md#config-validation-warnings).
77
+
78
+ If the diagnostic is *correct* but you are not ready to fix
79
+ it, a [baseline](06-baseline.md) is the right tool.
80
+
81
+ ## A result looks stale
82
+
83
+ It should not — cache entries are keyed by content and
84
+ invalidate themselves (see [Caching](12-caching.md)). If you
85
+ suspect the cache anyway, `rigor check --clear-cache` rules it
86
+ out. A result that survives a cleared cache is real analyzer
87
+ behaviour, not a caching artefact.
88
+
89
+ ## The run is slow
90
+
91
+ - Let the cache warm up — the first run is the slow one.
92
+ - Narrow `paths:` and widen `exclude:` so Rigor is not walking
93
+ generated or vendored code.
94
+ - For a large project, `rigor check --workers=N` spreads
95
+ per-file analysis across parallel worker processes (or set
96
+ `RIGOR_RACTOR_WORKERS=N`).
97
+
98
+ ## Advanced diagnostics
99
+
100
+ When a class infers worse than you expect, or a run uses more
101
+ memory than you expect, three environment variables make Rigor
102
+ report on *itself*. They print to stderr after `rigor check`
103
+ finishes and are no-ops when unset. They are process-global
104
+ counters, so run single-process (`--workers 0`) for meaningful
105
+ numbers.
106
+
107
+ | Variable | Reports |
108
+ | --- | --- |
109
+ | `RIGOR_BUDGET_TRACE=1` | How often inference hit a built-in cutoff (recursion guard, ancestor-walk limit, HKT fuel, …) and silently degraded to `Dynamic[top]`, plus the union-size distribution. The fastest way to see *where* inference gave up. |
110
+ | `RIGOR_HEAP_PROFILE=1` | A live-heap breakdown by class after a forced GC, ranked by memory — what the resident heap is actually made of (type carriers, RBS objects, Prism nodes, …). Walking the whole heap is slow; use it as a probe, not on every run. |
111
+ | `RIGOR_HEAP_TRACE=1` | The top String allocation sites by `file:line`. Very high overhead — run it on a small file subset only. |
112
+
113
+ These are intended for diagnosing Rigor itself or filing a
114
+ detailed bug report, not for day-to-day use.
115
+
116
+ ## Reporting a bug
117
+
118
+ Open a GitHub issue with the Rigor version (`rigor version`),
119
+ the command you ran, a minimal reproduction, and — for a
120
+ suspected false positive — what you expected Rigor to infer.