rigortype 0.3.9 → 0.4.0

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 (363) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/data/core_overlay/enumerable.rbs +51 -0
  4. data/data/core_overlay/enumerator.rbs +84 -0
  5. data/data/core_overlay/hash_rbs3.rbs +41 -0
  6. data/data/core_overlay/process.rbs +40 -0
  7. data/data/core_overlay/string_io.rbs +33 -0
  8. data/data/effects/core.yml +3 -3
  9. data/data/gem_overlay/activesupport/core_ext.rbs +127 -4
  10. data/docs/handbook/03-narrowing.md +95 -10
  11. data/docs/handbook/04-tuples-and-shapes.md +8 -6
  12. data/docs/handbook/07-rbs-and-extended.md +16 -11
  13. data/docs/handbook/10-sorbet.md +9 -10
  14. data/docs/handbook/11-sig-gen.md +454 -13
  15. data/docs/manual/02-cli-reference.md +63 -2
  16. data/docs/manual/03-configuration.md +7 -0
  17. data/docs/manual/04-diagnostics.md +4 -0
  18. data/docs/manual/07-plugins.md +1 -1
  19. data/docs/manual/10-mcp-server.md +3 -2
  20. data/docs/manual/16-rbs-extended-annotations.md +40 -7
  21. data/docs/manual/19-effect-labels.md +10 -0
  22. data/docs/manual/plugins/README.md +7 -0
  23. data/docs/manual/plugins/rigor-actioncable.md +8 -1
  24. data/docs/manual/plugins/rigor-actionmailer.md +7 -0
  25. data/docs/manual/plugins/rigor-actionpack.md +243 -0
  26. data/docs/manual/plugins/rigor-active-model-serializers.md +153 -0
  27. data/docs/manual/plugins/rigor-activejob.md +7 -0
  28. data/docs/manual/plugins/rigor-activerecord.md +110 -4
  29. data/docs/manual/plugins/rigor-activestorage.md +8 -1
  30. data/docs/manual/plugins/rigor-activesupport-core-ext.md +11 -5
  31. data/docs/manual/plugins/rigor-grape.md +106 -0
  32. data/docs/manual/plugins/rigor-graphql.md +23 -2
  33. data/docs/manual/plugins/rigor-pundit.md +8 -1
  34. data/docs/manual/plugins/rigor-rails-i18n.md +10 -5
  35. data/docs/manual/plugins/rigor-rails-routes.md +7 -0
  36. data/docs/manual/plugins/rigor-rbs-inline.md +212 -25
  37. data/docs/manual/plugins/rigor-sidekiq.md +8 -1
  38. data/docs/manual/plugins/rigor-sorbet.md +21 -5
  39. data/exe/rigor +19 -4
  40. data/lib/rigor/analysis/baseline.rb +1 -1
  41. data/lib/rigor/analysis/check_rules/declaration_sourced_guard.rb +167 -2
  42. data/lib/rigor/analysis/check_rules/lexical_method_sites.rb +189 -0
  43. data/lib/rigor/analysis/check_rules/main_pass_collector.rb +5 -3
  44. data/lib/rigor/analysis/check_rules/rule_ids.rb +20 -5
  45. data/lib/rigor/analysis/check_rules/rule_walk.rb +2 -1
  46. data/lib/rigor/analysis/check_rules/source_arity.rb +323 -0
  47. data/lib/rigor/analysis/check_rules/special_global_setters.rb +146 -0
  48. data/lib/rigor/analysis/check_rules/unreachable_clause_collector.rb +36 -2
  49. data/lib/rigor/analysis/check_rules.rb +520 -49
  50. data/lib/rigor/analysis/dependency_recorder.rb +23 -0
  51. data/lib/rigor/analysis/fact_store.rb +9 -0
  52. data/lib/rigor/analysis/incremental.rb +26 -0
  53. data/lib/rigor/analysis/incremental_session.rb +36 -4
  54. data/lib/rigor/analysis/project_scan.rb +11 -1
  55. data/lib/rigor/analysis/reachability/plugin_roots.rb +0 -1
  56. data/lib/rigor/analysis/reachability/scan_cache.rb +1 -0
  57. data/lib/rigor/analysis/rule_catalog.rb +127 -0
  58. data/lib/rigor/analysis/run_cache_key.rb +20 -11
  59. data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +167 -11
  60. data/lib/rigor/analysis/runner/effect_envelope_pass.rb +9 -4
  61. data/lib/rigor/analysis/runner/pool_coordinator.rb +107 -15
  62. data/lib/rigor/analysis/runner/project_pre_passes.rb +26 -7
  63. data/lib/rigor/analysis/runner.rb +278 -20
  64. data/lib/rigor/analysis/template_unit_collector.rb +303 -0
  65. data/lib/rigor/analysis/template_unit_paths.rb +91 -0
  66. data/lib/rigor/analysis/template_unit_positions.rb +293 -0
  67. data/lib/rigor/analysis/template_units.rb +399 -0
  68. data/lib/rigor/analysis/worker_session.rb +53 -10
  69. data/lib/rigor/bleeding_edge.rb +0 -2
  70. data/lib/rigor/builtins/hkt_builtins.rb +1 -0
  71. data/lib/rigor/builtins/imported_refinements.rb +4 -0
  72. data/lib/rigor/builtins/regex_refinement.rb +17 -9
  73. data/lib/rigor/builtins/static_return_refinements.rb +2 -0
  74. data/lib/rigor/cache/descriptor.rb +6 -1
  75. data/lib/rigor/cache/engine_source.rb +29 -1
  76. data/lib/rigor/cache/incremental_snapshot.rb +33 -1
  77. data/lib/rigor/cache/rbs_cache_producer.rb +4 -0
  78. data/lib/rigor/cache/rbs_descriptor.rb +37 -7
  79. data/lib/rigor/cache/store.rb +0 -1
  80. data/lib/rigor/ci_detector.rb +1 -0
  81. data/lib/rigor/cli/doc_links.rb +1 -1
  82. data/lib/rigor/cli/docs_command.rb +4 -4
  83. data/lib/rigor/cli/plugin_command.rb +3 -3
  84. data/lib/rigor/cli/prism_colorizer.rb +0 -1
  85. data/lib/rigor/cli/sig_gen_command.rb +210 -29
  86. data/lib/rigor/cli/skill_command.rb +1 -1
  87. data/lib/rigor/cli/skill_describe.rb +0 -1
  88. data/lib/rigor/cli/type_of_command.rb +19 -5
  89. data/lib/rigor/cli/type_of_renderer.rb +20 -9
  90. data/lib/rigor/cli/type_of_template_probe.rb +189 -0
  91. data/lib/rigor/cli.rb +21 -3
  92. data/lib/rigor/configuration/severity_profile.rb +19 -3
  93. data/lib/rigor/configuration.rb +66 -3
  94. data/lib/rigor/effects/ancestry_recorder.rb +191 -0
  95. data/lib/rigor/effects/attribution.rb +11 -2
  96. data/lib/rigor/effects/callee_rule.rb +368 -0
  97. data/lib/rigor/effects/catalog.rb +7 -4
  98. data/lib/rigor/effects/collector.rb +11 -5
  99. data/lib/rigor/effects/config_envelopes.rb +9 -2
  100. data/lib/rigor/effects/definition_context.rb +179 -0
  101. data/lib/rigor/effects/effect_table.rb +11 -3
  102. data/lib/rigor/effects/envelope_check.rb +1 -1
  103. data/lib/rigor/effects/envelope_index.rb +15 -0
  104. data/lib/rigor/effects/file_collection.rb +59 -5
  105. data/lib/rigor/effects/framework_units.rb +1 -1
  106. data/lib/rigor/effects/identity.rb +16 -0
  107. data/lib/rigor/effects/local_ownership.rb +38 -12
  108. data/lib/rigor/effects/method_key.rb +21 -0
  109. data/lib/rigor/effects/mutation_classifier.rb +23 -12
  110. data/lib/rigor/effects/plugin_facts.rb +43 -31
  111. data/lib/rigor/effects/propagator.rb +295 -16
  112. data/lib/rigor/effects/registry.rb +1 -1
  113. data/lib/rigor/effects/scanner.rb +121 -72
  114. data/lib/rigor/effects/signature_sources.rb +1 -1
  115. data/lib/rigor/effects/snapshot.rb +2 -1
  116. data/lib/rigor/effects/summary.rb +27 -4
  117. data/lib/rigor/effects/unit_scan.rb +385 -30
  118. data/lib/rigor/effects/visibility.rb +101 -0
  119. data/lib/rigor/environment/lockfile_resolver.rb +17 -0
  120. data/lib/rigor/environment/member_consistency/comparator.rb +708 -0
  121. data/lib/rigor/environment/member_consistency.rb +298 -0
  122. data/lib/rigor/environment/rbs_loader.rb +399 -133
  123. data/lib/rigor/environment.rb +103 -38
  124. data/lib/rigor/hashing/xxh3.rb +264 -0
  125. data/lib/rigor/inference/acceptance.rb +139 -9
  126. data/lib/rigor/inference/block_auto_splat.rb +216 -0
  127. data/lib/rigor/inference/block_call_timing.rb +338 -0
  128. data/lib/rigor/inference/block_parameter_binder.rb +73 -27
  129. data/lib/rigor/inference/block_repetition.rb +71 -0
  130. data/lib/rigor/inference/body_fixpoint.rb +2 -1
  131. data/lib/rigor/inference/budget_trace.rb +2 -1
  132. data/lib/rigor/inference/builtins/method_catalog.rb +2 -1
  133. data/lib/rigor/inference/builtins/string_catalog.rb +1 -1
  134. data/lib/rigor/inference/captured_locals.rb +387 -15
  135. data/lib/rigor/inference/closure_escape_analyzer.rb +157 -13
  136. data/lib/rigor/inference/content_join.rb +200 -27
  137. data/lib/rigor/inference/def_return_typer.rb +11 -7
  138. data/lib/rigor/inference/define_method_block_self.rb +64 -0
  139. data/lib/rigor/inference/element_read_widening.rb +22 -10
  140. data/lib/rigor/inference/error_info.rb +196 -0
  141. data/lib/rigor/inference/expression_typer.rb +1532 -496
  142. data/lib/rigor/inference/external_ancestor_resolution.rb +267 -0
  143. data/lib/rigor/inference/fresh_frame_blocks.rb +127 -0
  144. data/lib/rigor/inference/global_write_census.rb +239 -0
  145. data/lib/rigor/inference/guard_rebinding.rb +447 -0
  146. data/lib/rigor/inference/hash_lookup_mutation.rb +88 -0
  147. data/lib/rigor/inference/index_write_widening.rb +16 -3
  148. data/lib/rigor/inference/indexed_narrowing.rb +61 -9
  149. data/lib/rigor/inference/jump_targets.rb +82 -0
  150. data/lib/rigor/inference/last_line/implicit_self.rb +210 -0
  151. data/lib/rigor/inference/last_line/self_evidence.rb +329 -0
  152. data/lib/rigor/inference/last_line.rb +340 -0
  153. data/lib/rigor/inference/last_status.rb +144 -0
  154. data/lib/rigor/inference/macro_block_self_type.rb +167 -17
  155. data/lib/rigor/inference/match_rebinding/calls.rb +281 -0
  156. data/lib/rigor/inference/match_rebinding/frame.rb +148 -0
  157. data/lib/rigor/inference/match_rebinding/operands.rb +236 -0
  158. data/lib/rigor/inference/match_rebinding/self_calls.rb +83 -0
  159. data/lib/rigor/inference/match_rebinding.rb +392 -0
  160. data/lib/rigor/inference/method_dispatcher/alias_strict_nominals.rb +36 -0
  161. data/lib/rigor/inference/method_dispatcher/block_folding.rb +85 -24
  162. data/lib/rigor/inference/method_dispatcher/facet_distribution.rb +147 -0
  163. data/lib/rigor/inference/method_dispatcher/hash_transform_keys_folding.rb +191 -0
  164. data/lib/rigor/inference/method_dispatcher/iterator_dispatch.rb +4 -0
  165. data/lib/rigor/inference/method_dispatcher/match_data_folding.rb +159 -0
  166. data/lib/rigor/inference/method_dispatcher/overload_selector.rb +113 -73
  167. data/lib/rigor/inference/method_dispatcher/process_folding.rb +56 -0
  168. data/lib/rigor/inference/method_dispatcher/proven_overload.rb +72 -0
  169. data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +881 -38
  170. data/lib/rigor/inference/method_dispatcher/self_substitute.rb +142 -0
  171. data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +128 -53
  172. data/lib/rigor/inference/method_dispatcher/struct_folding.rb +1 -1
  173. data/lib/rigor/inference/method_dispatcher.rb +214 -13
  174. data/lib/rigor/inference/method_parameter_binder.rb +8 -3
  175. data/lib/rigor/inference/multi_target_binder.rb +340 -52
  176. data/lib/rigor/inference/mutation_rejoin.rb +4 -1
  177. data/lib/rigor/inference/mutation_widening.rb +70 -48
  178. data/lib/rigor/inference/narrowing.rb +540 -120
  179. data/lib/rigor/inference/operand_effects.rb +167 -0
  180. data/lib/rigor/inference/operand_walk.rb +88 -0
  181. data/lib/rigor/inference/optimistic_origin.rb +152 -9
  182. data/lib/rigor/inference/parameter_inference_collector.rb +3 -2
  183. data/lib/rigor/inference/project_method_ownership.rb +136 -0
  184. data/lib/rigor/inference/project_patched_methods.rb +7 -2
  185. data/lib/rigor/inference/project_patched_scanner.rb +7 -3
  186. data/lib/rigor/inference/receiver_alias.rb +90 -1
  187. data/lib/rigor/inference/receiver_blind_block.rb +219 -0
  188. data/lib/rigor/inference/refinement_mutation.rb +15 -11
  189. data/lib/rigor/inference/repeated_or_writes.rb +463 -0
  190. data/lib/rigor/inference/return_barrier.rb +54 -0
  191. data/lib/rigor/inference/rewrite_mutation.rb +120 -0
  192. data/lib/rigor/inference/scope_indexer.rb +4615 -551
  193. data/lib/rigor/inference/statement_evaluator.rb +3176 -490
  194. data/lib/rigor/inference/stored_block_call.rb +54 -0
  195. data/lib/rigor/inference/string_mutation.rb +44 -7
  196. data/lib/rigor/inference/unknown_store_widening.rb +200 -0
  197. data/lib/rigor/inference/unthreaded_rebinds.rb +282 -0
  198. data/lib/rigor/language_server/debouncer.rb +0 -1
  199. data/lib/rigor/language_server/diagnostic_publisher.rb +3 -2
  200. data/lib/rigor/language_server/hover_renderer.rb +3 -3
  201. data/lib/rigor/language_server/project_context.rb +5 -3
  202. data/lib/rigor/mcp/server.rb +2 -1
  203. data/lib/rigor/plugin/base.rb +168 -5
  204. data/lib/rigor/plugin/box_probe.rb +91 -0
  205. data/lib/rigor/plugin/bundled_catalog.rb +1 -1
  206. data/lib/rigor/plugin/effect_attribution.rb +58 -4
  207. data/lib/rigor/plugin/loader.rb +2 -1
  208. data/lib/rigor/plugin/macro/block_as_method.rb +45 -6
  209. data/lib/rigor/plugin/manifest.rb +71 -10
  210. data/lib/rigor/plugin/registry.rb +35 -1
  211. data/lib/rigor/plugin/source_rbs_synthesis_reporter.rb +9 -3
  212. data/lib/rigor/plugin/template_unit.rb +196 -0
  213. data/lib/rigor/plugin.rb +1 -0
  214. data/lib/rigor/protection/discovery_seed.rb +3 -1
  215. data/lib/rigor/protection/kill_signature.rb +0 -1
  216. data/lib/rigor/protection/mutation_cache.rb +1 -2
  217. data/lib/rigor/rbs_extended.rb +27 -0
  218. data/lib/rigor/reflection/constant_ancestors.rb +97 -0
  219. data/lib/rigor/reflection/constant_path.rb +19 -6
  220. data/lib/rigor/reflection.rb +72 -105
  221. data/lib/rigor/scope/discovery_index.rb +135 -2
  222. data/lib/rigor/scope.rb +859 -49
  223. data/lib/rigor/sig_gen/alias_index.rb +289 -0
  224. data/lib/rigor/sig_gen/classification.rb +22 -5
  225. data/lib/rigor/sig_gen/declaration_equivalence.rb +127 -0
  226. data/lib/rigor/sig_gen/effect_annotation.rb +202 -0
  227. data/lib/rigor/sig_gen/generator.rb +558 -31
  228. data/lib/rigor/sig_gen/inline_declarations.rb +184 -0
  229. data/lib/rigor/sig_gen/method_candidate.rb +47 -3
  230. data/lib/rigor/sig_gen/observation_collector.rb +1 -1
  231. data/lib/rigor/sig_gen/renderer.rb +124 -9
  232. data/lib/rigor/sig_gen/skip_reason_catalog.rb +44 -1
  233. data/lib/rigor/sig_gen/write_result.rb +19 -3
  234. data/lib/rigor/sig_gen/writer.rb +166 -35
  235. data/lib/rigor/sig_gen.rb +3 -0
  236. data/lib/rigor/signature_path_audit.rb +1 -1
  237. data/lib/rigor/source/node_walker.rb +0 -3
  238. data/lib/rigor/source/parameter_envelope.rb +72 -0
  239. data/lib/rigor/source.rb +1 -0
  240. data/lib/rigor/type/combinator.rb +88 -12
  241. data/lib/rigor/type/difference.rb +1 -0
  242. data/lib/rigor/type/hash_shape.rb +1 -1
  243. data/lib/rigor/type/refined.rb +1 -0
  244. data/lib/rigor/version.rb +1 -1
  245. data/lib/rigor.rb +1 -0
  246. data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/effects.rb +1 -0
  247. data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +9 -5
  248. data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb +13 -4
  249. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb +0 -1
  250. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_scan.rb +96 -0
  251. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/effects.rb +65 -8
  252. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/erb_compiler.rb +270 -0
  253. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/render_locals.rb +402 -0
  254. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/view_assigns.rb +370 -0
  255. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/view_units.rb +132 -0
  256. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +239 -4
  257. data/plugins/rigor-actionpack/sig/action_view.rbs +43 -0
  258. data/plugins/rigor-active-model-serializers/lib/rigor/plugin/active_model_serializers/serializer_discoverer.rb +220 -0
  259. data/plugins/rigor-active-model-serializers/lib/rigor/plugin/active_model_serializers/serializer_index.rb +56 -0
  260. data/plugins/rigor-active-model-serializers/lib/rigor/plugin/active_model_serializers.rb +263 -0
  261. data/plugins/rigor-active-model-serializers/lib/rigor-active-model-serializers.rb +7 -0
  262. data/plugins/rigor-active-model-serializers/sig/active_model_serializers.rbs +45 -0
  263. data/plugins/rigor-activejob/lib/rigor/plugin/activejob/effects.rb +1 -0
  264. data/plugins/rigor-activejob/lib/rigor/plugin/activejob.rb +9 -5
  265. data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/analyzer.rb +35 -3
  266. data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/effects.rb +72 -12
  267. data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +380 -3
  268. data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_index.rb +14 -6
  269. data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +281 -35
  270. data/plugins/rigor-activerecord/sig/active_record/relation.rbs +206 -31
  271. data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +25 -14
  272. data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext/effects.rb +9 -2
  273. data/plugins/rigor-activesupport-core-ext/sig/active_support/core_ext.rbs +171 -5
  274. data/plugins/rigor-dry-monads/lib/rigor/plugin/dry_monads.rb +2 -0
  275. data/plugins/rigor-ethon/lib/rigor/plugin/ethon.rb +1 -0
  276. data/plugins/rigor-ffi/lib/rigor/plugin/ffi/types.rb +1 -1
  277. data/plugins/rigor-grape/lib/rigor/plugin/grape.rb +141 -0
  278. data/plugins/rigor-grape/lib/rigor-grape.rb +6 -0
  279. data/plugins/rigor-grape/sig/grape.rbs +263 -0
  280. data/plugins/rigor-graphql/lib/rigor/plugin/graphql.rb +72 -2
  281. data/plugins/rigor-graphql/sig/graphql.rbs +485 -0
  282. data/plugins/rigor-minitest/lib/rigor/plugin/minitest/assertion_analyzer.rb +2 -0
  283. data/plugins/rigor-pundit/lib/rigor/plugin/pundit.rb +11 -7
  284. data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n.rb +35 -37
  285. data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/analyzer.rb +0 -1
  286. data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/devise_routes.rb +2 -0
  287. data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/doorkeeper_routes.rb +1 -0
  288. data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +9 -17
  289. data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline/same_line_annotations.rb +149 -0
  290. data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb +217 -36
  291. data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/schedule_scan.rb +1 -0
  292. data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq.rb +9 -5
  293. data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sigil_detector.rb +0 -1
  294. data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +46 -1
  295. data/plugins/rigor-sorbet/sig/sorbet.rbs +277 -0
  296. data/sig/rigor/analysis/baseline.rbs +69 -7
  297. data/sig/rigor/analysis/fact_store.rbs +1 -1
  298. data/sig/rigor/analysis/project_scan.rbs +74 -0
  299. data/sig/rigor/effects/config_envelopes.rbs +100 -0
  300. data/sig/rigor/effects/effect_table.rbs +60 -0
  301. data/sig/rigor/effects/envelope.rbs +97 -0
  302. data/sig/rigor/effects/envelope_index.rbs +33 -0
  303. data/sig/rigor/effects/file_collection.rbs +81 -0
  304. data/sig/rigor/effects/label.rbs +26 -0
  305. data/sig/rigor/effects/label_set.rbs +46 -0
  306. data/sig/rigor/effects/method_key.rbs +24 -0
  307. data/sig/rigor/effects/origin.rbs +50 -0
  308. data/sig/rigor/effects/plugin_facts.rbs +141 -0
  309. data/sig/rigor/effects/registry.rbs +68 -0
  310. data/sig/rigor/effects/summary.rbs +50 -0
  311. data/sig/rigor/effects/taint_cause.rbs +12 -0
  312. data/sig/rigor/environment.rbs +12 -10
  313. data/sig/rigor/inference/optimistic_origin.rbs +10 -0
  314. data/sig/rigor/inference.rbs +6 -4
  315. data/sig/rigor/plugin/additional_initializer.rbs +36 -0
  316. data/sig/rigor/plugin/base.rbs +30 -7
  317. data/sig/rigor/plugin/effect_ancestry.rbs +27 -0
  318. data/sig/rigor/plugin/effect_attribution.rbs +66 -0
  319. data/sig/rigor/plugin/effect_edge.rbs +33 -0
  320. data/sig/rigor/plugin/effect_entry_points.rbs +25 -0
  321. data/sig/rigor/plugin/io_boundary.rbs +1 -1
  322. data/sig/rigor/plugin/loader.rbs +3 -3
  323. data/sig/rigor/plugin/manifest.rbs +50 -11
  324. data/sig/rigor/plugin/protocol_contract.rbs +68 -0
  325. data/sig/rigor/plugin/registry.rbs +62 -1
  326. data/sig/rigor/plugin.rbs +1 -1
  327. data/sig/rigor/rbs_extended.rbs +1 -1
  328. data/sig/rigor/reflection.rbs +7 -6
  329. data/sig/rigor/scope.rbs +135 -20
  330. data/sig/rigor/sig_gen/skip_reason_catalog.rbs +14 -7
  331. data/sig/rigor/source.rbs +4 -4
  332. data/sig/rigor/testing.rbs +10 -4
  333. data/sig/rigor/type.rbs +6 -0
  334. data/sig/rigor.rbs +38 -20
  335. data/skills/rigor-ask/SKILL.md +8 -5
  336. data/skills/rigor-baseline-reduce/SKILL.md +4 -6
  337. data/skills/rigor-ci-setup/SKILL.md +17 -21
  338. data/skills/rigor-doctor/SKILL.md +24 -22
  339. data/skills/rigor-doctor/references/01-checks.md +97 -33
  340. data/skills/rigor-editor-setup/SKILL.md +6 -4
  341. data/skills/rigor-mcp-setup/SKILL.md +5 -4
  342. data/skills/rigor-monkeypatch-resolve/SKILL.md +5 -3
  343. data/skills/rigor-next-steps/SKILL.md +4 -2
  344. data/skills/rigor-plugin-author/SKILL.md +19 -23
  345. data/skills/rigor-plugin-author/references/01-plan-and-scaffold.md +9 -8
  346. data/skills/rigor-plugin-author/references/02-walker-and-types.md +12 -25
  347. data/skills/rigor-plugin-author/references/03-test-and-ship.md +6 -8
  348. data/skills/rigor-plugin-review/SKILL.md +6 -4
  349. data/skills/rigor-plugin-review/references/01-best-practices-checklist.md +2 -1
  350. data/skills/rigor-plugin-tune/SKILL.md +4 -2
  351. data/skills/rigor-project-init/SKILL.md +9 -7
  352. data/skills/rigor-project-init/references/01-detect.md +13 -9
  353. data/skills/rigor-project-init/references/02-configure.md +33 -8
  354. data/skills/rigor-project-init/references/03-baseline-and-bugs.md +14 -14
  355. data/skills/rigor-project-init/references/04-sig-uplift.md +27 -14
  356. data/skills/rigor-protection-uplift/SKILL.md +4 -6
  357. data/skills/rigor-rbs-setup/SKILL.md +4 -2
  358. data/skills/rigor-type-oracle/SKILL.md +4 -6
  359. data/skills/rigor-type-oracle/references/01-oracle-commands.md +12 -8
  360. data/skills/rigor-type-oracle/references/03-gap-protocol.md +0 -3
  361. data/skills/rigor-unused-adjudicate/SKILL.md +4 -2
  362. data/skills/rigor-upgrade/SKILL.md +13 -8
  363. metadata +108 -1
