rigortype 0.3.8 → 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 (634) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/data/capability_roles/capability_roles.rbs +36 -0
  4. data/data/core_overlay/enumerable.rbs +51 -0
  5. data/data/core_overlay/enumerator.rbs +84 -0
  6. data/data/core_overlay/hash_rbs3.rbs +41 -0
  7. data/data/core_overlay/process.rbs +40 -0
  8. data/data/core_overlay/string_io.rbs +33 -0
  9. data/data/effects/core.yml +3 -3
  10. data/data/gem_overlay/activesupport/core_ext.rbs +236 -17
  11. data/docs/handbook/02-everyday-types.md +17 -14
  12. data/docs/handbook/03-narrowing.md +132 -14
  13. data/docs/handbook/04-tuples-and-shapes.md +8 -6
  14. data/docs/handbook/05-methods-and-blocks.md +1 -1
  15. data/docs/handbook/06-classes.md +2 -2
  16. data/docs/handbook/07-rbs-and-extended.md +19 -1
  17. data/docs/handbook/10-sorbet.md +9 -10
  18. data/docs/handbook/11-sig-gen.md +525 -13
  19. data/docs/handbook/README.md +1 -1
  20. data/docs/handbook/appendix-elixir.md +2 -2
  21. data/docs/handbook/appendix-go.md +2 -2
  22. data/docs/handbook/appendix-java-csharp.md +2 -2
  23. data/docs/handbook/appendix-mypy.md +2 -2
  24. data/docs/handbook/appendix-phpstan.md +1 -1
  25. data/docs/handbook/appendix-rust.md +1 -1
  26. data/docs/handbook/appendix-type-theory.md +4 -4
  27. data/docs/handbook/appendix-typescript.md +1 -1
  28. data/docs/llms.txt +2 -0
  29. data/docs/manual/02-cli-reference.md +95 -6
  30. data/docs/manual/03-configuration.md +18 -0
  31. data/docs/manual/04-diagnostics.md +15 -0
  32. data/docs/manual/07-plugins.md +15 -5
  33. data/docs/manual/08-skills.md +23 -2
  34. data/docs/manual/10-mcp-server.md +3 -2
  35. data/docs/manual/11-ci.md +9 -0
  36. data/docs/manual/15-type-protection-coverage.md +8 -0
  37. data/docs/manual/16-rbs-extended-annotations.md +46 -8
  38. data/docs/manual/18-removing-dead-code.md +10 -8
  39. data/docs/manual/19-effect-labels.md +10 -0
  40. data/docs/manual/plugins/README.md +7 -0
  41. data/docs/manual/plugins/rigor-actioncable.md +8 -1
  42. data/docs/manual/plugins/rigor-actionmailer.md +7 -0
  43. data/docs/manual/plugins/rigor-actionpack.md +261 -0
  44. data/docs/manual/plugins/rigor-active-model-serializers.md +153 -0
  45. data/docs/manual/plugins/rigor-activejob.md +7 -0
  46. data/docs/manual/plugins/rigor-activerecord.md +138 -4
  47. data/docs/manual/plugins/rigor-activestorage.md +8 -1
  48. data/docs/manual/plugins/rigor-activesupport-core-ext.md +43 -7
  49. data/docs/manual/plugins/rigor-grape.md +106 -0
  50. data/docs/manual/plugins/rigor-graphql.md +23 -2
  51. data/docs/manual/plugins/rigor-pundit.md +8 -1
  52. data/docs/manual/plugins/rigor-rails-i18n.md +10 -5
  53. data/docs/manual/plugins/rigor-rails-routes.md +7 -0
  54. data/docs/manual/plugins/rigor-rbs-inline.md +229 -1
  55. data/docs/manual/plugins/rigor-sidekiq.md +8 -1
  56. data/docs/manual/plugins/rigor-sorbet.md +21 -5
  57. data/exe/rigor +19 -4
  58. data/lib/rigor/analysis/baseline.rb +3 -3
  59. data/lib/rigor/analysis/check_rules/always_truthy_condition_collector.rb +1 -1
  60. data/lib/rigor/analysis/check_rules/dead_version_guard_arms.rb +1 -5
  61. data/lib/rigor/analysis/check_rules/declaration_sourced_guard.rb +167 -2
  62. data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +10 -2
  63. data/lib/rigor/analysis/check_rules/lexical_method_sites.rb +189 -0
  64. data/lib/rigor/analysis/check_rules/main_pass_collector.rb +6 -4
  65. data/lib/rigor/analysis/check_rules/published_constant_guard.rb +15 -6
  66. data/lib/rigor/analysis/check_rules/rule_ids.rb +21 -6
  67. data/lib/rigor/analysis/check_rules/rule_walk.rb +41 -5
  68. data/lib/rigor/analysis/check_rules/self_closedness_scanner.rb +1 -1
  69. data/lib/rigor/analysis/check_rules/shadowed_rescue_collector.rb +1 -1
  70. data/lib/rigor/analysis/check_rules/source_arity.rb +323 -0
  71. data/lib/rigor/analysis/check_rules/special_global_setters.rb +146 -0
  72. data/lib/rigor/analysis/check_rules/unreachable_clause_collector.rb +38 -4
  73. data/lib/rigor/analysis/check_rules/void_value_use_collector.rb +0 -1
  74. data/lib/rigor/analysis/check_rules.rb +718 -79
  75. data/lib/rigor/analysis/crash_signature.rb +8 -24
  76. data/lib/rigor/analysis/dependency_recorder.rb +23 -0
  77. data/lib/rigor/analysis/dependency_source_inference/boundary_cross_reporter.rb +1 -1
  78. data/lib/rigor/analysis/dependency_source_inference/builder.rb +0 -2
  79. data/lib/rigor/analysis/dependency_source_inference/gem_resolver.rb +0 -2
  80. data/lib/rigor/analysis/dependency_source_inference/index.rb +5 -5
  81. data/lib/rigor/analysis/dependency_source_inference/return_type_heuristic.rb +1 -2
  82. data/lib/rigor/analysis/dependency_source_inference/walker.rb +4 -4
  83. data/lib/rigor/analysis/effects_cache_probe.rb +3 -4
  84. data/lib/rigor/analysis/erb_template_detector.rb +1 -2
  85. data/lib/rigor/analysis/fact_store.rb +15 -1
  86. data/lib/rigor/analysis/incremental.rb +42 -0
  87. data/lib/rigor/analysis/incremental_session.rb +117 -26
  88. data/lib/rigor/analysis/plugin_fact_fingerprint.rb +0 -1
  89. data/lib/rigor/analysis/project_scan.rb +11 -1
  90. data/lib/rigor/analysis/reachability/graph.rb +3 -5
  91. data/lib/rigor/analysis/reachability/plugin_roots.rb +5 -5
  92. data/lib/rigor/analysis/reachability/project_files.rb +2 -2
  93. data/lib/rigor/analysis/reachability/scan.rb +5 -5
  94. data/lib/rigor/analysis/reachability/scan_cache.rb +3 -2
  95. data/lib/rigor/analysis/reachability/signature_scan.rb +2 -2
  96. data/lib/rigor/analysis/result.rb +1 -3
  97. data/lib/rigor/analysis/rule_catalog.rb +131 -1
  98. data/lib/rigor/analysis/run_cache_key.rb +21 -12
  99. data/lib/rigor/analysis/run_cache_probe.rb +3 -5
  100. data/lib/rigor/analysis/runner/buffer_pool_dispatcher.rb +6 -8
  101. data/lib/rigor/analysis/runner/declaration_position.rb +1 -2
  102. data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +340 -33
  103. data/lib/rigor/analysis/runner/effect_annotation_residual_pass.rb +2 -3
  104. data/lib/rigor/analysis/runner/effect_envelope_pass.rb +18 -14
  105. data/lib/rigor/analysis/runner/pool_coordinator.rb +357 -97
  106. data/lib/rigor/analysis/runner/project_pre_passes.rb +38 -13
  107. data/lib/rigor/analysis/runner/run_snapshots.rb +6 -1
  108. data/lib/rigor/analysis/runner.rb +407 -51
  109. data/lib/rigor/analysis/template_unit_collector.rb +303 -0
  110. data/lib/rigor/analysis/template_unit_paths.rb +91 -0
  111. data/lib/rigor/analysis/template_unit_positions.rb +293 -0
  112. data/lib/rigor/analysis/template_units.rb +399 -0
  113. data/lib/rigor/analysis/worker_session.rb +62 -20
  114. data/lib/rigor/bleeding_edge.rb +10 -24
  115. data/lib/rigor/builtins/hkt_builtins.rb +3 -2
  116. data/lib/rigor/builtins/imported_refinements.rb +159 -21
  117. data/lib/rigor/builtins/predefined_constant_refinements.rb +5 -7
  118. data/lib/rigor/builtins/regex_refinement.rb +21 -13
  119. data/lib/rigor/builtins/static_return_refinements.rb +7 -6
  120. data/lib/rigor/cache/annotation_location.rb +2 -4
  121. data/lib/rigor/cache/descriptor.rb +63 -20
  122. data/lib/rigor/cache/engine_source.rb +33 -5
  123. data/lib/rigor/cache/file_digest.rb +9 -1
  124. data/lib/rigor/cache/incremental_snapshot.rb +72 -6
  125. data/lib/rigor/cache/rbs_cache_producer.rb +4 -0
  126. data/lib/rigor/cache/rbs_class_ancestor_table.rb +0 -3
  127. data/lib/rigor/cache/rbs_class_type_param_names.rb +0 -3
  128. data/lib/rigor/cache/rbs_constant_table.rb +0 -3
  129. data/lib/rigor/cache/rbs_descriptor.rb +112 -14
  130. data/lib/rigor/cache/rbs_environment.rb +8 -4
  131. data/lib/rigor/cache/rbs_known_class_names.rb +0 -3
  132. data/lib/rigor/cache/store.rb +76 -32
  133. data/lib/rigor/ci_detector.rb +1 -0
  134. data/lib/rigor/cli/annotate_command.rb +5 -6
  135. data/lib/rigor/cli/check_command.rb +57 -10
  136. data/lib/rigor/cli/check_invocation.rb +6 -11
  137. data/lib/rigor/cli/check_runner_factory.rb +1 -5
  138. data/lib/rigor/cli/coverage_command.rb +1 -1
  139. data/lib/rigor/cli/coverage_mutation.rb +12 -3
  140. data/lib/rigor/cli/coverage_scan.rb +1 -5
  141. data/lib/rigor/cli/diff_command.rb +1 -1
  142. data/lib/rigor/cli/doc_links.rb +4 -4
  143. data/lib/rigor/cli/docs_command.rb +6 -6
  144. data/lib/rigor/cli/doctor_command.rb +85 -38
  145. data/lib/rigor/cli/effects_command.rb +2 -2
  146. data/lib/rigor/cli/effects_diff_renderer.rb +3 -3
  147. data/lib/rigor/cli/effects_snapshot_command.rb +1 -1
  148. data/lib/rigor/cli/explain_command.rb +34 -1
  149. data/lib/rigor/cli/fused_protection_report.rb +7 -1
  150. data/lib/rigor/cli/lsp_command.rb +1 -1
  151. data/lib/rigor/cli/mcp_command.rb +1 -1
  152. data/lib/rigor/cli/measurement_integrity_warning.rb +4 -5
  153. data/lib/rigor/cli/mutation_fork_scan.rb +6 -6
  154. data/lib/rigor/cli/mutation_protection_report.rb +7 -1
  155. data/lib/rigor/cli/plugin_command.rb +4 -4
  156. data/lib/rigor/cli/plugins_command.rb +2 -1
  157. data/lib/rigor/cli/prism_colorizer.rb +1 -2
  158. data/lib/rigor/cli/protection_fork_scan.rb +6 -6
  159. data/lib/rigor/cli/show_bleedingedge_command.rb +1 -1
  160. data/lib/rigor/cli/sig_gen_command.rb +212 -31
  161. data/lib/rigor/cli/skill_command.rb +2 -2
  162. data/lib/rigor/cli/skill_deep_probe.rb +4 -4
  163. data/lib/rigor/cli/skill_describe.rb +35 -35
  164. data/lib/rigor/cli/trace_command.rb +4 -4
  165. data/lib/rigor/cli/trace_renderer.rb +5 -6
  166. data/lib/rigor/cli/triage_command.rb +1 -1
  167. data/lib/rigor/cli/type_of_command.rb +29 -11
  168. data/lib/rigor/cli/type_of_renderer.rb +20 -9
  169. data/lib/rigor/cli/type_of_template_probe.rb +189 -0
  170. data/lib/rigor/cli/type_scan_command.rb +4 -4
  171. data/lib/rigor/cli/unused_command.rb +11 -3
  172. data/lib/rigor/cli/upgrade_command.rb +1 -1
  173. data/lib/rigor/cli.rb +89 -9
  174. data/lib/rigor/config_audit.rb +30 -5
  175. data/lib/rigor/configuration/severity_profile.rb +25 -9
  176. data/lib/rigor/configuration.rb +109 -7
  177. data/lib/rigor/effects/ancestry_recorder.rb +191 -0
  178. data/lib/rigor/effects/attribution.rb +12 -5
  179. data/lib/rigor/effects/callee_rule.rb +368 -0
  180. data/lib/rigor/effects/catalog.rb +7 -4
  181. data/lib/rigor/effects/collector.rb +11 -5
  182. data/lib/rigor/effects/config_envelopes.rb +15 -10
  183. data/lib/rigor/effects/definition_context.rb +179 -0
  184. data/lib/rigor/effects/definition_lines.rb +25 -6
  185. data/lib/rigor/effects/effect_table.rb +11 -4
  186. data/lib/rigor/effects/entry_points.rb +0 -2
  187. data/lib/rigor/effects/envelope_check.rb +9 -9
  188. data/lib/rigor/effects/envelope_index.rb +20 -8
  189. data/lib/rigor/effects/file_collection.rb +59 -5
  190. data/lib/rigor/effects/framework_units.rb +5 -7
  191. data/lib/rigor/effects/identity.rb +20 -6
  192. data/lib/rigor/effects/inline_anchor.rb +7 -7
  193. data/lib/rigor/effects/label_intent.rb +3 -4
  194. data/lib/rigor/effects/liskov_check.rb +8 -8
  195. data/lib/rigor/effects/local_ownership.rb +38 -12
  196. data/lib/rigor/effects/method_key.rb +22 -1
  197. data/lib/rigor/effects/mutation_classifier.rb +23 -12
  198. data/lib/rigor/effects/plugin_facts.rb +47 -37
  199. data/lib/rigor/effects/propagator.rb +297 -19
  200. data/lib/rigor/effects/registry.rb +1 -1
  201. data/lib/rigor/effects/scanner.rb +122 -73
  202. data/lib/rigor/effects/signature_sources.rb +4 -6
  203. data/lib/rigor/effects/snapshot.rb +12 -11
  204. data/lib/rigor/effects/snapshot_diff.rb +1 -1
  205. data/lib/rigor/effects/summary.rb +27 -4
  206. data/lib/rigor/effects/unit_scan.rb +393 -38
  207. data/lib/rigor/effects/unknown_label_check.rb +3 -8
  208. data/lib/rigor/effects/unknown_label_report.rb +3 -4
  209. data/lib/rigor/effects/visibility.rb +101 -0
  210. data/lib/rigor/environment/bundle_sig_discovery.rb +6 -6
  211. data/lib/rigor/environment/class_registry.rb +3 -1
  212. data/lib/rigor/environment/failure_slot.rb +2 -2
  213. data/lib/rigor/environment/installed_gem_set.rb +85 -0
  214. data/lib/rigor/environment/lockfile_resolver.rb +68 -4
  215. data/lib/rigor/environment/member_consistency/comparator.rb +708 -0
  216. data/lib/rigor/environment/member_consistency.rb +298 -0
  217. data/lib/rigor/environment/missing_gem_constant_index.rb +4 -4
  218. data/lib/rigor/environment/rbs_collection_discovery.rb +5 -5
  219. data/lib/rigor/environment/rbs_coverage_report.rb +5 -5
  220. data/lib/rigor/environment/rbs_hierarchy.rb +3 -1
  221. data/lib/rigor/environment/rbs_loader.rb +674 -79
  222. data/lib/rigor/environment.rb +174 -24
  223. data/lib/rigor/flow_contribution/merger.rb +0 -2
  224. data/lib/rigor/flow_contribution.rb +11 -13
  225. data/lib/rigor/hashing/xxh3.rb +264 -0
  226. data/lib/rigor/inference/acceptance.rb +292 -17
  227. data/lib/rigor/inference/block_auto_splat.rb +216 -0
  228. data/lib/rigor/inference/block_call_timing.rb +338 -0
  229. data/lib/rigor/inference/block_parameter_binder.rb +75 -30
  230. data/lib/rigor/inference/block_repetition.rb +71 -0
  231. data/lib/rigor/inference/body_fixpoint.rb +7 -6
  232. data/lib/rigor/inference/budget_trace.rb +3 -6
  233. data/lib/rigor/inference/builtins/method_catalog.rb +2 -1
  234. data/lib/rigor/inference/builtins/string_catalog.rb +1 -1
  235. data/lib/rigor/inference/captured_locals.rb +389 -18
  236. data/lib/rigor/inference/closure_escape_analyzer.rb +159 -17
  237. data/lib/rigor/inference/content_join.rb +200 -27
  238. data/lib/rigor/inference/coverage_scanner.rb +4 -6
  239. data/lib/rigor/inference/def_return_typer.rb +11 -7
  240. data/lib/rigor/inference/define_method_block_self.rb +64 -0
  241. data/lib/rigor/inference/dynamic_origin.rb +1 -1
  242. data/lib/rigor/inference/element_read_widening.rb +180 -0
  243. data/lib/rigor/inference/error_info.rb +196 -0
  244. data/lib/rigor/inference/expression_typer.rb +2124 -468
  245. data/lib/rigor/inference/external_ancestor_resolution.rb +267 -0
  246. data/lib/rigor/inference/fork_map.rb +5 -7
  247. data/lib/rigor/inference/fresh_frame_blocks.rb +127 -0
  248. data/lib/rigor/inference/global_write_census.rb +239 -0
  249. data/lib/rigor/inference/guard_rebinding.rb +447 -0
  250. data/lib/rigor/inference/hash_lookup_mutation.rb +88 -0
  251. data/lib/rigor/inference/hkt_reducer.rb +2 -3
  252. data/lib/rigor/inference/hkt_registry.rb +4 -7
  253. data/lib/rigor/inference/index_write_widening.rb +16 -7
  254. data/lib/rigor/inference/indexed_narrowing.rb +61 -9
  255. data/lib/rigor/inference/jump_targets.rb +82 -0
  256. data/lib/rigor/inference/last_line/implicit_self.rb +210 -0
  257. data/lib/rigor/inference/last_line/self_evidence.rb +329 -0
  258. data/lib/rigor/inference/last_line.rb +340 -0
  259. data/lib/rigor/inference/last_status.rb +144 -0
  260. data/lib/rigor/inference/macro_block_self_type.rb +168 -21
  261. data/lib/rigor/inference/match_rebinding/calls.rb +281 -0
  262. data/lib/rigor/inference/match_rebinding/frame.rb +148 -0
  263. data/lib/rigor/inference/match_rebinding/operands.rb +236 -0
  264. data/lib/rigor/inference/match_rebinding/self_calls.rb +83 -0
  265. data/lib/rigor/inference/match_rebinding.rb +392 -0
  266. data/lib/rigor/inference/method_dispatcher/alias_strict_nominals.rb +36 -0
  267. data/lib/rigor/inference/method_dispatcher/block_folding.rb +87 -33
  268. data/lib/rigor/inference/method_dispatcher/cgi_folding.rb +1 -1
  269. data/lib/rigor/inference/method_dispatcher/constant_folding.rb +305 -19
  270. data/lib/rigor/inference/method_dispatcher/data_folding.rb +1 -1
  271. data/lib/rigor/inference/method_dispatcher/facet_distribution.rb +147 -0
  272. data/lib/rigor/inference/method_dispatcher/file_folding.rb +1 -1
  273. data/lib/rigor/inference/method_dispatcher/hash_transform_keys_folding.rb +191 -0
  274. data/lib/rigor/inference/method_dispatcher/iterator_dispatch.rb +6 -2
  275. data/lib/rigor/inference/method_dispatcher/json_folding.rb +1 -1
  276. data/lib/rigor/inference/method_dispatcher/kernel_dispatch.rb +7 -1
  277. data/lib/rigor/inference/method_dispatcher/match_data_folding.rb +159 -0
  278. data/lib/rigor/inference/method_dispatcher/math_folding.rb +41 -3
  279. data/lib/rigor/inference/method_dispatcher/method_folding.rb +2 -5
  280. data/lib/rigor/inference/method_dispatcher/overload_selector.rb +165 -111
  281. data/lib/rigor/inference/method_dispatcher/process_folding.rb +56 -0
  282. data/lib/rigor/inference/method_dispatcher/proven_overload.rb +72 -0
  283. data/lib/rigor/inference/method_dispatcher/random_folding.rb +82 -0
  284. data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +1046 -69
  285. data/lib/rigor/inference/method_dispatcher/receiver_affinity.rb +25 -4
  286. data/lib/rigor/inference/method_dispatcher/reduce_folding.rb +2 -8
  287. data/lib/rigor/inference/method_dispatcher/regexp_folding.rb +1 -1
  288. data/lib/rigor/inference/method_dispatcher/self_substitute.rb +142 -0
  289. data/lib/rigor/inference/method_dispatcher/set_folding.rb +1 -1
  290. data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +129 -54
  291. data/lib/rigor/inference/method_dispatcher/shellwords_folding.rb +1 -1
  292. data/lib/rigor/inference/method_dispatcher/singleton_mixin_dispatch.rb +1 -2
  293. data/lib/rigor/inference/method_dispatcher/struct_folding.rb +5 -6
  294. data/lib/rigor/inference/method_dispatcher/struct_materialization.rb +85 -4
  295. data/lib/rigor/inference/method_dispatcher/time_folding.rb +1 -1
  296. data/lib/rigor/inference/method_dispatcher/universal_object_dispatch.rb +1 -2
  297. data/lib/rigor/inference/method_dispatcher/uri_folding.rb +1 -1
  298. data/lib/rigor/inference/method_dispatcher.rb +225 -25
  299. data/lib/rigor/inference/method_parameter_binder.rb +12 -9
  300. data/lib/rigor/inference/multi_target_binder.rb +341 -55
  301. data/lib/rigor/inference/mutation_rejoin.rb +171 -0
  302. data/lib/rigor/inference/mutation_widening.rb +156 -85
  303. data/lib/rigor/inference/narrowing.rb +835 -162
  304. data/lib/rigor/inference/operand_effects.rb +167 -0
  305. data/lib/rigor/inference/operand_walk.rb +88 -0
  306. data/lib/rigor/inference/optimistic_origin.rb +153 -16
  307. data/lib/rigor/inference/origin_lookup.rb +2 -3
  308. data/lib/rigor/inference/parameter_inference_collector.rb +7 -7
  309. data/lib/rigor/inference/pre_eval_constants.rb +6 -5
  310. data/lib/rigor/inference/precision_scanner.rb +3 -4
  311. data/lib/rigor/inference/project_method_ownership.rb +136 -0
  312. data/lib/rigor/inference/project_patched_methods.rb +9 -4
  313. data/lib/rigor/inference/project_patched_scanner.rb +10 -6
  314. data/lib/rigor/inference/protection_scanner.rb +1 -2
  315. data/lib/rigor/inference/range_constant.rb +57 -0
  316. data/lib/rigor/inference/rbs_type_translator.rb +49 -11
  317. data/lib/rigor/inference/receiver_alias.rb +93 -4
  318. data/lib/rigor/inference/receiver_blind_block.rb +219 -0
  319. data/lib/rigor/inference/refinement_mutation.rb +76 -0
  320. data/lib/rigor/inference/repeated_or_writes.rb +463 -0
  321. data/lib/rigor/inference/return_barrier.rb +54 -0
  322. data/lib/rigor/inference/rewrite_mutation.rb +120 -0
  323. data/lib/rigor/inference/scope_indexer.rb +5228 -627
  324. data/lib/rigor/inference/statement_evaluator.rb +3452 -595
  325. data/lib/rigor/inference/stored_block_call.rb +54 -0
  326. data/lib/rigor/inference/string_mutation.rb +97 -0
  327. data/lib/rigor/inference/struct_fold_safety.rb +6 -7
  328. data/lib/rigor/inference/synthetic_method_index.rb +1 -2
  329. data/lib/rigor/inference/synthetic_method_scanner.rb +4 -6
  330. data/lib/rigor/inference/unknown_store_widening.rb +200 -0
  331. data/lib/rigor/inference/unthreaded_rebinds.rb +282 -0
  332. data/lib/rigor/inference/version_guard.rb +28 -21
  333. data/lib/rigor/inference/void_origin.rb +3 -3
  334. data/lib/rigor/inference/void_tail_summary.rb +2 -4
  335. data/lib/rigor/language_server/buffer_table.rb +4 -4
  336. data/lib/rigor/language_server/completion_provider.rb +1 -1
  337. data/lib/rigor/language_server/debouncer.rb +0 -1
  338. data/lib/rigor/language_server/diagnostic_publisher.rb +7 -6
  339. data/lib/rigor/language_server/document_symbol_provider.rb +1 -1
  340. data/lib/rigor/language_server/folding_range_provider.rb +1 -1
  341. data/lib/rigor/language_server/hover_provider.rb +1 -1
  342. data/lib/rigor/language_server/hover_renderer.rb +4 -4
  343. data/lib/rigor/language_server/incremental_sync.rb +6 -6
  344. data/lib/rigor/language_server/project_context.rb +7 -8
  345. data/lib/rigor/language_server/publish_batcher.rb +2 -2
  346. data/lib/rigor/language_server/selection_range_provider.rb +2 -2
  347. data/lib/rigor/language_server/server.rb +9 -9
  348. data/lib/rigor/language_server/signature_help_provider.rb +1 -1
  349. data/lib/rigor/language_server/uri.rb +1 -1
  350. data/lib/rigor/mcp/server.rb +2 -1
  351. data/lib/rigor/plugin/base.rb +258 -26
  352. data/lib/rigor/plugin/box_probe.rb +91 -0
  353. data/lib/rigor/plugin/bundled_catalog.rb +167 -0
  354. data/lib/rigor/plugin/effect_attribution.rb +65 -11
  355. data/lib/rigor/plugin/effect_entry_points.rb +3 -3
  356. data/lib/rigor/plugin/fact_store.rb +6 -6
  357. data/lib/rigor/plugin/io_boundary.rb +93 -8
  358. data/lib/rigor/plugin/isolation.rb +29 -6
  359. data/lib/rigor/plugin/loader.rb +33 -13
  360. data/lib/rigor/plugin/macro/block_as_method.rb +45 -6
  361. data/lib/rigor/plugin/macro/heredoc_template.rb +1 -1
  362. data/lib/rigor/plugin/macro/trait_registry.rb +1 -1
  363. data/lib/rigor/plugin/manifest.rb +94 -11
  364. data/lib/rigor/plugin/registry.rb +76 -12
  365. data/lib/rigor/plugin/source_rbs_synthesis_reporter.rb +21 -4
  366. data/lib/rigor/plugin/template_unit.rb +196 -0
  367. data/lib/rigor/plugin/trust_policy.rb +2 -4
  368. data/lib/rigor/plugin/type_node_resolver.rb +3 -3
  369. data/lib/rigor/plugin.rb +1 -0
  370. data/lib/rigor/plugin_gap_advisory.rb +96 -0
  371. data/lib/rigor/project_environment.rb +138 -0
  372. data/lib/rigor/protection/analysis_guard.rb +93 -14
  373. data/lib/rigor/protection/closure_kill_oracle.rb +67 -23
  374. data/lib/rigor/protection/dependency_closure.rb +5 -8
  375. data/lib/rigor/protection/diagnostic_oracle.rb +2 -2
  376. data/lib/rigor/protection/discovery_seed.rb +14 -12
  377. data/lib/rigor/protection/kill_signature.rb +1 -4
  378. data/lib/rigor/protection/measurement_integrity.rb +1 -3
  379. data/lib/rigor/protection/mutation_cache.rb +7 -11
  380. data/lib/rigor/protection/mutation_scanner.rb +12 -15
  381. data/lib/rigor/protection/mutator.rb +2 -1
  382. data/lib/rigor/protection/test_suite_oracle.rb +5 -5
  383. data/lib/rigor/rbs_extended/conformance_checker.rb +4 -3
  384. data/lib/rigor/rbs_extended/envelope_scanner.rb +4 -6
  385. data/lib/rigor/rbs_extended/reporter.rb +36 -10
  386. data/lib/rigor/rbs_extended.rb +88 -21
  387. data/lib/rigor/reflection/constant_ancestors.rb +97 -0
  388. data/lib/rigor/reflection/constant_path.rb +139 -0
  389. data/lib/rigor/reflection.rb +93 -110
  390. data/lib/rigor/runtime/jit.rb +6 -8
  391. data/lib/rigor/scope/discovery_index.rb +165 -2
  392. data/lib/rigor/scope.rb +1041 -32
  393. data/lib/rigor/sig_gen/alias_index.rb +289 -0
  394. data/lib/rigor/sig_gen/classification.rb +22 -5
  395. data/lib/rigor/sig_gen/declaration_equivalence.rb +127 -0
  396. data/lib/rigor/sig_gen/effect_annotation.rb +202 -0
  397. data/lib/rigor/sig_gen/generator.rb +673 -53
  398. data/lib/rigor/sig_gen/inline_declarations.rb +184 -0
  399. data/lib/rigor/sig_gen/layout_index.rb +3 -4
  400. data/lib/rigor/sig_gen/meta_class_shape.rb +3 -5
  401. data/lib/rigor/sig_gen/method_candidate.rb +47 -3
  402. data/lib/rigor/sig_gen/observation_collector.rb +18 -16
  403. data/lib/rigor/sig_gen/path_mapper.rb +4 -6
  404. data/lib/rigor/sig_gen/rbs_validity.rb +4 -4
  405. data/lib/rigor/sig_gen/renderer.rb +128 -14
  406. data/lib/rigor/sig_gen/skip_reason_catalog.rb +154 -0
  407. data/lib/rigor/sig_gen/superclass_spelling.rb +27 -0
  408. data/lib/rigor/sig_gen/type_elaborator.rb +1 -3
  409. data/lib/rigor/sig_gen/write_result.rb +19 -3
  410. data/lib/rigor/sig_gen/writer.rb +189 -41
  411. data/lib/rigor/sig_gen.rb +3 -0
  412. data/lib/rigor/signature_path_audit.rb +153 -6
  413. data/lib/rigor/source/literals.rb +0 -23
  414. data/lib/rigor/source/node_children.rb +0 -2
  415. data/lib/rigor/source/node_locator.rb +5 -11
  416. data/lib/rigor/source/node_walker.rb +0 -6
  417. data/lib/rigor/source/parameter_envelope.rb +72 -0
  418. data/lib/rigor/source.rb +1 -0
  419. data/lib/rigor/triage/catalogue.rb +1 -3
  420. data/lib/rigor/triage.rb +3 -5
  421. data/lib/rigor/type/accepts_result.rb +24 -6
  422. data/lib/rigor/type/combinator.rb +144 -5
  423. data/lib/rigor/type/data_class.rb +2 -2
  424. data/lib/rigor/type/data_instance.rb +4 -4
  425. data/lib/rigor/type/difference.rb +1 -0
  426. data/lib/rigor/type/float_range.rb +128 -0
  427. data/lib/rigor/type/hash_shape.rb +6 -6
  428. data/lib/rigor/type/integer_range.rb +13 -8
  429. data/lib/rigor/type/nominal.rb +8 -2
  430. data/lib/rigor/type/refined.rb +4 -3
  431. data/lib/rigor/type/struct_class.rb +3 -3
  432. data/lib/rigor/type/struct_instance.rb +4 -4
  433. data/lib/rigor/type.rb +1 -0
  434. data/lib/rigor/type_node/generic.rb +1 -1
  435. data/lib/rigor/type_node/range_literal.rb +25 -0
  436. data/lib/rigor/type_node/resolver_chain.rb +1 -1
  437. data/lib/rigor/type_node.rb +1 -0
  438. data/lib/rigor/version.rb +1 -1
  439. data/lib/rigor.rb +1 -0
  440. data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/analyzer.rb +0 -4
  441. data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_discoverer.rb +0 -1
  442. data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_index.rb +0 -2
  443. data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/effects.rb +1 -0
  444. data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +10 -5
  445. data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/analyzer.rb +0 -4
  446. data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_discoverer.rb +3 -5
  447. data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_index.rb +1 -4
  448. data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb +14 -4
  449. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb +32 -30
  450. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_discoverer.rb +0 -1
  451. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_index.rb +1 -3
  452. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_scan.rb +96 -0
  453. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/effects.rb +65 -8
  454. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/erb_compiler.rb +270 -0
  455. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/render_locals.rb +402 -0
  456. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/view_assigns.rb +370 -0
  457. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/view_units.rb +132 -0
  458. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +264 -3
  459. data/plugins/rigor-actionpack/sig/action_controller.rbs +71 -0
  460. data/plugins/rigor-actionpack/sig/action_view.rbs +43 -0
  461. data/plugins/rigor-active-model-serializers/lib/rigor/plugin/active_model_serializers/serializer_discoverer.rb +220 -0
  462. data/plugins/rigor-active-model-serializers/lib/rigor/plugin/active_model_serializers/serializer_index.rb +56 -0
  463. data/plugins/rigor-active-model-serializers/lib/rigor/plugin/active_model_serializers.rb +263 -0
  464. data/plugins/rigor-active-model-serializers/lib/rigor-active-model-serializers.rb +7 -0
  465. data/plugins/rigor-active-model-serializers/sig/active_model_serializers.rbs +45 -0
  466. data/plugins/rigor-activejob/lib/rigor/plugin/activejob/analyzer.rb +0 -4
  467. data/plugins/rigor-activejob/lib/rigor/plugin/activejob/effects.rb +2 -1
  468. data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_discoverer.rb +0 -1
  469. data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_index.rb +0 -2
  470. data/plugins/rigor-activejob/lib/rigor/plugin/activejob/recurring_scan.rb +1 -1
  471. data/plugins/rigor-activejob/lib/rigor/plugin/activejob.rb +10 -5
  472. data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/analyzer.rb +35 -3
  473. data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/effects.rb +72 -12
  474. data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +383 -7
  475. data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_index.rb +14 -6
  476. data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_parser.rb +1 -2
  477. data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/structure_sql_parser.rb +1 -2
  478. data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +322 -41
  479. data/plugins/rigor-activerecord/sig/active_record/framework.rbs +123 -0
  480. data/plugins/rigor-activerecord/sig/active_record/relation.rbs +206 -31
  481. data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +26 -14
  482. data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext/effects.rb +9 -2
  483. data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb +9 -2
  484. data/plugins/rigor-activesupport-core-ext/sig/active_support/core_ext.rbs +290 -19
  485. data/plugins/rigor-devise/lib/rigor/plugin/devise.rb +1 -0
  486. data/plugins/rigor-dry-monads/lib/rigor/plugin/dry_monads.rb +3 -0
  487. data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema/schema_scanner.rb +9 -7
  488. data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema.rb +7 -3
  489. data/plugins/rigor-dry-struct/lib/rigor/plugin/dry_struct.rb +1 -0
  490. data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types/alias_scanner.rb +8 -6
  491. data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types.rb +11 -7
  492. data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation/contract_scanner.rb +13 -11
  493. data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation.rb +9 -4
  494. data/plugins/rigor-ethon/lib/rigor/plugin/ethon.rb +2 -0
  495. data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/analyzer.rb +0 -5
  496. data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_discoverer.rb +0 -1
  497. data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_index.rb +0 -1
  498. data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot.rb +8 -1
  499. data/plugins/rigor-ffi/lib/rigor/plugin/ffi/types.rb +1 -1
  500. data/plugins/rigor-ffi/lib/rigor/plugin/ffi.rb +36 -4
  501. data/plugins/rigor-ffi-rzmq/lib/rigor/plugin/ffi_rzmq.rb +1 -0
  502. data/plugins/rigor-grape/lib/rigor/plugin/grape.rb +141 -0
  503. data/plugins/rigor-grape/lib/rigor-grape.rb +6 -0
  504. data/plugins/rigor-grape/sig/grape.rbs +263 -0
  505. data/plugins/rigor-graphql/lib/rigor/plugin/graphql/type_scanner.rb +8 -6
  506. data/plugins/rigor-graphql/lib/rigor/plugin/graphql.rb +78 -5
  507. data/plugins/rigor-graphql/sig/graphql.rbs +485 -0
  508. data/plugins/rigor-hanami/lib/rigor/plugin/hanami.rb +1 -0
  509. data/plugins/rigor-mangrove/lib/rigor/plugin/mangrove.rb +2 -1
  510. data/plugins/rigor-minitest/lib/rigor/plugin/minitest/assertion_analyzer.rb +2 -3
  511. data/plugins/rigor-minitest/lib/rigor/plugin/minitest.rb +1 -0
  512. data/plugins/rigor-pundit/lib/rigor/plugin/pundit/analyzer.rb +0 -5
  513. data/plugins/rigor-pundit/lib/rigor/plugin/pundit/authorization_scan.rb +2 -2
  514. data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_discoverer.rb +0 -1
  515. data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_index.rb +0 -1
  516. data/plugins/rigor-pundit/lib/rigor/plugin/pundit.rb +12 -7
  517. data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/analyzer.rb +0 -12
  518. data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_index.rb +1 -3
  519. data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_loader.rb +0 -1
  520. data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n.rb +36 -37
  521. data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/acronyms.rb +5 -5
  522. data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/analyzer.rb +0 -10
  523. data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/devise_routes.rb +5 -3
  524. data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/doorkeeper_routes.rb +3 -2
  525. data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/grape_api_discoverer.rb +2 -2
  526. data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_discoverer.rb +2 -2
  527. data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_table.rb +9 -10
  528. data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/routes_parser.rb +2 -3
  529. data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +10 -17
  530. data/plugins/rigor-railties/lib/rigor/plugin/railties.rb +1 -0
  531. data/plugins/rigor-rbnacl/lib/rigor/plugin/rbnacl.rb +13 -1
  532. data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline/same_line_annotations.rb +149 -0
  533. data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb +324 -18
  534. data/plugins/rigor-rspec/lib/rigor/plugin/rspec/analyzer.rb +0 -3
  535. data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_scope_index.rb +0 -3
  536. data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_type_resolver.rb +1 -5
  537. data/plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb +2 -3
  538. data/plugins/rigor-rspec/lib/rigor/plugin/rspec.rb +1 -0
  539. data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails/have_http_status_analyzer.rb +0 -3
  540. data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails.rb +1 -0
  541. data/plugins/rigor-sassc/lib/rigor/plugin/sassc.rb +1 -0
  542. data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers/analyzer.rb +1 -9
  543. data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers.rb +1 -0
  544. data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/analyzer.rb +0 -4
  545. data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/effects.rb +1 -1
  546. data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/schedule_scan.rb +2 -1
  547. data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_discoverer.rb +0 -1
  548. data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_index.rb +0 -2
  549. data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq.rb +10 -5
  550. data/plugins/rigor-sinatra/lib/rigor/plugin/sinatra.rb +1 -0
  551. data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/absurd_recognizer.rb +2 -5
  552. data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/assertion_recognizer.rb +1 -4
  553. data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog.rb +3 -9
  554. data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog_walker.rb +4 -4
  555. data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sig_parser.rb +1 -2
  556. data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sigil_detector.rb +3 -5
  557. data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/type_translator.rb +7 -5
  558. data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +51 -6
  559. data/plugins/rigor-sorbet/sig/sorbet.rbs +277 -0
  560. data/plugins/rigor-statesman/lib/rigor/plugin/statesman.rb +1 -0
  561. data/sig/rigor/analysis/baseline.rbs +69 -7
  562. data/sig/rigor/analysis/fact_store.rbs +1 -1
  563. data/sig/rigor/analysis/project_scan.rbs +74 -0
  564. data/sig/rigor/analysis/reachability/scan_cache.rbs +12 -0
  565. data/sig/rigor/cache.rbs +2 -3
  566. data/sig/rigor/effects/config_envelopes.rbs +100 -0
  567. data/sig/rigor/effects/effect_table.rbs +60 -0
  568. data/sig/rigor/effects/envelope.rbs +97 -0
  569. data/sig/rigor/effects/envelope_index.rbs +33 -0
  570. data/sig/rigor/effects/file_collection.rbs +81 -0
  571. data/sig/rigor/effects/label.rbs +26 -0
  572. data/sig/rigor/effects/label_set.rbs +46 -0
  573. data/sig/rigor/effects/method_key.rbs +24 -0
  574. data/sig/rigor/effects/origin.rbs +50 -0
  575. data/sig/rigor/effects/plugin_facts.rbs +141 -0
  576. data/sig/rigor/effects/registry.rbs +68 -0
  577. data/sig/rigor/effects/summary.rbs +50 -0
  578. data/sig/rigor/effects/taint_cause.rbs +12 -0
  579. data/sig/rigor/environment.rbs +17 -10
  580. data/sig/rigor/inference/optimistic_origin.rbs +10 -0
  581. data/sig/rigor/inference.rbs +9 -14
  582. data/sig/rigor/plugin/additional_initializer.rbs +36 -0
  583. data/sig/rigor/plugin/base.rbs +30 -7
  584. data/sig/rigor/plugin/effect_ancestry.rbs +27 -0
  585. data/sig/rigor/plugin/effect_attribution.rbs +66 -0
  586. data/sig/rigor/plugin/effect_edge.rbs +33 -0
  587. data/sig/rigor/plugin/effect_entry_points.rbs +25 -0
  588. data/sig/rigor/plugin/io_boundary.rbs +4 -0
  589. data/sig/rigor/plugin/loader.rbs +3 -3
  590. data/sig/rigor/plugin/manifest.rbs +51 -11
  591. data/sig/rigor/plugin/protocol_contract.rbs +68 -0
  592. data/sig/rigor/plugin/registry.rbs +62 -1
  593. data/sig/rigor/plugin.rbs +1 -1
  594. data/sig/rigor/rbs_extended.rbs +1 -1
  595. data/sig/rigor/reflection.rbs +9 -6
  596. data/sig/rigor/scope.rbs +148 -12
  597. data/sig/rigor/sig_gen/skip_reason_catalog.rbs +21 -0
  598. data/sig/rigor/source.rbs +4 -4
  599. data/sig/rigor/testing.rbs +10 -4
  600. data/sig/rigor/type.rbs +33 -1
  601. data/sig/rigor.rbs +39 -20
  602. data/skills/rigor-ask/SKILL.md +16 -11
  603. data/skills/rigor-baseline-reduce/SKILL.md +4 -6
  604. data/skills/rigor-ci-setup/SKILL.md +17 -21
  605. data/skills/rigor-doctor/SKILL.md +24 -22
  606. data/skills/rigor-doctor/references/01-checks.md +97 -33
  607. data/skills/rigor-editor-setup/SKILL.md +6 -4
  608. data/skills/rigor-mcp-setup/SKILL.md +5 -4
  609. data/skills/rigor-monkeypatch-resolve/SKILL.md +5 -3
  610. data/skills/rigor-next-steps/SKILL.md +4 -2
  611. data/skills/rigor-plugin-author/SKILL.md +19 -23
  612. data/skills/rigor-plugin-author/references/01-plan-and-scaffold.md +9 -8
  613. data/skills/rigor-plugin-author/references/02-walker-and-types.md +25 -27
  614. data/skills/rigor-plugin-author/references/03-test-and-ship.md +6 -8
  615. data/skills/rigor-plugin-review/SKILL.md +6 -4
  616. data/skills/rigor-plugin-review/references/01-best-practices-checklist.md +2 -1
  617. data/skills/rigor-plugin-tune/SKILL.md +4 -2
  618. data/skills/rigor-project-init/SKILL.md +15 -10
  619. data/skills/rigor-project-init/references/01-detect.md +13 -9
  620. data/skills/rigor-project-init/references/02-configure.md +43 -14
  621. data/skills/rigor-project-init/references/03-baseline-and-bugs.md +14 -14
  622. data/skills/rigor-project-init/references/04-sig-uplift.md +27 -14
  623. data/skills/rigor-project-init/references/06-agent-contract.md +67 -0
  624. data/skills/rigor-protection-uplift/SKILL.md +4 -6
  625. data/skills/rigor-rbs-setup/SKILL.md +4 -2
  626. data/skills/rigor-type-oracle/SKILL.md +226 -0
  627. data/skills/rigor-type-oracle/references/01-oracle-commands.md +265 -0
  628. data/skills/rigor-type-oracle/references/02-agents-md-fragment.md +52 -0
  629. data/skills/rigor-type-oracle/references/03-gap-protocol.md +125 -0
  630. data/skills/rigor-unused-adjudicate/SKILL.md +12 -7
  631. data/skills/rigor-upgrade/SKILL.md +13 -8
  632. metadata +133 -3
  633. data/lib/rigor/cli/probe_environment.rb +0 -85
  634. data/sig/rigor/inference/builtins/numeric_catalog.rbs +0 -3
