rigortype 0.2.0 → 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 (142) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +82 -20
  3. data/data/core_overlay/numeric.rbs +33 -0
  4. data/data/core_overlay/pathname.rbs +25 -0
  5. data/data/core_overlay/string_scanner.rbs +28 -0
  6. data/data/gem_overlay/activesupport/core_ext.rbs +473 -0
  7. data/data/vendored_gem_sigs/ast/ast.rbs +130 -0
  8. data/data/vendored_gem_sigs/bcrypt/bcrypt.rbs +47 -0
  9. data/data/vendored_gem_sigs/bundler/bundler.rbs +238 -0
  10. data/data/vendored_gem_sigs/cgi/cgi_extras.rbs +34 -0
  11. data/data/vendored_gem_sigs/did_you_mean/did_you_mean_extras.rbs +34 -0
  12. data/data/vendored_gem_sigs/idn-ruby/idn.rbs +54 -0
  13. data/data/vendored_gem_sigs/mysql2/client.rbs +55 -0
  14. data/data/vendored_gem_sigs/mysql2/error.rbs +5 -0
  15. data/data/vendored_gem_sigs/mysql2/result.rbs +31 -0
  16. data/data/vendored_gem_sigs/mysql2/statement.rbs +5 -0
  17. data/data/vendored_gem_sigs/nokogiri/nokogiri.rbs +2332 -0
  18. data/data/vendored_gem_sigs/nokogiri/nokogiri_html5.rbs +47 -0
  19. data/data/vendored_gem_sigs/pg/pg.rbs +212 -0
  20. data/data/vendored_gem_sigs/prism/prism_supplement.rbs +44 -0
  21. data/data/vendored_gem_sigs/redis/errors.rbs +50 -0
  22. data/data/vendored_gem_sigs/redis/future.rbs +5 -0
  23. data/data/vendored_gem_sigs/redis/redis.rbs +348 -0
  24. data/data/vendored_gem_sigs/redis/redis_extras.rbs +130 -0
  25. data/data/vendored_gem_sigs/rubygems/rubygems_extras.rbs +226 -0
  26. data/docs/handbook/01-getting-started.md +311 -0
  27. data/docs/handbook/02-everyday-types.md +337 -0
  28. data/docs/handbook/03-narrowing.md +359 -0
  29. data/docs/handbook/04-tuples-and-shapes.md +321 -0
  30. data/docs/handbook/05-methods-and-blocks.md +339 -0
  31. data/docs/handbook/06-classes.md +305 -0
  32. data/docs/handbook/07-rbs-and-extended.md +427 -0
  33. data/docs/handbook/08-understanding-errors.md +373 -0
  34. data/docs/handbook/09-plugins.md +241 -0
  35. data/docs/handbook/10-sorbet.md +347 -0
  36. data/docs/handbook/11-sig-gen.md +312 -0
  37. data/docs/handbook/12-lightweight-hkt.md +333 -0
  38. data/docs/handbook/README.md +275 -0
  39. data/docs/handbook/appendix-elixir.md +370 -0
  40. data/docs/handbook/appendix-go.md +399 -0
  41. data/docs/handbook/appendix-java-csharp.md +470 -0
  42. data/docs/handbook/appendix-liskov.md +580 -0
  43. data/docs/handbook/appendix-mypy.md +370 -0
  44. data/docs/handbook/appendix-phpstan.md +338 -0
  45. data/docs/handbook/appendix-protocols-and-structural-typing.md +292 -0
  46. data/docs/handbook/appendix-rust.md +446 -0
  47. data/docs/handbook/appendix-steep.md +336 -0
  48. data/docs/handbook/appendix-type-theory.md +1662 -0
  49. data/docs/handbook/appendix-typeprof.md +416 -0
  50. data/docs/handbook/appendix-typescript.md +332 -0
  51. data/docs/install.md +189 -0
  52. data/docs/llms.txt +72 -0
  53. data/docs/manual/01-installation.md +342 -0
  54. data/docs/manual/02-cli-reference.md +557 -0
  55. data/docs/manual/03-configuration.md +152 -0
  56. data/docs/manual/04-diagnostics.md +206 -0
  57. data/docs/manual/05-inspecting-types.md +109 -0
  58. data/docs/manual/06-baseline.md +104 -0
  59. data/docs/manual/07-plugins.md +92 -0
  60. data/docs/manual/08-skills.md +143 -0
  61. data/docs/manual/09-editor-integration.md +245 -0
  62. data/docs/manual/10-mcp-server.md +532 -0
  63. data/docs/manual/11-ci.md +274 -0
  64. data/docs/manual/12-caching.md +116 -0
  65. data/docs/manual/13-troubleshooting.md +120 -0
  66. data/docs/manual/14-rails-quickstart.md +332 -0
  67. data/docs/manual/15-type-protection-coverage.md +204 -0
  68. data/docs/manual/16-rbs-extended-annotations.md +190 -0
  69. data/docs/manual/17-driving-improvement.md +160 -0
  70. data/docs/manual/README.md +87 -0
  71. data/docs/manual/ci-templates/README.md +58 -0
  72. data/docs/manual/plugins/README.md +86 -0
  73. data/docs/manual/plugins/rigor-actioncable.md +78 -0
  74. data/docs/manual/plugins/rigor-actionmailer.md +74 -0
  75. data/docs/manual/plugins/rigor-actionpack.md +80 -0
  76. data/docs/manual/plugins/rigor-activejob.md +58 -0
  77. data/docs/manual/plugins/rigor-activerecord.md +102 -0
  78. data/docs/manual/plugins/rigor-activestorage.md +74 -0
  79. data/docs/manual/plugins/rigor-activesupport-core-ext.md +86 -0
  80. data/docs/manual/plugins/rigor-devise.md +70 -0
  81. data/docs/manual/plugins/rigor-dry-schema.md +56 -0
  82. data/docs/manual/plugins/rigor-dry-struct.md +60 -0
  83. data/docs/manual/plugins/rigor-dry-types.md +59 -0
  84. data/docs/manual/plugins/rigor-dry-validation.md +62 -0
  85. data/docs/manual/plugins/rigor-factorybot.md +76 -0
  86. data/docs/manual/plugins/rigor-graphql.md +89 -0
  87. data/docs/manual/plugins/rigor-hanami.md +83 -0
  88. data/docs/manual/plugins/rigor-mangrove.md +73 -0
  89. data/docs/manual/plugins/rigor-minitest.md +86 -0
  90. data/docs/manual/plugins/rigor-pundit.md +72 -0
  91. data/docs/manual/plugins/rigor-rails-i18n.md +92 -0
  92. data/docs/manual/plugins/rigor-rails-routes.md +94 -0
  93. data/docs/manual/plugins/rigor-rails.md +44 -0
  94. data/docs/manual/plugins/rigor-rbs-inline.md +83 -0
  95. data/docs/manual/plugins/rigor-rspec-rails.md +72 -0
  96. data/docs/manual/plugins/rigor-rspec.md +86 -0
  97. data/docs/manual/plugins/rigor-shoulda-matchers.md +78 -0
  98. data/docs/manual/plugins/rigor-sidekiq.md +78 -0
  99. data/docs/manual/plugins/rigor-sinatra.md +61 -0
  100. data/docs/manual/plugins/rigor-sorbet.md +63 -0
  101. data/docs/manual/plugins/rigor-statesman.md +75 -0
  102. data/docs/manual/plugins/rigor-typescript-utility-types.md +71 -0
  103. data/exe/rigor +1 -1
  104. data/lib/rigor/analysis/incremental_session.rb +4 -2
  105. data/lib/rigor/analysis/run_stats.rb +13 -1
  106. data/lib/rigor/analysis/runner.rb +54 -12
  107. data/lib/rigor/cli/check_command.rb +26 -3
  108. data/lib/rigor/cli/coverage_command.rb +67 -92
  109. data/lib/rigor/cli/coverage_mutation.rb +149 -0
  110. data/lib/rigor/cli/docs_command.rb +248 -0
  111. data/lib/rigor/cli/fused_protection_renderer.rb +67 -0
  112. data/lib/rigor/cli/fused_protection_report.rb +76 -0
  113. data/lib/rigor/cli/skill_command.rb +103 -41
  114. data/lib/rigor/cli/skill_describe.rb +346 -0
  115. data/lib/rigor/cli.rb +25 -3
  116. data/lib/rigor/config_audit.rb +152 -0
  117. data/lib/rigor/configuration.rb +12 -0
  118. data/lib/rigor/environment/rbs_loader.rb +27 -0
  119. data/lib/rigor/environment.rb +49 -1
  120. data/lib/rigor/inference/method_dispatcher/constant_folding.rb +140 -38
  121. data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +37 -6
  122. data/lib/rigor/inference/scope_indexer.rb +87 -89
  123. data/lib/rigor/inference/statement_evaluator.rb +27 -0
  124. data/lib/rigor/plugin/isolation.rb +5 -5
  125. data/lib/rigor/plugin/loader.rb +4 -2
  126. data/lib/rigor/protection/diagnostic_oracle.rb +51 -0
  127. data/lib/rigor/protection/mutation_scanner.rb +98 -38
  128. data/lib/rigor/protection/mutator.rb +21 -0
  129. data/lib/rigor/protection/test_suite_oracle.rb +68 -0
  130. data/lib/rigor/signature_path_audit.rb +92 -0
  131. data/lib/rigor/version.rb +1 -1
  132. data/skills/rigor-ask/SKILL.md +172 -0
  133. data/skills/rigor-doctor/SKILL.md +87 -0
  134. data/skills/rigor-editor-setup/SKILL.md +114 -0
  135. data/skills/rigor-mcp-setup/SKILL.md +117 -0
  136. data/skills/rigor-monkeypatch-resolve/SKILL.md +79 -0
  137. data/skills/rigor-next-steps/SKILL.md +113 -0
  138. data/skills/rigor-plugin-tune/SKILL.md +79 -0
  139. data/skills/rigor-protection-uplift/SKILL.md +133 -0
  140. data/skills/rigor-rbs-setup/SKILL.md +128 -0
  141. data/skills/rigor-upgrade/SKILL.md +79 -0
  142. metadata +120 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e5c87db4b1ce8d734a2c7f8d7f0b7af6a7d643612f011c08676a5bca123ae4cb