@@ -1,7 +1,9 @@
1
1
  ---
2
2
  name: rigor-ci-setup
3
- description: |
4
- Wire Rigor type-checking into a project's CI pipeline: run it in its own isolated Ruby-4.0 job and surface diagnostics inline on the pull / merge request via a CI-native output format (SARIF, GitHub Actions annotations, GitLab Code Quality, Checkstyle, JUnit) or through reviewdog. Triggers: "add Rigor to CI", "run rigor in GitHub Actions / GitLab CI", "show Rigor errors on the PR", "set up reviewdog for rigor". NOT for first-time project configuration (use rigor-project-init to create `.rigor.yml` first) or reducing a baseline (use rigor-baseline-reduce).
3
+ description: >-
4
+ Set up Rigor in a project's CI and surface diagnostics on pull or merge requests. Use when adding or
5
+ changing GitHub Actions, GitLab CI, SARIF, or reviewdog wiring; not for first-time Rigor configuration
6
+ or baseline reduction.
5
7
  license: MPL-2.0
6
8
  metadata:
7
9
  version: 0.1.0
@@ -31,7 +33,6 @@ Rigor is installed:
31
33
  ```sh
32
34
  rigor skill --full rigor-ci-setup # this skill's current workflow, in one call
33
35
  rigor docs ci # the manual's CI chapter — the actual templates
34
- rigor docs --list manual | grep ci-templates # ready-to-copy template files
35
36
  ```