@@ -0,0 +1,265 @@
1
+ # 01 — The oracle commands, exactly
2
+
3
+ Every command form here was taken from `rigor <cmd> --help` on the
4
+ version this file ships with. If a flag below is missing from your
5
+ `--help`, trust `--help`.
6
+
7
+ All five commands are **read-only**: they analyse and print. None of them
8
+ writes to your source tree. (`rigor sig-gen --write` does, and is the one
9
+ form this skill never reaches for on its own — see § "Writing, not just
10
+ reading".)
11
+
12
+ ## `rigor type-of` — the type of one expression
13
+
14
+ ```sh
15
+ rigor type-of FILE:LINE[:COL] [FILE:LINE[:COL] ...]
16
+ ```
17
+
18
+ | Option | Effect |
19
+ | --- | --- |
20
+ | `--format=text\|json` | `text` (default) or a JSON object per position. |
21
+ | `--trace` | Also record fail-soft fallbacks via the tracer. |
22
+ | `--config=PATH` | Explicit `.rigor.yml`. |
23
+ | `--tmp-file=PATH` / `--instead-of=PATH` | Editor mode: analyse an unsaved buffer as if it were the project path. Paired. |
24
+
25
+ **Position syntax.** `FILE:LINE:COL`, both **1-based**. The column may be
26
+ omitted (`FILE:LINE`). Several positions in one invocation — that is the
27
+ cheap way to ask about a whole method.
28
+
29
+ Text output:
30
+
31
+ ```
32
+ lib/demo/budget_ledger.rb:19:7
33
+ node: Prism::LocalVariableWriteNode
34
+ type: Array[Dynamic[top]]
35
+ erased: Array[untyped]
36
+ ```
37
+
38
+ - `node` — the Prism node the position resolved to. Check it: if it is
39
+ not the expression you meant, your column is off, and the `type` below
40
+ it answers a different question.
41
+ - `type` — Rigor's internal type. **This is the answer.**
42
+ - `erased` — the same type spelled as RBS. **This is what you write into
43
+ a `.rbs` file or an annotation.** `Dynamic[top]` erases to `untyped`.
44
+
45
+ JSON output is the same five fields:
46
+
47
+ ```json
48
+ { "file": "…", "line": 19, "column": 7,
49
+ "node": "Prism::LocalVariableWriteNode",
50
+ "type": "Array[Dynamic[top]]", "erased": "Array[untyped]" }
51
+ ```
52
+
53
+ ## `rigor annotate` — every line of a file at once
54
+
55
+ ```sh
56
+ rigor annotate FILE
57
+ ```
58
+
59
+ | Option | Effect |
60
+ | --- | --- |
61
+ | `--format=text\|json` | `text` (default), or JSON as a `{ line => type }` map. |
62
+ | `--[no-]color` | Force / disable ANSI colour (auto-detects a tty; honours `NO_COLOR`). |
63
+ | `--[no-]bat` | Force / disable highlighting through `bat`. |
64
+ | `--config=PATH` | Explicit `.rigor.yml`. |
65
+
66
+ Output is the source with each line's **last-expression type** appended
67
+ after `#=>`:
68
+
69
+ ```ruby
70
+ def initialize(currency, opening_balance: 0) #=> Dynamic[top]
71
+ @currency = currency #=> Dynamic[top]
72
+ @entries = [] #=> []
73
+ end #=> :initialize
74
+ ```
75
+
76
+ Two reading rules that catch people out:
77
+
78
+ - `#=>` is the type of the line's **last expression**, not of the
79
+ variable being assigned and not of the method being defined. A `def`
80
+ line's `#=>` is the *return* type of the method; the `end` line's
81
+ `#=>` is the symbol the `def` expression itself evaluates to
82
+ (`:initialize`) — that is Ruby, not a Rigor quirk. Ignore it.
83
+ - One `#=>` per line. For a multi-expression line, or for a
84
+ sub-expression in the middle, go back to `type-of` with a column.
85
+
86
+ Reach for `annotate` first when the task is "document this file" or "add
87
+ types to this class": one call types everything, and the lines that come
88
+ back `Dynamic[top]` are your gap list before you have written a word.
89
+
90
+ ## `rigor sig-gen` — the signature of a method
91
+
92
+ ```sh
93
+ rigor sig-gen [paths]
94
+ ```
95
+
96
+ | Option | Effect |
97
+ | --- | --- |
98
+ | `--print` | RBS to stdout. **Default** — you may omit it. |
99
+ | `--diff` | Unified diff against the existing RBS. Read-only. |
100
+ | `--write` | Write to `sig/<path>.rbs`. The only mode that touches the filesystem. |
101
+ | `--overwrite` | Allow a tighter return to replace user-authored RBS. |
102
+ | `--include-private` | Emit private / protected instance methods too (default: public only). |
103
+ | `--params=untyped\|observed\|observed-strict` | Parameter policy. Default `untyped`. `observed-strict` is reserved and currently a usage error. |
104
+ | `--observe=PATH` | Directory / file to scan for call-site observations. Repeatable. Defaults to the configured `test_paths:` (unset: whichever of `spec/` and `test/` exist). |
105
+ | `--new-files` / `--new-methods` / `--tighter-returns` | Emit only that classification. |
106
+ | `--format=text\|json` | Text RBS, or the structured candidate report. |
107
+ | `--config=PATH` | Explicit `.rigor.yml`. |
108
+
109
+ Text output is RBS you paste as-is:
110
+
111
+ ```
112
+ class Demo::BudgetLedger
113
+ # [new]
114
+ def record: (untyped, ?memo: untyped, ?at: untyped) -> Demo::BudgetLedger
115
+ # [new]
116
+ def entries_matching: (untyped) -> (Array[untyped] | [])
117
+ end
118
+ ```
119
+
120
+ **Read stderr.** A skip summary goes there, not to stdout:
121
+
122
+ ```
123
+ rigor sig-gen: skipped 2 method(s) it could not type or would not overwrite
124
+ (sig.skipped.untyped-return: 2). Run with --format=json to see each one with
125
+ its skip_reason.
126
+ ```
127
+
128
+ A method that is missing from the printed RBS was **skipped**, and a
129
+ skip is a finding. `--format=json` names each one:
130
+
131
+ ```json
132
+ { "class": "Demo::BudgetLedger", "method": "balance", "kind": "instance",
133
+ "classification": "skipped", "skip_reason": "sig.skipped.untyped-return" }
134
+ ```
135
+
136
+ Classifications (the JSON `classification` values): `new_file`,
137
+ `new_method`, `tighter_return`, `equivalent` (nothing to tighten;
138
+ silently dropped), `skipped`. Skip reasons and what
139
+ each one means for you: [`03-gap-protocol.md`](03-gap-protocol.md).
140
+
141
+ ### Deriving a parameter type from call sites
142
+
143
+ ```sh
144
+ rigor sig-gen --print --params=observed --observe spec lib/demo/budget_ledger.rb
145
+ ```
146
+
147
+ `observed` collects argument types from every call site under the
148
+ `--observe` paths, unions them per parameter position, and emits the
149
+ union. The recogniser understands RSpec shapes — `RSpec.describe Foo`,
150
+ bare `describe Foo`, `subject { … }` / `subject(:name) { … }`,
151
+ `let(:name)` / `let!(:name)`, and `described_class.new(...)` — so a
152
+ normal spec suite is already an observation corpus. No plugin needed.
153
+
154
+ The result is *evidence*, and it is narrow evidence:
155
+
156
+ ```
157
+ def initialize: ("JPY", ?opening_balance: 100) -> void
158
+ def entries_matching: (Regexp) -> (Array[untyped] | [])
159
+ ```
160
+
161
+ `(Regexp)` is a real derivation and adoptable. `("JPY")` and `100` are
162
+ literal types — the union of what today's callers happen to pass, frozen
163
+ as a contract. Widen those to the class before adopting
164
+ (`String`, `Integer`), per [ADR-5](https://github.com/rigortype/rigor/blob/master/docs/adr/5-robustness-principle.md):
165
+ lenient on parameters. The gate on any widening is that `rigor check`
166
+ gains no new diagnostic.
167
+
168
+ ### Writing, not just reading
169
+
170
+ This skill's job ends at *knowing* the type. `--write` is an edit to the
171
+ project and belongs to whoever asked for it — propose `--diff` first, and
172
+ run `rigor check` after. `--write` only ever writes inside the configured
173
+ signature paths (`sig/` by default).
174
+
175
+ ## `rigor trace` — why the type is what it is
176
+
177
+ ```sh
178
+ rigor trace FILE
179
+ ```
180
+
181
+ | Option | Effect |
182
+ | --- | --- |
183
+ | `--format=text\|json` | `text` is an interactive animation; **use `json`** for the raw event stream. |
184
+ | `--line=N` | Only replay events whose source range starts on line `N`. |
185
+ | `--verbose` | Include every expression enter/result frame. |
186
+ | `--delay=SECONDS` | Autoplay the text animation (default: step on key press). |
187
+ | `--config=PATH` | Explicit `.rigor.yml`. |
188
+
189
+ An agent wants `--format=json --line=N`: the text mode waits on
190
+ keystrokes. Each event carries `kind`, `depth`, a `location`, the node
191
+ `stack`, and a `data` payload — a `bind` event, for example, names the
192
+ local and the type it received:
193
+
194
+ ```json
195
+ { "kind": "bind", "depth": 2,
196
+ "location": { "start_line": 20, "start_column": 25, "…": "…" },
197
+ "stack": ["CallNode", "CallNode"],
198
+ "data": { "name": "amount", "type": "Dynamic[top]" } }
199
+ ```
200
+
201
+ Reach for it when `type-of` gave you `Dynamic[top]` and you need to name
202
+ *where* the precision was lost before reporting the gap.
203
+
204
+ ## `rigor explain` — what a diagnostic rule means
205
+
206
+ ```sh
207
+ rigor explain [<rule>]
208
+ ```
209
+
210
+ | Option | Effect |
211
+ | --- | --- |
212
+ | `--format=text\|json` | Default `text`. |
213
+
214
+ With no argument it lists every rule. With a rule id, a legacy alias, or
215
+ a family prefix (`call`, `flow`, `assert`, `dump`, `def`) it prints the
216
+ rule's firing conditions, the severity per profile, the evidence tier,
217
+ and how to suppress it.
218
+
219
+ **`explain` has two catalogues.** A `sig.skipped.*` id is a sig-gen
220
+ *skip reason*, not a diagnostic rule, but `rigor explain
221
+ sig.skipped.untyped-return` answers it from a second catalogue (no
222
+ severity, no profile, nothing to suppress). The table in
223
+ [`03-gap-protocol.md`](03-gap-protocol.md) is the summary.
224
+
225
+ ## `rigor check` — the gate, not the oracle
226
+
227
+ ```sh
228
+ rigor check [paths]
229
+ ```
230
+
231
+ You need one flag family here: `--format=text|json|sarif|github|gitlab|checkstyle|junit|teamcity`,
232
+ plus `--explain` to surface fail-soft fallback events as `:info`
233
+ diagnostics. Everything else (`--baseline*`, `--workers`, `--incremental`,
234
+ the cache flags) belongs to other skills.
235
+
236
+ `check` never *sources* a type. Its role here is the verification half:
237
+ after any annotation lands, `rigor check PATHS` must gain **no new
238
+ diagnostic** versus before. Green is a non-contradiction proof, not a
239
+ correctness proof — say which lines it actually covers.
240
+
241
+ ## The MCP tools
242
+
243
+ With the Rigor MCP server wired up (`rigor-mcp-setup`), the same oracle
244
+ is available as tool calls. Prefer them over shelling out; the results
245
+ are the CLI's, so read them exactly as above.
246
+
247
+ | Tool | Required arguments | Optional | Returns |
248
+ | --- | --- | --- | --- |
249
+ | `rigor_type_of` | `file` (string), `line` (integer, 1-based), `col` (integer, 1-based) | `config` | The inferred type at that location. |
250
+ | `rigor_annotate` | `file` (string) | `config` | The source with each line's last-expression type appended. |
251
+ | `rigor_sig_gen` | — (defaults to the configured paths) | `paths` (array of strings), `params` (`"untyped"` \| `"observed"`), `config` | The JSON candidate report — classifications, `rbs`, `inferred_return`, `skip_reason`. |
252
+ | `rigor_check` | `paths` (array of strings) | `config` | The JSON diagnostic report. |
253
+ | `rigor_explain` | — (omit `rule` to list every rule) | `rule` (string) | The rule catalogue entry, as JSON. |
254
+
255
+ Two shape differences from the CLI worth knowing:
256
+
257
+ - `rigor_sig_gen` returns the **JSON candidate report**, always — there
258
+ is no `--print` text mode and no `--diff`. Read `rbs` per candidate.
259
+ - `rigor_sig_gen` exposes `params` but **not** `observe`; observation
260
+ reads the configured `test_paths:` (unset: whichever of `spec/` and
261
+ `test/` exist). To observe anything else, declare it in `test_paths:`
262
+ or use the CLI's `--observe`.
263
+
264
+ `rigor_triage` and `rigor_coverage` are also served, and belong to
265
+ `rigor-baseline-reduce` / `rigor-protection-uplift` rather than here.
@@ -0,0 +1,52 @@
1
+ # 02 — The paragraph to keep in the project's agent contract
2
+
3
+ A skill only binds an agent that loaded it. The rule below binds every
4
+ session, because it lives in the file the agent reads at startup —
5
+ `AGENTS.md`, or `CLAUDE.md` for Claude Code (which pulls `AGENTS.md` in
6
+ with `@AGENTS.md` when both exist).
7
+
8
+ Paste it verbatim. `rigor-project-init` installs it during onboarding; if
9
+ the project is already onboarded, add it now.
10
+
11
+ ## Where it goes
12
+
13
+ - **`AGENTS.md` exists** → append the section at the end. Do not
14
+ reorganise the file.
15
+ - **Only `CLAUDE.md` exists** → append it there.
16
+ - **Both exist** → put it in `AGENTS.md`; add `@AGENTS.md` to `CLAUDE.md`
17
+ only if it is not already pulled in.
18
+ - **Neither exists** → create `AGENTS.md` with this as its first section.
19
+ - **A "Types" / "Type checking" section already exists** → merge into it
20
+ rather than adding a second one, and keep the five bullets intact.
21
+
22
+ Never overwrite unrelated content, and never rewrite a rule the project
23
+ already wrote for itself — show the user the conflict instead.
24
+
25
+ ## The fragment
26
+
27
+ ```markdown
28
+ ## Types come from Rigor, not from reading code
29
+
30
+ This project is type-checked by [Rigor](https://github.com/rigortype/rigor). A type you did not obtain from Rigor is a guess, and a guessed type is never written anywhere: not in `sig/`, not in an inline annotation (`#:`, `# @rbs`), not in a doc comment, not in a review comment, and not as the reason for a nil check or an `is_a?` guard.
31
+
32
+ - The type of an expression: `rigor type-of FILE:LINE:COL`, or `rigor annotate FILE` for a whole file.
33
+ - The signature of a method: `rigor sig-gen --print FILE`; paste what it prints, never what you expect.
34
+ - A parameter type is the one thing inference does not give you: derive it from the call sites with `rigor sig-gen --observe PATH` and keep it only while `rigor check` stays green.
35
+ - When Rigor answers `Dynamic[top]` or `untyped`, or `sig-gen` skips the method, do not fill the gap. Report the exact command and its output; the gap is the finding.
36
+ - Every type you state to a human carries the command that produced it, so it can be re-run.
37
+
38
+ The `rigor-type-oracle` skill (`rigor skill --full rigor-type-oracle`) has the full procedure. With the Rigor MCP server connected, `rigor_type_of`, `rigor_annotate`, and `rigor_sig_gen` are the same oracle as tool calls.
39
+ ```
40
+
41
+ ## Two notes for whoever installs it
42
+
43
+ - **The single-long-line shape is deliberate.** Each bullet is one line,
44
+ however long. Some of these files are rendered as Markdown by tools
45
+ that turn a newline inside a paragraph into a line break, so a
46
+ column-wrapped bullet reads ragged. Do not re-wrap it to fit an editor
47
+ ruler.
48
+ - **Tell the user it landed.** It is a change to the file that governs
49
+ every future agent session in the repo — it belongs in the "here is
50
+ what I created, and whether to commit it" report, not in a silent diff.
51
+ It should be committed: the point is that every contributor's agent
52
+ reads the same rule.
@@ -0,0 +1,125 @@
1
+ # 03 — The gap protocol
2
+
3
+ Rigor answering "I don't know" is not the oracle failing. It is the
4
+ oracle telling you something the code alone would not have: precision is
5
+ lost *here*, for *this* reason. That is worth more than the annotation
6
+ you were about to write, and it is worth exactly nothing if you paper
7
+ over it.
8
+
9
+ **The rule: never convert a gap into a type.** Report it, locate it,
10
+ route it.
11
+
12
+ ## Which output means which gap
13
+
14
+ ### `Dynamic[top]` (erased: `untyped`)
15
+
16
+ Rigor has no class information for this expression at all. It is the
17
+ top type, and it is contagious: a `Dynamic[top]` receiver makes every
18
+ method call on it `Dynamic[top]` too, so one unresolved source can
19
+ account for a whole file of "unknown".
20
+
21
+ Common causes, in the order worth checking:
22
+
23
+ - A **method parameter** — parameters are `untyped` by design unless RBS
24
+ or observation says otherwise. Not a defect; use call-site derivation.
25
+ - An **ivar** assigned from a parameter (`@currency = currency`) — the
26
+ same gap, one hop later.
27
+ - A call into a **gem with no RBS** — the dominant cause on a real
28
+ project.
29
+ - A call into a **framework Rigor is not configured for** — Rails
30
+ without the Rails plugins enabled, say.
31
+ - The project's **own monkey-patch or DSL**, which the analyzer never saw
32
+ defined.
33
+
34
+ ### `untyped` inside an otherwise-precise type
35
+
36
+ `Array[untyped]`, `Hash[Symbol, untyped]`: the container is proven, the
37
+ element is not. Write the container. Do **not** invent the element — an
38
+ `Array[String]` you guessed is worse than the `Array[untyped]` Rigor
39
+ proved, because it will be believed.
40
+
41
+ ### A method missing from `sig-gen` output — the `sig.skipped.*` reasons
42
+
43
+ Read stderr for the count, `--format=json` for the per-method reason.
44
+
45
+ | Reason | What it means | What you do |
46
+ | --- | --- | --- |
47
+ | `sig.skipped.untyped-return` | The body's last expression types as `Dynamic[top]`; emitting `untyped` would be noise. | The commonest gap. Trace the return expression back to its `Dynamic[top]` source and route *that*. Never write a return type here. |
48
+ | `sig.skipped.user-authored` | An RBS declaration already exists and `--overwrite` was not given. | Not a gap. The hand-written type is the project's answer — read `sig/`, and if it disagrees with inference, raise the disagreement rather than silently retyping. |
49
+ | `sig.skipped.unrenderable-rbs` | Rigor rendered a signature that does not parse as RBS, so it was dropped rather than written. | **A bug in Rigor**, not in the code. Report it with the method and the file. |
50
+ | `sig.skipped.complex-shape` | Reserved; the generator does not produce it today. | If you ever see one, it is worth reporting as a surprise. |
51
+ | `skipped_outside_sig_root` | A `--write` target outside the configured signature paths. | Configuration, not inference. |
52
+
53
+ `rigor explain <id>` answers each of these ids directly (the command
54
+ carries a second catalogue for the skip reasons alongside the
55
+ diagnostic rules); this table is the summary.
56
+
57
+ ### `equivalent`, and silence
58
+
59
+ A `tighter-return` candidate that never appears was classified
60
+ `equivalent`: the inferred return is not a strict subtype of what `sig/`
61
+ already declares. The existing declaration stands. Silence here means
62
+ "nothing to change", not "nothing is known" — check `sig/` before calling
63
+ it a gap.
64
+
65
+ ## Locating the gap before you report it
66
+
67
+ Two commands turn "somewhere upstream" into a line number.
68
+
69
+ ```sh
70
+ rigor annotate FILE # walk the #=> column upward to the first Dynamic[top]
71
+ rigor trace --format=json --line=N FILE
72
+ ```
73
+
74
+ `annotate` is usually enough: the first line in the chain that reports
75
+ `Dynamic[top]` is the source, and everything below it is cascade. Use
76
+ `trace` when the loss happens *within* a line — its `bind` events name
77
+ each local and the type it received, so you can see which argument
78
+ arrived unknown.
79
+
80
+ If a diagnostic fired near the site, `rigor explain <rule>` gives its
81
+ firing conditions, which frequently name the cause outright.
82
+
83
+ ## Routing table — project-side gaps have an owner
84
+
85
+ Once you know the source, the fix is almost never "write the type here".
86
+
87
+ | The gap's source | Route to | Why |
88
+ | --- | --- | --- |
89
+ | A dependency gem ships no RBS | **`rigor-rbs-setup`** | `rbs collection install` brings in community RBS; this is the single biggest `Dynamic` reduction on most projects. |
90
+ | A framework Rigor isn't configured for (Rails, RSpec, dry-rb…) | **`rigor-plugin-tune`** | The bundled plugin for it is probably just not enabled in `.rigor.dist.yml`. |
91
+ | `undefined-method` on the project's own monkey-patches | **`rigor-monkeypatch-resolve`** | Wiring the defining files into `pre_eval:` makes them visible. |
92
+ | The project's own DSL / `define_method` factory / `method_missing` | **`rigor-plugin-author`** | Rigor does not bundle per-application plugins; a project-owned plugin is the durable fix. |
93
+ | The site is protected-coverage work, not a documentation task | **`rigor-protection-uplift`** | It owns the "minimal true annotation + double gate" loop. |
94
+ | The setup itself looks wrong (zero RBS classes, config not taking) | **`rigor-doctor`** | Validate before concluding anything about inference. |
95
+ | None of the above — Rigor should have inferred this | A Rigor issue | See below. |
96
+
97
+ Offer the route; do not silently switch tasks. The user asked you to
98
+ document a class, and "the reason I cannot is X, and here is the skill
99
+ that fixes X" is the answer to that request.
100
+
101
+ ## Reporting an engine-side gap
102
+
103
+ When the type is derivable from the source and Rigor still says
104
+ `Dynamic[top]`, that is a completeness gap in the engine, and it is worth
105
+ more to the project than any annotation. File it at
106
+ <https://github.com/rigortype/rigor/issues> with these five parts:
107
+
108
+ 1. **The file and line** — the smallest reproduction you can get to,
109
+ ideally a standalone snippet rather than a pointer into a private
110
+ repo.
111
+ 2. **The exact command**, as run: `rigor type-of demo.rb:12:5`,
112
+ `rigor sig-gen --print demo.rb`.
113
+ 3. **The exact output**, pasted, including the stderr skip line.
114
+ 4. **What the correct type is, and what proves it** — the Ruby-level
115
+ reasoning a reader can verify. "`Array#sum` over `Integer` elements is
116
+ `Integer`", not "it should obviously be Integer".
117
+ 5. **What the report proves** — one sentence naming the *class* of gap,
118
+ not just the instance: "block-parameter destructuring loses the
119
+ element type", "a keyword default of `Time.now` does not seed the
120
+ parameter". This is the part that makes the issue actionable, because
121
+ it says what a fix would generalise to.
122
+
123
+ Also say `rigor --version`, and note whether `sig/` and the relevant
124
+ plugins were in play — a gap that only appears without community RBS is a
125
+ different bug from one that survives it.
@@ -1,7 +1,9 @@
1
1
  ---
2
2
  name: rigor-unused-adjudicate
3
- description: |
4
- Find dead code in a Ruby project with `rigor unused` — establish what the report can see on THIS project first, then adjudicate every row before proposing any deletion. Use this whenever someone asks to find or remove dead code, unused classes, unused constants, or "code nobody calls", whenever they ask what a `rigor unused` report means or which rows are safe to delete, and whenever a dead-code cleanup, codebase inventory, or legacy audit comes up — even if they never say "rigor". The report is a review queue and not a defect list; on an adjudicated corpus target only 4 of 57 rows were genuinely dead, so acting on it directly produces mostly wrong deletions. NOT for deleting a specific class you already know is dead, and NOT for `rigor check` diagnostics (those are ordinary type errors).
3
+ description: >-
4
+ Adjudicate a `rigor unused` report safely before proposing dead-code removal. Use when interpreting or
5
+ reviewing Rigor's unused classes/modules/constants, or when a cleanup is based on that report; not for
6
+ a specific deletion already known to be safe or for ordinary `rigor check` diagnostics.
5
7
  license: MPL-2.0
6
8
  metadata:
7
9
  version: 0.2.0
@@ -31,11 +33,14 @@ and skipping one is how a live class ends up on a deletion list.
31
33
 
32
34
  Run the report and answer these against the project in front of you.
33
35
 
34
- **Are framework roots actually supplied?** The summary prints
35
- `roots: N (M from plugins, …)`. On a framework application `0 from plugins`
36
- means nothing is naming your controllers, jobs or policies, so most of the
37
- report is noise. Stop and fix the plugin configuration — `rigor docs
38
- 07-plugins` — rather than adjudicating hundreds of rows.
36
+ **Are framework roots actually supplied?** When a plugin contributes roots, the
37
+ summary's `roots:` line grows a parenthetical: `roots: N (M from plugins, K
38
+ matched no declaration)`. The parenthetical is omitted entirely when no plugin
39
+ contributed — so on a framework application, a bare `roots: N` with **no**
40
+ `(… from plugins …)` note means nothing is naming your controllers, jobs or
41
+ policies, and most of the report is noise. Stop and fix the plugin
42
+ configuration — `rigor docs 07-plugins` — rather than adjudicating hundreds of
43
+ rows.
39
44
 
40
45
  **Does the project ship signatures?** If `signature_paths:` is configured, also
41
46
  run with it emptied and compare:
@@ -1,7 +1,9 @@
1
1
  ---
2
2
  name: rigor-upgrade
3
- description: |
4
- Adopt a new Rigor version cleanly: after upgrading the `rigortype` gem, re-run the analysis, diff the diagnostics against the committed baseline, and sort the changes into genuine new catches (sharper inference), known sig-quality false positives, and the baseline you should regenerate. Triggers: "I upgraded Rigor, what changed?", "new diagnostics after gem update rigortype", "adopt the new Rigor version", "rigor baseline drifted after upgrade". NOT for first-time setup (use rigor-project-init) or routine baseline work unrelated to an upgrade (use rigor-baseline-reduce).
3
+ description: >-
4
+ Adopt a new `rigortype` version by comparing its diagnostics with the committed baseline and separating
5
+ new catches from signature-quality false positives. Use after a Rigor gem upgrade; not for first-time
6
+ setup or routine baseline reduction.
5
7
  license: MPL-2.0
6
8
  metadata:
7
9
  version: 0.1.0
@@ -50,12 +52,15 @@ rigor --version
50
52
  ### Phase 2 — see the delta against the committed baseline
51
53
 
52
54
  ```sh
53
- rigor check
54
- rigor diff # compare current diagnostics to the saved baseline JSON
55
+ rigor check # everything outside the committed baseline's envelope
56
+ rigor baseline drift # per-bucket movement against .rigor-baseline.yml
55
57
  ```
56
58
 
57
- `rigor diff` shows what is **new** relative to the baseline — that set is
58
- what the upgrade changed.
59
+ With `baseline:` wired, `rigor check` already hides what the baseline
60
+ covers, so what it prints is **new** relative to the baseline — that set
61
+ is what the upgrade changed. `rigor baseline drift` adds the bucket view:
62
+ buckets now over their recorded count, and buckets the new version
63
+ cleared or shrank.
59
64
 
60
65
  ### Phase 3 — sort the new diagnostics
61
66
 
@@ -80,8 +85,8 @@ envelope so the regeneration does not bury what you just fixed:
80
85
  rigor baseline regenerate
81
86
  ```
82
87
 
83
- Commit the updated `.rigor-baseline.yml` together with any fixes, so the
84
- team adopts the same post-upgrade baseline.
88
+ Recommend committing the updated `.rigor-baseline.yml` together with any
89
+ fixes, so the team adopts the same post-upgrade baseline.
85
90
 
86
91
  ## Note
87
92