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,485 @@
1
+ # graphql-ruby class-level DSL surface — bundled by rigor-graphql via
2
+ # the manifest's `signature_paths:` (ADR-25).
3
+ #
4
+ # graphql-ruby ships no RBS of its own, so without this file every
5
+ # `field`/`argument`/`value`/`implements`/`description` call inside a
6
+ # `GraphQL::Schema::*` subclass reads Dynamic[top] — ~5k implicit-self
7
+ # sites on the GitLab checkout alone
8
+ # (docs/notes/20260919-survey-typing-holes.md).
9
+ #
10
+ # Return types follow graphql-ruby's real implementations: `field`
11
+ # returns the created `Schema::Field`, `argument` the created
12
+ # `Schema::Argument`, `Enum.value` the `Schema::EnumValue`, the
13
+ # registration macros on `Schema` return the collection or object they
14
+ # registered, and the setter/getter pairs (`description`,
15
+ # `graphql_name`, `type`, `null`, …) return their configured value.
16
+ # `void` is deliberately avoided — these expressions are ordinary API
17
+ # (a stored `field` result is a real `Field`), and the engine recovers
18
+ # a `void` return as `top`, which would keep every DSL call in the
19
+ # Dynamic census this signature exists to drain.
20
+ #
21
+ # The ancestry follows graphql-ruby's real hierarchy:
22
+ # `Mutation`/`Subscription`/`RelayClassicMutation < Resolver`,
23
+ # `Object`/`InputObject`/`Enum`/`Union`/`Scalar`/`EnumValue <
24
+ # Member`, and `Field`/`Argument` standalone (each `include`s
25
+ # `Member::HasArguments` for their own `argument` DSL). The shared
26
+ # class-level DSL lives on the `Member::*` mixin modules exactly as
27
+ # graphql-ruby arranges it, so user subclasses pick it up by RBS
28
+ # ancestry rather than per-class duplication.
29
+ #
30
+ # Deferred, deliberately:
31
+ #
32
+ # - `include GraphQL::Schema::Interface` — graphql-ruby wires the DSL
33
+ # onto the includer through `Interface.included` →
34
+ # `base.extend(DefinitionMethods)`, an include-time effect RBS
35
+ # cannot express, so `field` inside interface modules stays opaque.
36
+ # `Interface::DefinitionMethods` is still declared so an `extend`
37
+ # of it resolves.
38
+ # - `field ... do ... end` / `argument ... do ... end` block bodies —
39
+ # graphql-ruby `instance_eval`s a zero-arity definition block on the
40
+ # new Field/Argument, and no engine mechanism currently rebinds a
41
+ # block's `self` to a declared block `self:` type. The one-parameter
42
+ # form (`field(:x) { |f| f.argument }`) types through the declared
43
+ # block parameter.
44
+ # - `Schema.execute` / `Schema.multiplex` result typing and
45
+ # resolver-method return checking — tracked by issue #136; they are
46
+ # declared `-> untyped` here so dispatch resolves, but the honestly
47
+ # opaque return is unchanged.
48
+
49
+ module GraphQL
50
+ class Error < ::StandardError
51
+ end
52
+
53
+ class ExecutionError < GraphQL::Error
54
+ def initialize: (untyped message, **untyped opts) -> void
55
+ def extensions: () -> ::Hash[untyped, untyped]
56
+ def to_h: () -> ::Hash[untyped, untyped]
57
+ end
58
+
59
+ class AnalysisError < GraphQL::Error
60
+ end
61
+
62
+ class RequiredImplementationMissingError < GraphQL::Error
63
+ end
64
+
65
+ class UnauthorizedError < GraphQL::Error
66
+ end
67
+
68
+ class Dataloader
69
+ def with: (untyped source_class, *untyped batch_args) -> untyped
70
+ def load: (untyped source_class, untyped id) -> untyped
71
+ def load_all: (untyped source_class, untyped ids) -> ::Array[untyped]
72
+ def append: (untyped job) -> untyped
73
+ def run: () -> untyped
74
+ def run_all: () -> untyped
75
+ def merge!: (untyped) -> untyped
76
+
77
+ class Source
78
+ def load: (untyped input) -> untyped
79
+ def fetch: (untyped inputs) -> ::Array[untyped]
80
+ def result_key_for: (untyped input) -> untyped
81
+ end
82
+ end
83
+
84
+ class Query
85
+ def context: () -> GraphQL::Query::Context
86
+
87
+ class Context
88
+ def []: (untyped key) -> untyped
89
+ def []=: (untyped key, untyped value) -> untyped
90
+ def fetch: (untyped key, ?untyped default) -> untyped
91
+ def key?: (untyped key) -> bool
92
+ def dig: (untyped key, *untyped rest) -> untyped
93
+ def namespace: (untyped ns) -> untyped
94
+ def scoped_set!: (untyped key, untyped value) -> untyped
95
+ def to_h: () -> ::Hash[untyped, untyped]
96
+ def schema: () -> singleton(GraphQL::Schema)
97
+ def query: () -> GraphQL::Query
98
+ def object: () -> untyped
99
+ def dataloader: () -> GraphQL::Dataloader
100
+ def errors: () -> ::Array[untyped]
101
+ def add_error: (untyped error) -> untyped
102
+ end
103
+ end
104
+
105
+ class Schema
106
+ # Schema-class registration DSL (`class AppSchema < GraphQL::Schema`).
107
+ # Setter/getter pairs return the configured value; the `<<`-style
108
+ # registrars return the collection they pushed onto.
109
+ def self.use: (untyped plugin, **untyped kwargs) -> ::Array[untyped]
110
+ def self.plugins: () -> ::Array[untyped]
111
+ def self.query: (?Class? new_query_object) ?{ () -> untyped } -> Class?
112
+ def self.mutation: (?Class? new_mutation_object) ?{ () -> untyped } -> Class?
113
+ def self.subscription: (?Class? new_subscription_object) ?{ () -> untyped } -> Class?
114
+ # Runtime returns the stored Class under a visibility profile, otherwise the
115
+ # `add_type_and_traverse` result — the union is untyped (schema.rb `directive`).
116
+ def self.directive: (untyped new_directive) -> untyped
117
+ def self.directives: (*untyped) -> ::Hash[untyped, untyped]
118
+ def self.orphan_types: (*untyped new_orphan_types) -> ::Array[untyped]
119
+ # `mode:` as an Array re-enters once per element and returns that Array; the
120
+ # default path ends in `add_trace_options_for`, which returns nil.
121
+ def self.trace_with: (untyped trace_mod, **untyped options) -> ::Array[untyped]?
122
+ def self.instrument: (untyped instrument_step, untyped instrumenter, ?untyped options) -> ::Array[untyped]
123
+ # Returns `err_classes.each`'s receiver — the exception-class Array, not the
124
+ # handlers Hash (schema.rb `rescue_from`).
125
+ def self.rescue_from: (*untyped err_classes) ?{ (untyped err) -> void } -> ::Array[untyped]
126
+ def self.error_handlers: () -> ::Hash[untyped, untyped]
127
+ def self.max_depth: (?Integer? new_max_depth, ?count_introspection_fields: bool) -> Integer?
128
+ def self.max_complexity: (?untyped new_max_complexity, ?count_introspection_fields: bool) -> untyped
129
+ def self.max_query_string_tokens: (?Integer? new_max_tokens) -> Integer?
130
+ def self.validate_max_errors: (?Integer? new_validate_max_errors) -> Integer?
131
+
132
+ def self.error_bubbling: (?bool? new_error_bubbling) -> bool
133
+ def self.default_max_page_size: (?Integer? new_default_max_page_size) -> Integer?
134
+ def self.default_page_size: (?Integer? new_default_page_size) -> Integer?
135
+
136
+ def self.cursor_encoder: (?Class? new_encoder) -> Class?
137
+ def self.context_class: (?Class? new_context_class) -> Class?
138
+ def self.connections: (?untyped new_connections) -> untyped
139
+ def self.introspection: (?Module? new_introspection_namespace) -> Module?
140
+ def self.query_analyzer: (untyped new_analyzer) -> ::Array[untyped]
141
+ def self.multiplex_analyzer: (untyped new_analyzer) -> ::Array[untyped]
142
+ def self.query_analyzers: () -> ::Array[untyped]
143
+ def self.multiplex_analyzers: () -> ::Array[untyped]
144
+ def self.visible?: (untyped member, untyped ctx) -> bool
145
+ def self.id_from_object: (untyped application_object, untyped graphql_type, untyped context) -> String?
146
+ def self.object_from_id: (untyped object_id, untyped context) -> untyped
147
+ def self.resolve_type: (untyped abstract_type, untyped obj, untyped ctx) -> untyped
148
+ def self.type_error: (untyped type_error, untyped ctx) -> untyped
149
+ def self.types: (?untyped context) -> ::Hash[untyped, untyped]
150
+ def self.execute: (*untyped) -> untyped
151
+ def self.multiplex: (*untyped) -> untyped
152
+
153
+ # Shared class-level DSL inherited by every schema member class.
154
+ class Member
155
+ module BaseDSLMethods
156
+ def description: (?String? new_description) -> String?
157
+ def graphql_name: (?String? new_name) -> String
158
+ def comment: (?String? new_comment) -> String?
159
+ def introspection: (?untyped new_introspection) -> bool
160
+ def introspection?: () -> bool
161
+ def visible?: (untyped context) -> bool
162
+ def authorized?: (untyped object, untyped context) -> bool
163
+ def mutation: (?Class? mutation_class) -> Class?
164
+ def to_graphql: () -> untyped
165
+ def kind: () -> untyped
166
+ def path: () -> String
167
+ end
168
+ extend BaseDSLMethods
169
+
170
+ module HasArguments
171
+ def argument: ( ?untyped arg_name
172
+ , ?untyped type_expr
173
+ , ?untyped desc
174
+ , **untyped kwargs
175
+ ) ?{ (GraphQL::Schema::Argument) -> void } -> GraphQL::Schema::Argument
176
+ def add_argument: (GraphQL::Schema::Argument arg_defn) -> GraphQL::Schema::Argument
177
+ def arguments: (?untyped context) -> ::Hash[untyped, untyped]
178
+ def get_argument: (untyped argument_name, ?untyped context) -> GraphQL::Schema::Argument?
179
+ def any_arguments?: () -> bool
180
+ def all_argument_definitions: () -> ::Array[untyped]
181
+ def argument_class: (?Class? new_arg_class) -> Class
182
+ end
183
+
184
+ module HasFields
185
+ def field: ( ?untyped name_positional
186
+ , ?untyped type_positional
187
+ , ?untyped desc_positional
188
+ , **untyped kwargs
189
+ ) ?{ (GraphQL::Schema::Field) -> void } -> GraphQL::Schema::Field
190
+ # Runtime ends in a bare `nil` after mutating `own_fields` (has_fields.rb).
191
+ def add_field: (GraphQL::Schema::Field field_defn, **untyped kwargs) -> nil
192
+ def field_class: (?Class? new_field_class) -> Class
193
+ # Ends in `define_singleton_method(field_name)`, which returns the Symbol.
194
+ def global_id_field: (untyped field_name, **untyped kwargs) -> ::Symbol
195
+ def fields: (?untyped context) -> ::Hash[untyped, untyped]
196
+ def get_field: (untyped field_name, ?untyped context) -> GraphQL::Schema::Field?
197
+ end
198
+
199
+ module HasInterfaces
200
+ def implements: (*untyped new_interfaces, **untyped options) -> ::Array[untyped]
201
+ def interfaces: (?untyped context) -> ::Array[untyped]
202
+ def interface_type_memberships: () -> ::Array[untyped]
203
+ end
204
+
205
+ module RelayShortcuts
206
+ def connection_type: () -> Class
207
+ def edge_type: () -> Class
208
+ def connection_type_class: (?Class? new_connection_type_class) -> Class
209
+ def edge_type_class: (?Class? new_edge_type_class) -> Class
210
+ def node_field: (**untyped kwargs) -> GraphQL::Schema::Field
211
+ def nodes_field: (**untyped kwargs) -> GraphQL::Schema::Field
212
+ end
213
+ extend RelayShortcuts
214
+
215
+ module TypeSystemHelpers
216
+ def to_graphql: () -> untyped
217
+ end
218
+ end
219
+
220
+ class Object < Member
221
+ extend Member::HasFields
222
+ extend Member::HasInterfaces
223
+ attr_reader object: untyped
224
+ attr_reader context: GraphQL::Query::Context
225
+ end
226
+
227
+ class Resolver
228
+ module HasPayloadType
229
+ def payload_type: (?Class? new_payload_type) -> Class
230
+ def type: ( ?untyped new_type
231
+ , ?null: bool? null
232
+ ) -> untyped
233
+ def type_expr: () -> untyped
234
+ def null: (?bool? allow_null) -> bool
235
+ def field_class: (?Class? new_class) -> Class
236
+ def object_class: (?Class? new_class) -> Class
237
+ end
238
+ extend Member::BaseDSLMethods
239
+ extend Member::HasArguments
240
+ extend HasPayloadType
241
+
242
+ def self.resolve_method: (?Symbol? new_method) -> Symbol
243
+ def self.resolver_method: (?Symbol? new_method_name) -> Symbol
244
+ def self.extras: (?::Array[untyped]? new_extras) -> ::Array[untyped]
245
+ def self.complexity: (?untyped new_complexity) -> untyped
246
+ def self.broadcastable: (untyped new_broadcastable) -> untyped
247
+ def self.broadcastable?: () -> bool?
248
+ def self.max_page_size: (?Integer? new_max_page_size) -> Integer?
249
+ def self.default_page_size: (?Integer? new_default_page_size) -> Integer?
250
+ def self.has_max_page_size?: () -> bool
251
+ def self.has_default_page_size?: () -> bool
252
+ def self.has_scope: (?untyped new_has_scope) -> bool
253
+ def self.field_arguments: (?untyped context) -> ::Hash[untyped, untyped]
254
+ def self.extension: (untyped extension, **untyped options) -> untyped
255
+ def self.extensions: () -> ::Array[untyped]
256
+ def self.authorizes?: (untyped context) -> bool
257
+
258
+ attr_reader object: untyped
259
+ attr_reader context: GraphQL::Query::Context
260
+ attr_reader field: GraphQL::Schema::Field
261
+ def arguments: () -> ::Hash[untyped, untyped]
262
+ def dataloader: () -> GraphQL::Dataloader
263
+ def resolve: (**untyped args) -> untyped
264
+ def ready?: (**untyped args) -> bool
265
+ def authorized?: (**untyped inputs) -> bool
266
+ def load_application_object: (untyped type, untyped id) -> untyped
267
+ def load_application_object_failed!: (untyped err) -> void
268
+ end
269
+
270
+ class Mutation < Resolver
271
+ extend Member::HasFields
272
+ def self.ready?: (**untyped inputs) -> bool
273
+ def self.authorized?: (**untyped inputs) -> bool
274
+ def self.load_application_object: (untyped type, untyped id) -> untyped
275
+ def object: () -> untyped
276
+ def ready?: (**untyped inputs) -> bool
277
+ def authorized?: (**untyped inputs) -> bool
278
+ end
279
+
280
+ class RelayClassicMutation < Mutation
281
+ def self.input_object_class: (?Class? new_class) -> Class
282
+ def self.return_field: () -> untyped
283
+ end
284
+
285
+ class Subscription < Resolver
286
+ extend Member::HasFields
287
+ def self.topic: (?untyped new_topic) -> untyped
288
+ def self.subscription_scope: (?untyped new_scope) -> untyped
289
+ def subscribe: (**untyped args) -> untyped
290
+ def update: (**untyped args) -> untyped
291
+ def unsubscribe: (**untyped args) -> untyped
292
+ end
293
+
294
+ class InputObject < Member
295
+ extend Member::HasArguments
296
+ def self.prepare: (*untyped) -> untyped
297
+ def self.one_of: () -> bool
298
+ def prepare: () -> untyped
299
+ def arguments: () -> untyped
300
+ end
301
+
302
+ class Union < Member
303
+ def self.possible_types: (*untyped new_types, ?context: untyped, **untyped) -> ::Array[untyped]
304
+ def self.get_possible_type: (untyped type_expr, untyped obj, untyped ctx) -> untyped
305
+ def self.resolve_type: (untyped type_expr, untyped obj, untyped ctx) -> untyped
306
+ def self.type_error: (untyped type_error, untyped ctx) -> untyped
307
+ def self.orphan_types: (*untyped new_orphan_types) -> ::Array[untyped]
308
+ end
309
+
310
+ class Enum < Member
311
+ def self.value: (*untyped args, **untyped kwargs) ?{ (EnumValue) -> void } -> EnumValue
312
+ def self.values: (?untyped context) -> ::Hash[untyped, untyped]
313
+ def self.enum_values: (?untyped context) -> ::Array[untyped]
314
+ def self.enum_value_for: (untyped value_name, ?untyped context) -> EnumValue?
315
+ def self.value_from_ruby: (untyped val, ?untyped ctx) -> untyped
316
+ end
317
+
318
+ class EnumValue < Member
319
+ def value: (?untyped new_val) -> untyped
320
+ def deprecation_reason: (?String? new_reason) -> String?
321
+ attr_reader owner: untyped
322
+ attr_reader graphql_name: String
323
+ attr_reader description: String?
324
+ end
325
+
326
+ class Scalar < Member
327
+ def self.coerce_input: (untyped val, untyped ctx) -> untyped
328
+ def self.coerce_result: (untyped val, untyped ctx) -> untyped
329
+ end
330
+
331
+ class Directive < Member
332
+ extend Member::HasArguments
333
+ def self.locations: (*untyped new_locations) -> ::Array[untyped]
334
+ def self.repeatable: (?bool? new_repeatable) -> bool
335
+ def self.on: (*untyped new_locations) -> ::Array[untyped]
336
+ # Runtime takes the runtime object, argument values, and query context
337
+ # (directive.rb `include?` delegates to `static_include?`).
338
+ def self.include?: (untyped object, untyped arguments, untyped context) -> bool
339
+ end
340
+
341
+ # `Field`/`Argument` are definition objects, not schema members —
342
+ # they `include HasArguments` so `argument` inside a definition
343
+ # block's one-parameter form (`field(:x) { |f| f.argument }`)
344
+ # resolves on the yielded object.
345
+ class Field
346
+ include Member::HasArguments
347
+ def name: () -> String
348
+ def graphql_name: () -> String
349
+ def type: () -> untyped
350
+ def description: (?String? new_description) -> String?
351
+ def deprecation_reason: (?String? new_reason) -> String?
352
+ def extension: (untyped extension, **untyped options) -> untyped
353
+ def extensions: () -> untyped
354
+ def complexity: (?untyped new_complexity) -> untyped
355
+ def scope: (?untyped new_scope) -> untyped
356
+ def null: (?bool? new_null) -> bool
357
+ def null?: () -> bool
358
+ def method_sym: () -> Symbol
359
+ def method_str: () -> String
360
+ def resolver_method: () -> Symbol
361
+ def owner: () -> untyped
362
+ def connection?: () -> bool
363
+ def max_page_size: () -> Integer?
364
+ def default_page_size: () -> Integer?
365
+ def subscription_scope: (?untyped) -> untyped
366
+ end
367
+
368
+ class Argument
369
+ def keyword: () -> Symbol
370
+ def name: () -> String
371
+ def graphql_name: () -> String
372
+ def type: () -> untyped
373
+ def description: (?String? new_description) -> String?
374
+ def deprecation_reason: (?String? new_reason) -> String?
375
+ def default_value: (?untyped new_default_value) -> untyped
376
+ def default_value?: () -> bool
377
+ def required?: () -> bool
378
+ def loads: () -> untyped
379
+ def as: () -> Symbol
380
+ def prepare: () -> untyped
381
+ def owner: () -> untyped
382
+ def validates: () -> untyped
383
+ def replace_null_with_default?: () -> bool
384
+ end
385
+
386
+ class LateBoundType
387
+ def initialize: (untyped name, ?untyped type_defn) -> void
388
+ def graphql_name: () -> String
389
+ end
390
+
391
+ # The include-time `extend DefinitionMethods` is not modelled —
392
+ # see the file header. `DefinitionMethods` is declared so code that
393
+ # extends it directly resolves the same surface class bodies get.
394
+ module Interface
395
+ module DefinitionMethods
396
+ include Member::BaseDSLMethods
397
+ include Member::HasFields
398
+ include Member::HasInterfaces
399
+ include Member::RelayShortcuts
400
+ def orphan_types: (*untyped new_orphan_types) -> ::Array[untyped]
401
+ def resolve_type: (untyped type_expr, untyped obj, untyped ctx) -> untyped
402
+ def definition_methods: (?Module? other_module) -> untyped
403
+ end
404
+ extend DefinitionMethods
405
+ end
406
+ end
407
+
408
+ # graphql-ruby's own scalar / Relay wrapper types, referenced as
409
+ # `field`/`argument` arguments (`field :x, GraphQL::Types::ISO8601DateTime`).
410
+ module Types
411
+ class Boolean < Schema::Scalar
412
+ end
413
+
414
+ class ID < Schema::Scalar
415
+ end
416
+
417
+ class Int < Schema::Scalar
418
+ end
419
+
420
+ class Float < Schema::Scalar
421
+ end
422
+
423
+ class String < Schema::Scalar
424
+ end
425
+
426
+ class BigInt < Schema::Scalar
427
+ end
428
+
429
+ class Decimal < Schema::Scalar
430
+ end
431
+
432
+ class ISO8601Date < Schema::Scalar
433
+ end
434
+
435
+ class ISO8601DateTime < Schema::Scalar
436
+ end
437
+
438
+ class ISO8601DateTimePrecise < Schema::Scalar
439
+ end
440
+
441
+ class JSON < Schema::Scalar
442
+ end
443
+
444
+ class JSONString < Schema::Scalar
445
+ end
446
+
447
+ class Base64Binary < Schema::Scalar
448
+ end
449
+
450
+ module Relay
451
+ class BaseConnection < Schema::Object
452
+ def self.edge_type: (untyped edge_class, **untyped kwargs) -> Class?
453
+ def self.node_type: () -> Class?
454
+ def self.edges_field: (**untyped) -> GraphQL::Schema::Field
455
+ def self.nodes_field: (**untyped) -> GraphQL::Schema::Field
456
+ end
457
+
458
+ class BaseEdge < Schema::Object
459
+ def self.node_type: () -> Class?
460
+ end
461
+
462
+ class PageInfo < Schema::Object
463
+ end
464
+
465
+ class BaseField < Schema::Field
466
+ def self.connection_extension: () -> untyped
467
+ end
468
+
469
+ module Node
470
+ include GraphQL::Schema::Interface
471
+ end
472
+
473
+ module NodeBehaviors
474
+ def object_from_id: (untyped object_id, untyped ctx) -> untyped
475
+ def type_from_object: (untyped obj) -> untyped
476
+ end
477
+
478
+ module HasNodeField
479
+ end
480
+
481
+ module HasNodesField
482
+ end
483
+ end
484
+ end
485
+ end
@@ -51,6 +51,7 @@ module Rigor
51
51
  class Hanami < Rigor::Plugin::Base