36
37
 
37
38
  If you already loaded this skill *via* `rigor skill` you have the current
@@ -61,7 +62,7 @@ these markers from the project root and let them drive the platform choice:
61
62
  | `bitbucket-pipelines.yml` / `azure-pipelines.yml` / `.drone.yml` | that platform (generic recipe) |
62
63
  | none of the above | no CI yet — **ask** the user which platform they use |
63
64
 
64
- Concretely (the agent has file tools — use them):
65
+ Concretely:
65
66
 
66
67
  - List `.github/workflows/*.yml` and `.gitlab-ci.yml`. **If
67
68
  `.github/workflows/rigor.yml` already exists, read it** — this is an
@@ -108,10 +109,8 @@ this is the *decision*:
108
109
  ## Phase 2 — Apply the matching template
109
110
 
110
111
  Take the template for your (platform, surface) choice from `rigor docs ci`
111
- — or copy a ready file listed by `rigor docs --list manual | grep
112
- ci-templates` (GitHub annotations / SARIF / reviewdog, and GitLab). Copy it
113
- in, adjust nothing but the trigger unless asked, and pin the version next
114
- (Phase 3).
112
+ (GitHub annotations / SARIF / reviewdog, and GitLab). Copy it in, adjust
113
+ nothing but the trigger unless asked, and pin the version next (Phase 3).
115
114
 