4
- data.tar.gz: b9340fe30f78245443d61d82965e08f2833e4787b938886f8f42890981a88cff
3
+ metadata.gz: a23952ba800fa7d807c8b8acc4d1cfbb3489024d91c3c30d687ebfdb75c7d1f5
4
+ data.tar.gz: 1a301a820c1c0bd3c2946695ae59f8e00906d1ecebedc0fbfb1fa93da3f6a72a
5
5
  SHA512:
6
- metadata.gz: 94cafd68574caa752869465bcbf8a8e646bf302f4c540f9eb3dee122b6d455c193a21dd2debbf2c481f1676fb4c83aca131a3ba73508fef65c3dd1f2a3debaaa
7
- data.tar.gz: f762d58ad77bd3e819f346b6de84408769320d6025030737b3611ce918db4c5e7943e0371b9b0603c27c2be8b8d2064975ff1e2bb113b4e3af8443bb2723fd05
6
+ metadata.gz: 6574512ee06d1eb87e42f697d7261eac8ecf9bba9ae4a8a4be6263fba188de5b9786babdcef7e9b2cf41ac4877010726d60f66b741af7b5295d6d3e98e5937cb
7
+ data.tar.gz: d1bcccf23cac521597657aadd2f1c35d7a860998dd3fc8e02a7802c2dc0e9bf23ca3c0e6c368cdb9574cc1ac1e5ff2395f9dd5f164beae13541874d617886b19
data/README.md CHANGED
@@ -4,20 +4,25 @@
4
4
  [![GitHub License](https://img.shields.io/github/license/rigortype/rigor)](https://github.com/rigortype/rigor/blob/master/LICENSE)
5
5
  [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/rigortype/rigor)
6
6
 
7
- **Type-aware bug finding for Ruby — zero annotations, and a
8
- zero-false-positive bar enforced against real codebases.** Run one
9
- command over the code you already have, and trust every line of
10
- output.
7
+ **Type-aware bug finding for Ruby — no annotations required, and a
8
+ zero-false-positive bar enforced against real codebases.** Built on
9
+ RBS: Rigor infers types from the values your code produces, reads any
10
+ RBS you write as an authoritative source, and generates more — but
11
+ needs none to start. Run one command over the code you already have,
12
+ and trust every line of output.
11
13
 
12
14
  ```sh
13
- gem install rigortype && rigor check app lib
15
+ mise use -g ruby@4.0 gem:rigortype # install the tool, globally, on Ruby 4.0
16
+ rigor check app lib # find bugs in the code you already have
14
17
  ```
15
18
 
16
- (The tool itself runs on Ruby 4.0; your project can stay on whatever
17
- Ruby it targets see [Get started](#get-started-in-one-prompt).)
19
+ (The tool runs on Ruby 4.0 while your project keeps its own Ruby; the
20
+ global `-g` install keeps it off your project's pins. See
21
+ [Get started](#get-started-in-one-prompt).)
18
22
 
19
- No type annotations to write or maintain, no runtime dependency, no
20
- changes to your code. Rigor parses Ruby with
23
+ No annotations required, no runtime dependency, no changes to your
24
+ code and any RBS you do add, Rigor reads and uses. Rigor parses Ruby
25
+ with
21
26
  [Prism](https://github.com/ruby/prism) and runs a flow-sensitive
22
27
  inference engine that reasons about the *values* your expressions
23
28
  produce — not just their classes. It catches undefined methods (and
@@ -106,13 +111,14 @@ Bahasa Indonesia, Polski, Українська, Русский, Română, Türk
106
111
  the [installation guide](https://rigor.typedduck.fail/reference/manual/01-installation/#set-up-in-your-language).
107
112
 
108
113
  **Manual install** — Rigor is a tool, not a library: install it
109
- independently, **not** in your project's `Gemfile`. It runs on Ruby
110
- 4.0 regardless of which Ruby your project targets
111
- ([`mise`](https://mise.jdx.dev/) provisions both, pinned per project):
114
+ independently, **not** in your project's `Gemfile`. Install it
115
+ **globally** so `rigor` is on your `PATH` everywhere, running on Ruby
116
+ 4.0 while each project keeps its own Ruby — the `-g` install lives in
117
+ your global [`mise`](https://mise.jdx.dev/) config and never touches a
118
+ project's pins:
112
119
 
113
120
  ```sh
114
- mise use ruby@4.0
115
- mise use gem:rigortype # or: gem install rigortype
121
+ mise use -g ruby@4.0 gem:rigortype # or: gem install rigortype
116
122
  ```
117
123
 
118
124
  The gem is named `rigortype` (the name `rigor` was taken on RubyGems);
@@ -202,14 +208,38 @@ walks the whole type model; the
202
208
  and [user manual](https://rigor.typedduck.fail/reference/manual/) are
203
209
  the reference companions.
204
210
 
211
+ **Stuck on Rigor — or just curious how it works? Ask your agent in
212
+ plain language.** The whole skill surface collapses to two an agent (and
213
+ you) need to remember: **`rigor-next-steps`** ("what should we do
214
+ next?") and **`rigor-ask`** ("answer this about Rigor"). Rigor is niche
215
+ and fast-moving, so a model's *remembered* answer is often stale —
216
+ `rigor-ask` **investigates instead**: it reads Rigor's own handbook and
217
+ manual (bundled in the gem, served **offline** by `rigor docs`, always
218
+ matching your installed version) *and* runs Rigor over your actual code
219
+ (`rigor check` / `annotate` / `type-of`), then answers from what it
220
+ found — citing the page, or the inferred type. Ask *"why is this
221
+ flagged?"*, *"how does narrowing work?"*, *"how is it different from
222
+ Sorbet?"*, *"does it handle Sidekiq?"*, or *"how do I type this
223
+ method?"* — you only have to remember the question, never the command.
224
+ To browse the docs yourself:
225
+
226
+ ```sh
227
+ rigor docs # the offline doc index
228
+ rigor docs handbook/03-narrowing # any handbook or manual page by name
229
+ rigor docs --list # list every bundled page
230
+ ```
231
+
205
232
  ## Status
206
233
 
207
- Current release: **`v0.1.18`** (2026-06-11), with `v0.2.0` — the first
208
- evaluation release landing shortly. Rigor analyses real Ruby today:
209
- the `0.1.x` line has been hardened against Mastodon, Redmine, and
210
- GitLab FOSS, and the deliberately conservative rule catalogue grows
211
- only as fast as the zero-false-positive bar allows. Release history:
212
- [`CHANGELOG.md`](CHANGELOG.md) · forward-looking commitments:
234
+ Current release: **`v0.2.0`** (2026-06-17) — the first
235
+ publicly-announced (general / evaluation) release. It publishes an
236
+ enumerated [compatibility surface](docs/compatibility.md) as a
237
+ minor-non-break trial, rehearsing the contract that hard-freezes at
238
+ `v1.0.0`. Rigor analyses real Ruby today: it has been hardened against
239
+ Mastodon, Redmine, and GitLab FOSS, and the deliberately conservative
240
+ rule catalogue grows only as fast as the zero-false-positive bar
241
+ allows. Release history: [`CHANGELOG.md`](CHANGELOG.md) ·
242
+ forward-looking commitments:
213
243
  [Roadmap](https://rigor.typedduck.fail/reference/roadmap/).
214
244
 
215
245
  ## Contributing
@@ -221,3 +251,35 @@ contributors should read.
221
251
  ## License
222
252
 
223
253
  Mozilla Public License Version 2.0. See [`LICENSE`](LICENSE).
254
+
255
+ ## Sponsors
256
+
257
+ Rigor is built and maintained by one person, who has spent the better
258
+ part of the last month — nearly every spare hour of personal time — on
259
+ this project. Sustainable development depends on sustainable funding.
260
+
261
+ **The current monthly budget is well short of the $200 minimum needed
262
+ to keep this pace going; $600 or more would let me work on it
263
+ properly.** If Rigor is saving you time or catching real bugs, please
264
+ consider contributing:
265
+
266
+ - **GitHub Sponsors**: [github.com/sponsors/zonuexe](https://github.com/sponsors/zonuexe)
267
+ - **FANBOX** (credit-card / PayPal): [tadsan.fanbox.cc](https://tadsan.fanbox.cc/)
268
+
269
+ **For individuals** — any amount is welcome and genuinely appreciated.
270
+ Even a small recurring pledge (think of it as buying me one coffee a
271
+ month) makes a difference when it adds up across many users.
272
+
273
+ **For companies** using Rigor in production — please consider a
274
+ contribution that reflects the engineering hours Rigor is saving you.
275
+ A modest business sponsorship goes a long way toward keeping this
276
+ project alive and actively maintained.
277
+
278
+ **Sponsors at $50/month or more** are listed here with a banner.
279
+ *(This threshold will likely move to $100/month at some point — early
280
+ sponsors lock in the lower bar.)*
281
+
282
+ To the sponsors who have already contributed: **thank you sincerely.**
283
+ Your support makes the difference between a project that stalls and
284
+ one that ships.
285
+
@@ -0,0 +1,33 @@
1
+ # Rigor core overlay — supplemental core signatures.
2
+ #
3
+ # This directory holds Rigor-owned reopenings of Ruby core classes that
4
+ # add methods upstream `ruby/rbs` does not declare on a class but which
5
+ # every concrete value of that class answers at runtime. It is loaded
6
+ # LAST into the RBS environment (after core + stdlib + vendored gem
7
+ # sigs), so an upstream declaration always wins on conflict — these
8
+ # entries only fill genuine holes.
9
+ #
10
+ # Provenance: hand-authored against the documented CRuby behaviour, not
11
+ # extracted. Keep each addition justified by an observed false positive.
12
+ #
13
+ # --- Numeric coercion methods ---
14
+ #
15
+ # `ruby/rbs`'s `Numeric` declares only `to_c` and `to_int`; the three
16
+ # value-coercion selectors `to_f` / `to_i` / `to_r` are declared solely
17
+ # on the concrete subclasses (`Integer`, `Float`, `Rational`, `Complex`).
18
+ # But Rigor routinely *widens* an arithmetic chain to the abstract
19
+ # `Numeric` nominal — `Complex#abs -> Numeric`, or an overload join over
20
+ # `Integer | Float` — and the instant a widened value is asked for
21
+ # `.to_f`, dispatch misses and `call.undefined-method` fires on plain,
22
+ # correct arithmetic (observed four times across actionview's
23
+ # `date_helper`: `(distance_in_minutes.to_f / 60.0)`).
24
+ #
25
+ # Every concrete `Numeric` responds to all three, so the widening must
26
+ # not strip the capability. Returns mirror the concrete subclass
27
+ # signatures. `to_int` is already upstream and intentionally not
28
+ # duplicated here.
29
+ class Numeric
30
+ def to_f: () -> Float
31
+ def to_i: () -> Integer
32
+ def to_r: () -> Rational
33
+ end
@@ -0,0 +1,25 @@
1
+ # Rigor core overlay — supplemental core signatures.
2
+ #
3
+ # --- Pathname#expand_path ---
4
+ #
5
+ # Upstream `ruby/rbs` declares `Pathname#expand_path` as:
6
+ #
7
+ # def expand_path: (?String dir) -> Pathname
8
+ #
9
+ # But `Pathname#expand_path` delegates to `File.expand_path`, whose `dir`
10
+ # parameter is typed as `path` (= `string | _ToPath`). Passing a `Pathname`
11
+ # as the base directory is the idiomatic Bundler pattern:
12
+ #
13
+ # Pathname.new(path).expand_path(Bundler.root) # root → Pathname
14
+ #
15
+ # With the ADR-57 self-call adoption gate now resolving `Bundler.root` to
16
+ # `Pathname`, all five call sites in bundler.rb / bundler/source/git.rb fire
17
+ # `argument type mismatch at parameter 'dir'`. The upstream sig is simply
18
+ # under-typed: the runtime accepts any `to_path`-bearing object.
19
+ #
20
+ # The overlay widens `dir` to `String | Pathname`, matching the runtime
21
+ # delegation and the `File.expand_path` `path` alias used elsewhere in RBS.
22
+ class Pathname
23
+ def expand_path: (?String | Pathname dir) -> Pathname
24
+ | ...
25
+ end
@@ -0,0 +1,28 @@
1
+ # Rigor core overlay — supplemental core signatures.
2
+ #
3
+ # --- StringScanner#[] ---
4
+ #
5
+ # The pinned `rbs` gem (4.0.2) declares `StringScanner#[]` as only:
6
+ #
7
+ # def []: (Integer) -> String?
8
+ #
9
+ # But `StringScanner#[]` also accepts a capture-group *name* — a `String`
10
+ # or `Symbol` — and returns the named capture from the most recent match.
11
+ # Named-capture access (`scanner[:key]`) is the idiomatic form when the
12
+ # scan pattern uses named groups:
13
+ #
14
+ # scanner.skip(/(?<key>\w+)=/)
15
+ # scanner[:key] # => the captured String, or nil
16
+ #
17
+ # Newer `ruby/rbs` already widens the signature to
18
+ # `(Integer | String | Symbol) -> String?`; the pinned 4.0.2 gem lags.
19
+ # Without the wider overload, a named-capture access such as Mastodon's
20
+ # `scanner[:key]` false-fires `call.argument-type-mismatch` (the lone
21
+ # overload rejects a `Symbol`).
22
+ #
23
+ # The overlay supplies the runtime-accurate overload; drop it once the
24
+ # pinned `rbs` gem carries the wider signature.
25
+ class StringScanner
26
+ def []: (Integer | String | Symbol) -> String?
27
+ | ...
28
+ end