52
52
  manifest(
53
53
  id: "hanami",
54
+ target_gems: ["hanami"],
54
55
  version: "0.1.0",
55
56
  description: "Enforces the Hanami::Action protocol: #handle(request, response) → void.",
56
57
  config_schema: {
@@ -56,6 +56,7 @@ module Rigor
56
56
  class Mangrove < Rigor::Plugin::Base
57
57
  manifest(
58
58
  id: "mangrove",
59
+ target_gems: ["mangrove"],
59
60
  version: "0.2.0",
60
61
  description: "Instantiates Mangrove Result/Option carrier generics at unwrap call sites, " \
61
62
  "sharpening `unwrap!` / `unwrap_in` / `unwrap_or` from `untyped` to the carried type; " \
@@ -134,7 +135,7 @@ module Rigor
134
135
 
135
136
  private
136
137
 
137
- # @return [Rigor::Type, nil] the receiver's inferred type, or nil when the engine raises on a synthetic
138
+ # @return the receiver's inferred type, or nil when the engine raises on a synthetic
138
139
  # / unrecognised node (mirrors rigor-sorbet's defensive degrade).
139
140
  def receiver_type_of(receiver, scope)
140
141
  scope.type_of(receiver)
@@ -59,9 +59,6 @@ module Rigor
59
59
  module AssertionAnalyzer
60
60
  module_function
61
61
 
62
- # @param call_node [Prism::CallNode]
63
- # @param environment [Rigor::Environment, nil]
64
- # @return [Rigor::FlowContribution, nil]
65
62
  def contribution_for(call_node, environment:)
66
63
  return nil unless call_node.is_a?(Prism::CallNode)
67
64
 
@@ -96,6 +93,7 @@ module Rigor
96
93
  assert_not_equal: [:literal_then_local, true],
97
94
  assert_match: [:regex_then_local, false]
98
95
  }.freeze
96
+ Ractor.make_shareable(ASSERT_FORM)
99
97
  private_constant :ASSERT_FORM
100
98
 
101
99
  def assert_form_fact(call_node, environment:)
@@ -129,6 +127,7 @@ module Rigor
129
127
  wont_equal: [:literal_arg, true],
130
128
  must_match: [:regex_arg, false]
131
129
  }.freeze
130
+ Ractor.make_shareable(SPEC_MATCHER_FORM)
132
131
  private_constant :SPEC_MATCHER_FORM
133
132
 
134
133
  # ADR-37 slice 2 — the method names this analyzer narrows on, for the plugin's
@@ -37,6 +37,7 @@ module Rigor
37
37
  class Minitest < Rigor::Plugin::Base
38
38
  manifest(
39
39
  id: "minitest",
40
+ target_gems: ["minitest"],
40
41
  version: "0.1.0",
41
42
  description: "Narrows locals through Minitest / Test::Unit `assert_*` / `refute_*` " \
42
43
  "and Minitest/spec `_(x).must_*` / `.wont_*` matchers.",
@@ -33,11 +33,6 @@ module Rigor
33
33
  # The policy violations for a single call node (0..2 of them), or `[]` when the node is not a
34
34
  # Pundit entry call or its record type is not statically determinable. ADR-37: the engine owns the
35
35
  # walk, so this is per-node logic.
36
- #
37
- # @param call_node [Prism::Node]
38
- # @param policy_index [PolicyIndex]
39
- # @param scope [Rigor::Scope, nil]
40
- # @return [Array<Violation>]
41
36
  def violations_for(call_node:, policy_index:, scope:)
42
37
  return [] unless call_node.is_a?(Prism::CallNode) && entry_call?(call_node)
43
38
 
@@ -42,7 +42,7 @@ module Rigor
42
42
  @search_paths = search_paths
43
43
  end
44
44
 
45
- # @return [Array<String>] policy class names named by an authorization call, sorted and unique. Not
45
+ # @return policy class names named by an authorization call, sorted and unique. Not
46
46
  # yet intersected with the discovered policies — the caller does that.
47
47
  def policy_names
48
48
  names = Set.new
@@ -93,7 +93,7 @@ module Rigor
93
93
  names << name if name
94
94
  end
95
95
 
96
- # @return [String, nil] the policy class the argument names, or nil when the argument is an
96
+ # @return the policy class the argument names, or nil when the argument is an
97
97
  # expression this reading cannot attribute to a record (a method call with arguments, a literal, an
98
98
  # index read). Silence, not a guess: an unattributable call contributes nothing.
99
99
  def policy_name_for(node)
@@ -28,7 +28,6 @@ module Rigor
28
28
  @base_classes = base_classes.to_set
29
29
  end
30
30
 
31
- # @return [PolicyIndex]
32
31
  def discover
33
32
  entries = []
34
33
  ruby_files_under(@search_paths).each do |path|
@@ -35,7 +35,6 @@ module Rigor
35
35
  freeze
36
36
  end
37
37
 
38
- # @return [Entry, nil]
39
38
  def find(policy_class_name)
40
39
  @by_name[policy_class_name.to_s]
41
40
  end
@@ -46,6 +46,7 @@ module Rigor
46
46
  class Pundit < Rigor::Plugin::Base
47
47
  manifest(
48
48
  id: "pundit",
49
+ target_gems: ["pundit"],
49
50
  # Bumped 2026-08-16 — publishes `:reachability_roots` for `rigor unused` (ADR-102 WD3): the policy
50
51
  # classes the project's own `authorize` / `policy` / `policy_scope` calls name by convention.
51
52
  version: "0.2.0",
@@ -108,12 +109,12 @@ module Rigor
108
109
  services.fact_store.publish(plugin_id: manifest.id, name: :reachability_roots, value: roots)
109
110
  end
110
111
 
111
- # File-level only: the load-error emission. The per-call policy validation runs over the engine-owned
112
- # walk via the node_rule below (ADR-37). The index is lazily loaded + memoised by `producer_value`,
113
- # so both surfaces share one load.
112
+ # File-level only: the load-error disclosure. The per-call policy validation runs over the
113
+ # engine-owned walk via the node_rule below (ADR-37). The index is lazily loaded + memoised by
114
+ # `producer_value`, so both surfaces share one load.
114
115
  def diagnostics_for_file(path:, scope:, root:) # rubocop:disable Lint/UnusedMethodArgument
115
116
  index = producer_value(:policy_index)
116
- return [load_error_diagnostic(path)] if index.nil? && producer_error(:policy_index)
117
+ disclose_load_error if index.nil? && producer_error(:policy_index)
117
118
 
118
119
  []
119
120
  end
@@ -129,10 +130,14 @@ module Rigor
129
130
 
130
131
  private
131
132
 
132
- def load_error_diagnostic(path)
133
+ # Issue #1056 — "the policy index did not load" is a fact about the run's INPUTS, not about the file being
134
+ # analysed, so it is registered rather than returned: see {Plugin::Base#disclose_once} for the
135
+ # channel, the `(plugin id, key)` de-duplication and why the engine positions it at `.rigor.yml:1:1`.
136
+ # Returned from the per-file hook it carried no once-guard at all and repeated on every file.
137
+ def disclose_load_error
133
138
  error = producer_error(:policy_index)
134
- Rigor::Analysis::Diagnostic.new(
135
- path: path, line: 1, column: 1,
139
+ disclose_once(
140
+ :policy_index_load_failed,
136
141
  message: "rigor-pundit: failed to discover policies: #{error.class}: #{error.message}",
137
142
  severity: :warning,
138
143
  rule: "load-error"
@@ -91,22 +91,10 @@ module Rigor
91
91
  RAILS_SHIPPED_KEY_PREFIXES.any? { |prefix| key_str.start_with?(prefix) }
92
92
  end
93
93
 
94
- # @param path [String]
95
- # @param root [Prism::Node]
96
- # @param locale_index [LocaleIndex]
97
- # @param configured_locales [Array<String>]
98
- # @return [Array<Diagnostic>]
99
94
  # The translation violations for a single call node, or `[]` when it is not a recognised `t` /
100
95
  # `translate` call with a literal key. ADR-37: the engine owns the walk; `action` (the enclosing
101
96
  # method, for lazy `t('.key')` expansion) comes from the node-rule `NodeContext`, and
102
97
  # `controller_scope` from the file path.
103
- #
104
- # @param call_node [Prism::Node]
105
- # @param locale_index [LocaleIndex]
106
- # @param configured_locales [Array<String>]
107
- # @param controller_scope [String, nil]
108
- # @param action [String, nil]
109
- # @return [Array<Violation>]
110
98
  def violations_for(call_node:, locale_index:, configured_locales:, controller_scope:, action:)
111
99
  return [] unless call_node.is_a?(Prism::CallNode) && translate_call_candidate?(call_node)
112
100
 
@@ -36,8 +36,7 @@ module Rigor
36
36
 
37
37
  attr_reader :entries, :locales
38
38
 
39
- # @param entries [Array<Entry>]
40
- # @param locales [Array<String>] all locale names that contributed at least one key.
39
+ # @param locales — all locale names that contributed at least one key.
41
40
  def initialize(entries, locales:)
42
41
  @entries = entries.freeze
43
42
  @locales = locales.dup.freeze
@@ -45,7 +44,6 @@ module Rigor
45
44
  freeze
46
45
  end
47
46
 
48
- # @return [Entry, nil]
49
47
  def find(dotted_key)
50
48
  @by_key[dotted_key.to_s]
51
49
  end