116
115
  **reviewdog is platform-specific.** It reads Rigor's `checkstyle`
117
116
  (preferred — light, no code scanning) or `sarif`, but the `-reporter` must
@@ -142,14 +141,11 @@ The exact recipe (the `BUNDLE_GEMFILE` wiring, the Dependabot entry) is in
142
141
  - **Determinism.** Add `--no-cache` in CI if you want each run independent
143
142
  of any persisted `.rigor/cache`.
144
143
  - **Cache persistence (opposite trade).** When the Rigor job's runtime
145
- matters, persist `.rigor/cache` with the CI's cache facility. Current
146
- Rigor detects CI and validates the restored cache by content hash
147
- automatically (`cache.validation: auto`); on versions before the
148
- `auto` default, **also set `RIGOR_STRICT_VALIDATION=1` on the job** —
149
- without it a fresh checkout's regenerated stat tuples make the plugin
150
- watch-glob cache slots read as stale on every run. A self-hosted
151
- runner that reuses its workspace opts back into the faster stat check
152
- with `cache.validation: stat`. Snippets: `rigor docs ci`
144
+ matters, persist `.rigor/cache` with the CI's cache facility. Rigor
145
+ detects CI and validates the restored cache by content hash
146
+ automatically (`cache.validation: auto`). A self-hosted runner that
147
+ reuses its workspace opts back into the faster stat check with
148
+ `cache.validation: stat`. Snippets: `rigor docs ci`
153
149
  § "Persisting the analysis cache across runs".
154
150
 
155
151
  ## Verify
@@ -165,12 +161,12 @@ The exact recipe (the `BUNDLE_GEMFILE` wiring, the Dependabot entry) is in
165
161
 
166
162
  - Manual: `rigor`'s CI chapter — the authoritative templates, severity
167
163
  mapping, and pinning recipe, **offline and version-matched** with
168
- `rigor docs ci` (ready files: `rigor docs --list manual | grep
169
- ci-templates`). Web fallback, before Rigor is installed:
170
- <https://github.com/rigortype/rigor/blob/master/docs/manual/11-ci.md>.
171
- - [ADR-51](../../docs/adr/51-ci-diagnostic-output-formats.md)
164
+ `rigor docs ci`. Web fallback, before Rigor is installed:
165
+ <https://github.com/rigortype/rigor/blob/master/docs/manual/11-ci.md>
166
+ (ready-to-copy files in `docs/manual/ci-templates/` beside it).
167
+ - [ADR-51](https://github.com/rigortype/rigor/blob/master/docs/adr/51-ci-diagnostic-output-formats.md)
172
168
  — the output-format surface (the severity / identifier contract).
173
- - [ADR-27](../../docs/adr/27-tool-distribution-model.md)
169
+ - [ADR-27](https://github.com/rigortype/rigor/blob/master/docs/adr/27-tool-distribution-model.md)
174
170
  — why Rigor installs standalone and runs in its own job.
175
171
  - [reviewdog](https://github.com/reviewdog/reviewdog) /
176
172
  [action-setup](https://github.com/reviewdog/action-setup).
@@ -1,7 +1,9 @@
1
1
  ---
2
2
  name: rigor-doctor
3
- description: |
4
- Validate that a project's Rigor setup is actually healthy — config parses with no silently-inert values, every configured plugin loads, the baseline is not stale, and the bundled paths resolve — by running Rigor's existing validators and interpreting them. Triggers: "is my Rigor setup correct?", "check my rigor config", "rigor diagnostics look wrong / suspicious", "validate rigor setup", "why is rigor reporting nothing / everything?". NOT for first-time setup (use rigor-project-init) or for working real diagnostics down (use rigor-baseline-reduce).
3
+ description: >-
4
+ Validate that a project's Rigor configuration, plugins, paths, and baseline are actually healthy. Use
5
+ when diagnostics are suspicious or setup behavior is wrong; not for first-time onboarding or reducing
6
+ ordinary diagnostics.
5
7
  license: MPL-2.0
6
8
  metadata:
7
9
  version: 0.1.0
@@ -11,12 +13,13 @@ metadata:
11
13
  # Rigor Doctor
12
14
 
13
15
  `rigor skill describe` reports what *exists* (presence checks). This skill
14
- goes a level deeper: it *runs* Rigor's own validators to confirm the setup
15
- is actually working — the difference between "a `.rigor.yml` is present"
16
- and "it parses, loads its plugins, and analyses the right files." Reach for
17
- it when the diagnostics look wrong (suspiciously zero, or suspiciously
18
- many) or after editing the config. It needs no special command — it
19
- orchestrates checks Rigor already ships and interprets the results.
16
+ goes a level deeper: `rigor doctor` *runs* Rigor's own setup validators
17
+ (config audit, RBS environment, plugin loading, baseline drift, plugin
18
+ gaps, install layout) and this skill interprets the result — the
19
+ difference between "a `.rigor.yml` is present" and "it parses, loads its
20
+ plugins, and analyses the right files." Reach for it when the diagnostics
21
+ look wrong (suspiciously zero, or suspiciously many) or after editing the
22
+ config.
20
23
 
21
24
  ## First: load the version-current copy
22
25
 
@@ -44,25 +47,24 @@ header names). If `rigor` is not on `PATH`, this task needs it: run
44
47
 
45
48
  ## What it validates
46
49
 
47
- Four validators, each a check Rigor already ships. The exact commands and
48
- how to read each output live in the version-current
50
+ `rigor doctor` runs the setup checks in one pass (`--format json` gives
51
+ each finding's `checks[].id` and `status`) and exits non-zero when any
52
+ check fails. It does not check whether the analysis sees the right
53
+ files; that is a separate look at `stats.target_files` in
54
+ `rigor check --format json`. What each check id means and how to act on
55
+ it live in the version-current
49
56
  [`references/01-checks.md`](references/01-checks.md) (loaded per the
50
- directive above):
51
-
52
- 1. **Config resolves with nothing silently inert** — no `config_warnings`.
53
- 2. **Every configured plugin loads** — `rigor plugins --strict` is clean.
54
- 3. **The baseline is not stale** (if one exists) — no large drift.
55
- 4. **The analysis is actually seeing your code** — the source-file count
56
- matches the project.
57
+ directive above).
57
58
 
58
59
  ## Interpreting the result
59
60
 
60
- - **All clean** → the setup is healthy; any diagnostics are about the
61
- code, not the configuration. Move on to `rigor-baseline-reduce` or
61
+ - **All clean** (no `fail` or `warn` finding, and the file count matches
62
+ the project) → the setup is healthy; any diagnostics are about the code,
63
+ not the configuration. Move on to `rigor-baseline-reduce` or
62
64
  `rigor-protection-uplift`.
63
- - **A `config_warning` or a plugin failure** → that is the real problem;
64
- fixing it usually clears a whole cluster of confusing downstream
65
- diagnostics at once.
65
+ - **A `config_audit`, `rbs_environment`, or `plugins` failure** → that is
66
+ the real problem; fixing it usually clears a whole cluster of confusing
67
+ downstream diagnostics at once.
66
68
 
67
69
  For deeper symptoms (hover shows `untyped` everywhere, completion empty,
68
70
  LSP silent) read the manual's troubleshooting chapter — offline and
@@ -1,52 +1,116 @@
1
- # 01 — The four checks
1
+ # 01 — The checks
2
2
 
3
- Each check runs a validator Rigor already ships and interprets its
4
- output. Run them in order; the first failure is usually the root cause of
5
- a cluster of confusing downstream diagnostics.
6
-
7
- ## 1. Config resolves with nothing silently inert
3
+ ## Run `rigor doctor`
8
4
 
9
5
  ```sh
10
- rigor check --format json # read the `config_warnings` array
6
+ rigor doctor # human-readable: [FAIL] / [WARN] / [PASS] lines
7
+ rigor doctor --format json # machine-readable
11
8
  ```
12
9
 
13
- `rigor check` audits the config and emits `config_warnings` for the typo
14
- class whose only symptom is a confusing downstream error: a
15
- `signature_paths:` that is missing / not a directory / holds no `.rbs`
16
- (which would turn every covered call into a false `call.undefined-method`
17
- at `evidence_tier: high`), a `libraries:` name RBS does not recognise, a
18
- `disable:` / `severity_overrides:` id naming no real rule, or a missing
19
- `bundler` / `rbs_collection` path. **Each warning here is a real
20
- misconfiguration — fix it.** None appearing is the healthy state.
21
-
22
- ## 2. Every configured plugin loads
10
+ It runs one scoped analysis, audits the config, loads the plugins, and
11
+ checks baseline drift in a single pass, then prints a finding per
12
+ problem with a hint. The JSON shape:
23
13
 
24
- ```sh
25
- rigor plugins --strict
14
+ ```json
15
+ { "status": "issues_found",
16
+ "checks": [ { "id": "plugins", "status": "fail",
17
+ "message": "Plugin load errors: 1",
18
+ "hint": "Run `rigor plugins --strict` for the full per-plugin report." } ] }
26
19
  ```
27
20
 
28
- Reports the activation status of each plugin in `plugins:`; `--strict`
29
- exits non-zero on any failure. A failure is usually a misspelled id or a
21
+ - Top-level `status` is `issues_found` when any check has `status: "fail"`,
22
+ otherwise `clean` — a run with only `warn` findings still reads `clean`,
23
+ so read the `checks` array too.
24
+ - `checks[].status` is `fail`, `warn`, or `pass`. A check with nothing to
25
+ report is usually **absent**, not `pass`; only `rbs_environment` reports
26
+ a `pass` line.
27
+ - The command exits non-zero when any check fails.
28
+
29
+ Fix `fail` findings first, in the order below: an early failure is usually
30
+ the root cause of a cluster of confusing downstream diagnostics.
31
+
32
+ ## The check ids
33
+
34
+ ### `config_audit` — config resolves with nothing silently inert
35
+
36
+ `fail` with a count of configuration warnings. Doctor gives only the
37
+ count; the individual warnings are in `rigor check --format json` under
38
+ `config_warnings`. They cover the typo class whose only symptom is a
39
+ confusing downstream error: a `signature_paths:` that is missing / not a
40
+ directory / holds no `.rbs` (which would turn every covered call into a
41
+ false `call.undefined-method` at `evidence_tier: high`), a `libraries:`
42
+ name RBS does not recognise, a `disable:` / `severity_overrides:` id
43
+ naming no real rule, or a missing `bundler` / `rbs_collection` path.
44
+ **Each warning is a real misconfiguration — fix it.**
45
+
46
+ ### `rbs_environment` — the type universe loaded
47
+
48
+ - `fail` — the RBS environment is empty (zero classes). It failed to build
49
+ or loaded no signatures: look for duplicate declarations across
50
+ `signature_paths:`, or run `rbs collection install` for gem signatures.
51
+ - `warn` — degraded: one or more `signature_paths:` files did not parse
52
+ and were skipped. The run is quieter, not cleaner — the types those
53
+ files declare are gone. Run `rbs validate` on the `sig/` set and fix
54
+ the parse error.
55
+ - `pass` — healthy, with the class count.
56
+
57
+ ### `plugins` — every configured plugin loads
58
+
59
+ `fail` with a count of plugin load errors. Run `rigor plugins --strict`
60
+ for the per-plugin report. A failure is usually a misspelled id or a
30
61
  plugin whose `signature_paths:` did not resolve. Fix it, or the plugin's
31
62
  type knowledge is silently absent.
32
63
 
33
- ## 3. The baseline is not stale (if one exists)
64
+ ### `plugin_skew` — a bundled plugin came from another installation
34
65
 
35
- ```sh
36
- rigor baseline drift
37
- ```
66
+ `warn` when a bundled plugin was loaded from a different `rigortype`
67
+ installation than the engine. The engine and its bundled plugins are
68
+ versioned together, so a mismatched copy can produce wrong diagnostics.
69
+ Make sure a single `rigortype` is on the load path.
70
+
71
+ ### `baseline` — the baseline is not stale (if one exists)
72
+
73
+ - `fail` — drift: some baseline buckets are over their recorded count,
74
+ cleared, or reducible. The hint is `rigor baseline regenerate`; before
75
+ regenerating, run `rigor baseline drift` to see which buckets moved, so
76
+ a regeneration does not bury a new catch (often after an upgrade — see
77
+ `rigor-upgrade`).
78
+ - `warn` — the baseline file failed to load. Check the `baseline:` path
79
+ in the config.
80
+
81
+ ### `plugin_gap` — the stack has a plugin that is not enabled
82
+
83
+ Read from the `DEPENDENCIES` section of `Gemfile.lock`.
84
+
85
+ - `fail` — the project depends on gems that bundled plugins model, and
86
+ **none** of those plugins is enabled: framework calls will not resolve.
87
+ Add the plugins for the stack to `plugins:` (the `rigor-plugin-tune`
88
+ skill does this).
89
+ - `warn` — one per plugin that models a direct dependency but is not
90
+ enabled. Enable it, or leave it out deliberately; declining a plugin is
91
+ a legitimate choice.
92
+
93
+ ### `gemfile_install` — Rigor is a project dependency
94
+
95
+ `fail` when `rigortype` is resolved from a gem source in the project's
96
+ `Gemfile.lock`. Rigor is a tool, not a library: remove it from the
97
+ `Gemfile` and install it standalone (`rigor docs manual/01-installation`).
98
+
99
+ ### `bundle_layout` — gem-shipped signatures are not discovered
38
100
 
39
- Shows whether the live diagnostics have drifted from `.rigor-baseline.yml`
40
- — entries the baseline ignores that no longer occur (safe to prune) and
41
- new diagnostics outside the envelope. A large drift means the baseline
42
- needs regenerating (often after an upgrade — see `rigor-upgrade`).
101
+ `warn` when a `Gemfile.lock` exists but Rigor cannot locate the installed
102
+ bundle (the gems live in the active Ruby's default gem home). Gems that
103
+ ship their own `sig/` are then not loaded. Point Rigor at the install
104
+ root with `bundler.bundle_path:`, install into `vendor/bundle`, or supply
105
+ signatures with `rbs collection install` instead.
43
106
 
44
- ## 4. The analysis is actually seeing your code
107
+ ## Not covered by `rigor doctor`: is the analysis seeing your code?
45
108
 
46
109
  ```sh
47
- rigor check --format json # check the "Ruby source files" count
110
+ rigor check --no-cache --format json | jq '.stats.target_files'
48
111
  ```
49
112
 
50
- If the file count is `0` or far below your project size, `paths:` /
51
- `exclude:` are mis-scoped, or the command is running from the wrong
113
+ `--no-cache` matters: a result served from the run cache carries no
114
+ `stats`. If the file count is `0` or far below your project size, `paths:`
115
+ / `exclude:` are mis-scoped, or the command is running from the wrong
52
116
  directory. The analysis is only as good as the files it reads.
@@ -1,7 +1,9 @@
1
1
  ---
2
2
  name: rigor-editor-setup
3
- description: |
4
- Wire Rigor's bundled language server (`rigor lsp`) into the developer's editor for live diagnostics, hover-to-type, outline, and type-aware completion. The per-editor config snippets live in the manual; this skill identifies the editor, applies the right one, and verifies the server attaches. Triggers: "set up Rigor in my editor", "rigor LSP / language server", "live Rigor diagnostics in VS Code / Neovim / Helix / Emacs", "hover types in my editor". NOT for CI integration (use rigor-ci-setup) or first-time project setup (use rigor-project-init).
3
+ description: >-
4
+ Set up Rigor's bundled language server for live diagnostics, hover, outline, and completion in a
5
+ developer's editor. Use when wiring `rigor lsp` into VS Code, Neovim, Helix, Emacs, or another LSP
6
+ client; not for CI or first-time project setup.
5
7
  license: MPL-2.0
6
8
  metadata:
7
9
  version: 0.1.0
@@ -24,7 +26,7 @@ rigor docs editor-integration
24
26
  ```
25
27
 
26
28
  (Web fallback, only before Rigor is installed:
27
- **[Rigor LSP — Editor Integration](../../docs/manual/09-editor-integration.md)**.)
29
+ **[Rigor LSP — Editor Integration](https://github.com/rigortype/rigor/blob/master/docs/manual/09-editor-integration.md)**.)
28
30
  This skill is the *workflow* around it (identify the editor → apply the
29
31
  manual's snippet → verify), so it does not duplicate (and cannot
30
32
  stale-out) the config details.
@@ -62,7 +64,7 @@ Every editor snippet simply launches **`rigor lsp`** (stdio) and needs
62
64
  **`rigor` on the editor's `PATH`** — the same executable `rigor check`
63
65
  uses. For GUI editors that do not inherit your shell, the `mise` shim
64
66
  path is the most reliable channel (see `rigor docs install`, or
65
- [Installing Rigor](../../docs/install.md)
67
+ [Installing Rigor](https://github.com/rigortype/rigor/blob/master/docs/install.md)
66
68
  on the web). Do **not** add `rigortype` to the project's `Gemfile` — it
67
69
  is a tool, not a library.
68
70
 
@@ -1,7 +1,8 @@
1
1
  ---
2
2
  name: rigor-mcp-setup
3
- description: |
4
- Wire Rigor's bundled MCP server (`rigor mcp`) into an AI coding agent (Claude Code, Claude Desktop, Cursor, Cline) so the agent can call Rigor's read-only analysis tools — rigor_check, rigor_type_of, rigor_triage, rigor_coverage, and more — during a session. The per-client config lives in the manual; this skill identifies the client, applies the right one, and verifies the handshake. Triggers: "set up rigor mcp", "give my AI agent Rigor tools", "wire Rigor into Claude Code / Cursor / Cline", "rigor MCP server". NOT for editor LSP integration (use rigor-editor-setup) or CI (use rigor-ci-setup).
3
+ description: >-
4
+ Set up Rigor's bundled MCP server for an AI coding agent and verify the connection. Use when wiring
5
+ `rigor mcp` into Claude Code, Cursor, Cline, or another MCP client; not for editor LSP or CI setup.
5
6
  license: MPL-2.0
6
7
  metadata:
7
8
  version: 0.1.0
@@ -26,7 +27,7 @@ rigor docs mcp-server
26
27
  ```
27
28
 
28
29
  (Web fallback, only before Rigor is installed:
29
- **[Rigor MCP Server — AI Agent Integration](../../docs/manual/10-mcp-server.md)**.)
30
+ **[Rigor MCP Server — AI Agent Integration](https://github.com/rigortype/rigor/blob/master/docs/manual/10-mcp-server.md)**.)
30
31
  This skill is the *workflow* around it (identify the client → apply the
31
32
  manual's snippet → verify the handshake), so it does not duplicate (and
32
33
  cannot stale-out) the config details.
@@ -70,7 +71,7 @@ Every client config simply launches **`rigor mcp`** (stdio) and needs
70
71
  **`rigor` on the agent's `PATH`** — the same executable `rigor check`
71
72
  uses. For agents that do not inherit your shell, the `mise` shim path is
72
73
  the most reliable channel (see `rigor docs install`, or
73
- [Installing Rigor](../../docs/install.md)
74
+ [Installing Rigor](https://github.com/rigortype/rigor/blob/master/docs/install.md)
74
75
  on the web). Do **not** add `rigortype` to the project's `Gemfile` — it
75
76
  is a tool, not a library.
76
77
 
@@ -1,7 +1,9 @@
1
1
  ---
2
2
  name: rigor-monkeypatch-resolve
3
- description: |
4
- Resolve a cluster of `call.unresolved-toplevel` / `call.undefined-method` diagnostics that are really the project's own monkey-patches (core-extension files that add methods with literal `def`) by wiring them into `pre_eval:` so Rigor pre-evaluates them and learns the added methods. Triggers: "Rigor flags methods my core-ext adds", "undefined-method on my own monkey-patch", "set up pre_eval", "lots of unresolved-toplevel from my lib/core_ext". NOT for dynamically-generated methods (define_method / method_missing / class_eval heredocs) — those need a plugin (use rigor-plugin-author) — and NOT for an external gem with no RBS (use rigor-rbs-setup).
3
+ description: >-
4
+ Resolve Rigor diagnostics caused by literal `def` methods in a project's own monkey-patches by wiring
5
+ their files into `pre_eval:`. Use when project core extensions cause undefined-method findings; not for
6
+ dynamic method generation or an external gem without RBS.
5
7
  license: MPL-2.0
6
8
  metadata:
7
9
  version: 0.1.0
@@ -14,7 +16,7 @@ When a project adds methods to existing classes in its own files — the
14
16
  classic `lib/core_ext/*.rb` `class String; def squish; …; end` pattern —
15
17
  Rigor does not see them unless told to, so every call to the added method
16
18
  fires `call.undefined-method` (or `call.unresolved-toplevel` for a
17
- top-level helper). `pre_eval:` ([ADR-17](../../docs/adr/17-monkey-patch-pre-evaluation.md))
19
+ top-level helper). `pre_eval:` ([ADR-17](https://github.com/rigortype/rigor/blob/master/docs/adr/17-monkey-patch-pre-evaluation.md))
18
20
  fixes this: it pre-evaluates the listed project files and registers every
19
21
  method they define with a **literal** `def` / `def self.`.
20
22
 
@@ -1,7 +1,9 @@
1
1
  ---
2
2
  name: rigor-next-steps
3
- description: |
4
- Route a project to its next Rigor step from a single entry point: resolve the `rigor` command (install it if missing), onboard the project if it has no Rigor config, then ask `rigor skill describe` what to do next and hand off to the matching skill. Triggers: "what should we do next with Rigor?", "I want to use Rigor on this project", "help me move this project forward with Rigor", "where do I start with Rigor?". NOT a replacement for the task-specific skills it routes to — it hands off to them.
3
+ description: >-
4
+ Route a project to its next Rigor step, installing or onboarding Rigor when needed and then delegating
5
+ to `rigor skill describe`. Use when the user asks where to start or what to do next with Rigor; not
6
+ instead of a task-specific skill the route selects.
5
7
  license: MPL-2.0
6
8
  metadata:
7
9
  version: 0.1.0
@@ -1,7 +1,9 @@
1
1
  ---
2
2
  name: rigor-plugin-author
3
- description: |
4
- Author a Rigor plugin in your own repository — a standalone rigor-prefixed gem or a project-private plugin — to teach Rigor about an application DSL, framework, or metaprogramming pattern. Covers gemspec / Gemfile wiring, the plugin class and AST walker, return-type contributions, fixture-based testing (RSpec or Minitest), and version pinning against the pre-1.0 plugin contract. Triggers: "write a Rigor plugin for our DSL", "extend Rigor for X in this project", "make Rigor understand our macro". NOT for onboarding a project (use rigor-project-init) or reducing a baseline (use rigor-baseline-reduce).
3
+ description: >-
4
+ Author a Rigor plugin in an adopting project or standalone `rigor-*` gem for a DSL, framework, or
5
+ metaprogramming pattern. Use when Rigor needs project-specific extension support; not for onboarding a
6
+ project, reducing a baseline, or editing Rigor's bundled plugins.
5
7
  license: MPL-2.0
6
8
  metadata:
7
9
  version: 0.1.0
@@ -43,21 +45,20 @@ If you already loaded this skill *via* `rigor skill` you have the current
43
45
  copy — just proceed. If the `rigor` command is not available, run
44
46
  **`rigor-next-steps`** to install Rigor first, then come back.
45
47
 
46
- ## Important — the plugin contract is a preview (pre-1.0)
48
+ ## The plugin contract is pre-1.0
47
49
 
48
- Rigor's plugin contract (ADR-2) is **not yet frozen**. It stabilises
49
- at `rigortype` v0.2.0. Until then, treat each `rigortype` minor
50
- release as potentially contract-changing:
50
+ Rigor's plugin contract (ADR-2) freezes at `rigortype` v1.0.0. Until
51
+ then, treat each `rigortype` minor release as potentially
52
+ contract-changing:
51
53
 
52
- - **Pin `rigortype` tightly** — `>= 0.1.0, < 0.2.0` in your gemspec
53
- or Gemfile. Do not float across the v0.2.0 boundary blind.
54
- - Expect to **revisit your plugin** when you bump `rigortype` to the
55
- next minor. The walker hook signature, the `Diagnostic` shape, and
56
- the type carriers may shift.
57
- - After v0.2.0 the contract is stable and ordinary semver applies.
54
+ - **Pin `rigortype` to the minor you built against** — `"~> X.Y.0"`
55
+ in your gemspec or Gemfile, where `X.Y` comes from `rigor --version`.
56
+ - Expect to **revisit your plugin** when you move to the next minor.
57
+ The node-rule block signature, the `Diagnostic` shape, and the type
58
+ carriers may shift.
58
59
 
59
- Tell the user this up front. A plugin written today is a preview
60
- artefact, valuable but not yet on a stable foundation.
60
+ Tell the user this up front: a plugin written today is valuable but
61
+ not yet on a frozen foundation.
61
62
 
62
63
  ## Read a real plugin — `rigor plugin`
63
64
 
@@ -114,14 +115,9 @@ AST walk per file — hands every matching node to the block along with a
114
115
  `Rigor::Analysis::Diagnostic` (built via the `diagnostic` helper).
115
116
  Optionally the plugin also declares `dynamic_return(receivers:)` /
116
117
  `narrowing_facts(methods:)` to *supply* a return type or narrowing facts
117
- for call sites the core analyzer types as `Dynamic`. (`narrowing_facts`
118
- was renamed from `type_specifier` in ADR-80; the old verb was removed in
119
- 0.3.0, so `narrowing_facts` is the only spelling.)
120
- `#diagnostics_for_file`
121
- is the file-rule surface for whole-file diagnostics a per-node walk can't
122
- express. (`flow_contribution_for` was removed pre-1.0 in ADR-52 WD3 —
123
- defining it now raises `ArgumentError`; use `dynamic_return` /
124
- `narrowing_facts`. See Phase 2.)
118
+ for call sites the core analyzer types as `Dynamic`.
119
+ `#diagnostics_for_file` is the file-rule surface for whole-file
120
+ diagnostics a per-node walk can't express. See Phase 2.
125
121
 
126
122
  ## Phase outline
127
123
 
@@ -136,5 +132,5 @@ defining it now raises `ArgumentError`; use `dynamic_return` /
136
132
  | Module | Read | Covers |
137
133
  | --- | --- | --- |
138
134
  | 1 | [`references/01-plan-and-scaffold.md`](references/01-plan-and-scaffold.md) | **Phase 1.** The gem vs project-private packaging split, directory trees for both, gemspec template, project-private path-gem / `RUBYLIB` activation, the `Rigor::Plugin::Base` skeleton, `.rigor.yml` `plugins:` wiring. |
139
- | 2 | [`references/02-walker-and-types.md`](references/02-walker-and-types.md) | **Phase 2.** The `node_rule` engine-owned AST walk over Prism nodes, the `Base#diagnostic` helper, asking the analyzer for inferred types via `scope.type_of`, two-pass / lexical context (`node_file_context` / `NodeContext`), the optional `dynamic_return` / `narrowing_facts` return-type hooks (`narrowing_facts` was renamed from `type_specifier` in ADR-80, the alias removed in 0.3.0; `flow_contribution_for` was removed pre-1.0 in ADR-52 WD3), calling the target library's pure methods directly rather than reimplementing them (ADR-39: `Plugin::Inflector` over the real `ActiveSupport::Inflector`; `Base.suggest` for did-you-mean), and shipping `sig/*.rbs` so the DSL's types are visible. |
135
+ | 2 | [`references/02-walker-and-types.md`](references/02-walker-and-types.md) | **Phase 2.** The `node_rule` engine-owned AST walk over Prism nodes, the `Base#diagnostic` helper, asking the analyzer for inferred types via `scope.type_of`, two-pass / lexical context (`node_file_context` / `NodeContext`), the optional `dynamic_return` / `narrowing_facts` return-type hooks, calling the target library's pure methods directly rather than reimplementing them (ADR-39: `Plugin::Inflector` over the real `ActiveSupport::Inflector`; `Base.suggest` for did-you-mean), and shipping `sig/*.rbs` so the DSL's types are visible. |
140
136
  | 3 | [`references/03-test-and-ship.md`](references/03-test-and-ship.md) | **Phase 3.** Testing a plugin from outside the monorepo — fixture projects driven through `rigor check --format json`, plus pure unit tests of dispatch tables — with RSpec or Minitest. Version pinning against the pre-1.0 contract. README. Publishing to RubyGems or keeping the plugin private. |
@@ -52,8 +52,9 @@ Gem::Specification.new do |spec|
52
52
  spec.require_paths = ["lib"]
53
53
 
54
54
  spec.add_dependency "prism", ">= 1.0", "< 2.0"
55
- # Pin tightly — the plugin contract is pre-1.0 (see SKILL.md).
56
- spec.add_dependency "rigortype", ">= 0.1.0", "< 0.2.0"
55
+ # Pin to the minor you built against — the contract is pre-1.0
56
+ # (see SKILL.md). X.Y comes from `rigor --version`.
57
+ spec.add_dependency "rigortype", "~> X.Y.0"
57
58
  end
58
59
  ```
59
60
 
@@ -131,7 +132,7 @@ your-app/
131
132
 
132
133
  ```ruby
133
134
  # your-app/Gemfile
134
- gem "rigortype", "~> 0.1.0"
135
+ gem "rigortype", "~> X.Y.0" # the minor you built against
135
136
  gem "rigor-myapp", path: "rigor-plugin"
136
137
  ```
137
138
 
@@ -172,16 +173,16 @@ module Rigor
172
173
  # Optional: declare config keys the user may set under
173
174
  # `.rigor.yml` plugins: [{ gem:, config: { … } }].
174
175
  config_schema: {
175
- # "module_name" => :string,
176
- # "rules" => :array,
176
+ "module_name" => { kind: :string, default: "Default" }
177
+ # "rules" => :array,
177
178
  }
178
179
  )
179
180
 
180
181
  # Called once at load time with the service container.
181
- # Read config defaults here. `config` is the validated
182
- # user config Hash.
182
+ # `config` is the validated user config Hash, with declared
183
+ # defaults merged beneath it.
183
184
  def init(_services)
184
- @module_name = config.fetch("module_name", "Default")
185
+ @module_name = config["module_name"]
185
186
  end
186
187
 
187
188
  # The engine owns the AST walk and hands every matching node to
@@ -165,20 +165,14 @@ Rigor::Plugin::Base.suggest(typo, known_names) # nearest match, or nil
165
165
 
166
166
  ## Optional — contribute a return type with `dynamic_return` / `narrowing_facts`
167
167
 
168
- > **Critical — these hooks do NOT make a method "defined", so they do
169
- > NOT suppress `call.undefined-method`.** Method *existence* and call
170
- > *type* are two independent checks. A return-type contribution sharpens
171
- > the type of a call the analyzer has **already resolved to a real
172
- > method** (turning a `Dynamic` return into something precise). It is
173
- > never consulted for a receiver/method the analyzer cannot find — that
174
- > fires `call.undefined-method` first, and a contribution does nothing
175
- > to silence it. **If your goal is to kill a `call.undefined-method`
176
- > cluster on a DSL-generated method (the common reason
177
- > `rigor-project-init` hands off to this skill), the fix is to make the
178
- > method *exist* in Rigor's view — ship RBS declaring it (see "Shipping
179
- > RBS for the DSL" below), not a return-type contribution.** Reach for
180
- > these only when the call already resolves and you want a *better
181
- > return type*.
168
+ > **Prefer RBS to make a DSL method exist.** A `dynamic_return` answer
169
+ > suppresses `call.undefined-method` only at the call sites where the
170
+ > rule fires (its gated receiver kind and methods); RBS makes the method
171
+ > defined for all of core inference — arity, argument types, every call
172
+ > site. To clear a `call.undefined-method` cluster on DSL-generated
173
+ > methods (the common reason `rigor-project-init` hands off to this
174
+ > skill), ship RBS (see "Shipping RBS for the DSL" below). Reach for
175
+ > these hooks when you want a better *return type* for a call.
182
176
 
183
177
  A plugin can do more than emit diagnostics: it can *supply* the
184
178
  inferred return type (or narrowing facts) for a call site the core
@@ -213,10 +207,6 @@ narrowing_facts methods: [:assert_kind_of] do |call_node, scope|
213
207
  end
214
208
  ```
215
209
 
216
- > **`narrowing_facts` was renamed from `type_specifier` in ADR-80.**
217
- > The old verb was removed in 0.3.0 — `narrowing_facts` is the only
218
- > spelling a plugin can declare.
219
-
220
210
  Build return types with `Rigor::Type::Combinator`:
221
211
 
222
212
  ```ruby
@@ -233,12 +223,9 @@ plugin is confident; a wrong contribution propagates downstream.
233
223
  `rigor plugins --capabilities` catalogue enumerates — run it to see
234
224
  exactly what each loaded plugin contributes.
235
225
 
236
- > **The removed fat hook.** The original `flow_contribution_for(call_node:,
237
- > scope:)` was **deleted pre-1.0 in ADR-52 WD3** — defining it now raises
238
- > `ArgumentError` at load time. The two shapes it used to cover are
239
- > expressed by `dynamic_return`'s callable gates: a **method-gated return
240
- > type** (an RSpec `let(:x) { … }` binding, a Sorbet `sig`-driven return —
241
- > keyed on the method, not a fixed receiver class) uses
226
+ > **Callable gates.** A **method-gated return type** (an RSpec
227
+ > `let(:x) { … }` binding, a Sorbet `sig`-driven return — keyed on the
228
+ > method, not a fixed receiver class) uses
242
229
  > `dynamic_return methods: -> { [...] }` or `file_methods: ->(path) { [...] }`;
243
230
  > a **dynamic per-project receiver set** (ActiveStorage's `Attached::One`
244
231
  > on discovered model classes) uses `dynamic_return receivers: -> { [...] }`,
@@ -247,7 +234,7 @@ exactly what each loaded plugin contributes.
247
234
  > if the plugin genuinely needs to sharpen call-site types; a
248
235
  > diagnostics-only plugin skips them entirely.
249
236
 
250
- ## Shipping RBS for the DSL — the way to suppress `call.undefined-method`
237
+ ## Shipping RBS for the DSL — making DSL methods exist
251
238
 
252
239
  If the DSL introduces methods or classes that Rigor cannot see (a
253
240
  `Money` class defined by metaprogramming, `Setting.<name>` accessors a
@@ -106,11 +106,12 @@ CLI tests for the end-to-end wiring.
106
106
 
107
107
  ## Version pinning — the pre-1.0 contract
108
108
 
109
- The plugin contract is **not frozen until `rigortype` v0.2.0** (see
109
+ The plugin contract is **not frozen until `rigortype` v1.0.0** (see
110
110
  SKILL.md). Concretely:
111
111
 
112
- - Gemspec / Gemfile: `rigortype` `>= 0.1.0, < 0.2.0`. Never `>= 0.1`
113
- alone — that floats across the contract-changing v0.2.0 boundary.
112
+ - Gemspec / Gemfile: `rigortype` `~> X.Y.0` for the minor you tested
113
+ (`rigor --version`). Never an open `>=` range — that floats across
114
+ contract-changing minors.
114
115
  - Your plugin's own version is normal semver, independent of
115
116
  `rigortype`'s.
116
117
  - When you bump the `rigortype` pin to a new minor, **re-run the
@@ -120,9 +121,6 @@ SKILL.md). Concretely:
120
121
  - State the supported `rigortype` range in the README so users do
121
122
  not pair the plugin with an incompatible Rigor.
122
123
 
123
- When v0.2.0 lands, re-pin to the stable range and ordinary
124
- compatibility rules apply.
125
-
126
124
  ## README
127
125
 
128
126
  A plugin README should carry:
@@ -151,13 +149,13 @@ wired and the fixture tests run.
151
149
  Either way, if the plugin uncovered a gap that *should* be core
152
150
  Rigor behaviour — or if you hit a plugin-contract rough edge — report
153
151
  it: <https://github.com/rigortype/rigor/issues>. External plugin
154
- authors are the main source of pre-v0.2.0 contract feedback.
152
+ authors are the main source of contract feedback before v1.0.
155
153
 
156
154
  ## Output of this module — plugin shipped
157
155
 
158
156
  - A test suite: fast unit tests + fixture-driven `rigor check`
159
157
  tests, in RSpec or Minitest.
160
- - A `rigortype` pin tight to `< 0.2.0`.
158
+ - A `rigortype` pin tight to the tested minor.
161
159
  - A README stating the compatibility range.
162
160
  - The plugin published as a gem, or committed project-private with
163
161
  CI wired.