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,74 @@
1
+ module Rigor
2
+ module Analysis
3
+ # Frozen snapshot of the project-wide pre-pass state the runner consumes — see
4
+ # lib/rigor/analysis/project_scan.rb for the full ownership/invalidation contract.
5
+ class ProjectScan < ::Data
6
+ # sig-gen gap: #1150 — `Data.define` member reads carry no type; `build_project_scan` fills
7
+ # this slot with the prepared `Plugin::Loader` result.
8
+ def plugin_registry: () -> Rigor::Plugin::Registry
9
+
10
+ # sig-gen gap: #1150 — as above (`DependencySourceInference::Builder.build` output, or
11
+ # `Index::EMPTY` when no dependencies are configured).
12
+ def dependency_source_index: () -> DependencySourceInference::Index
13
+
14
+ # `Inference::SyntheticMethodIndex` — the class is not yet declared under `sig/` (#1181
15
+ # backlog), so `untyped` is the honest member type for now.
16
+ def synthetic_method_index: () -> untyped
17
+
18
+ # `Inference::ProjectPatchedMethods` — unsigned like the slot above.
19
+ def project_patched_methods: () -> untyped
20
+
21
+ # sig-gen gap: #1150 — as above (`plugin_prepare_diagnostics` collects the
22
+ # `plugin_prepare_error_diagnostic` `Diagnostic`s, `[]` under pool mode).
23
+ def plugin_prepare_diagnostics: () -> Array[Analysis::Diagnostic]
24
+
25
+ # sig-gen gap: #1150 — as above. The pre-eval scanner deliberately emits a Hash shape (it
26
+ # must not depend on the analysis layer); the runner translates each row to a `Diagnostic`
27
+ # at the call site.
28
+ def pre_eval_diagnostics: () -> Array[{ path: String, line: Integer, column: Integer, severity: Symbol, rule: String, message: String }]
29
+
30
+ # `Analysis::TemplateUnits` — unsigned (#1181 backlog), kept `untyped`.
31
+ def template_units: () -> untyped
32
+
33
+ # sig-gen gap: #1150 — as above; constructor keywords mirror the member declarations.
34
+ def self.new: (
35
+ plugin_registry: Rigor::Plugin::Registry,
36
+ dependency_source_index: DependencySourceInference::Index,
37
+ synthetic_method_index: untyped,
38
+ project_patched_methods: untyped,
39
+ plugin_prepare_diagnostics: Array[Analysis::Diagnostic],
40
+ pre_eval_diagnostics: Array[{ path: String, line: Integer, column: Integer, severity: Symbol, rule: String, message: String }],
41
+ template_units: untyped
42
+ ) -> instance
43
+ | (
44
+ Rigor::Plugin::Registry plugin_registry,
45
+ DependencySourceInference::Index dependency_source_index,
46
+ untyped synthetic_method_index,
47
+ untyped project_patched_methods,
48
+ Array[Analysis::Diagnostic] plugin_prepare_diagnostics,
49
+ Array[{ path: String, line: Integer, column: Integer, severity: Symbol, rule: String, message: String }] pre_eval_diagnostics,
50
+ untyped template_units
51
+ ) -> instance
52
+
53
+ # sig-gen gap: #1150 — as above.
54
+ def self.[]: (
55
+ plugin_registry: Rigor::Plugin::Registry,
56
+ dependency_source_index: DependencySourceInference::Index,
57
+ synthetic_method_index: untyped,
58
+ project_patched_methods: untyped,
59
+ plugin_prepare_diagnostics: Array[Analysis::Diagnostic],
60
+ pre_eval_diagnostics: Array[{ path: String, line: Integer, column: Integer, severity: Symbol, rule: String, message: String }],
61
+ template_units: untyped
62
+ ) -> instance
63
+ | (
64
+ Rigor::Plugin::Registry plugin_registry,
65
+ DependencySourceInference::Index dependency_source_index,
66
+ untyped synthetic_method_index,
67
+ untyped project_patched_methods,
68
+ Array[Analysis::Diagnostic] plugin_prepare_diagnostics,
69
+ Array[{ path: String, line: Integer, column: Integer, severity: Symbol, rule: String, message: String }] pre_eval_diagnostics,
70
+ untyped template_units
71
+ ) -> instance
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,12 @@
1
+ module Rigor
2
+ module Analysis
3
+ module Reachability
4
+ class ScanCache
5
+ def self.open: (untyped, ?target_ruby: untyped) -> Rigor::Analysis::Reachability::ScanCache
6
+ def self.source_digest: () -> String
7
+ def initialize: (path: untyped, header: untyped) -> void
8
+ def save: () -> nil
9
+ end
10
+ end
11
+ end
12
+ end
data/sig/rigor/cache.rbs CHANGED
@@ -16,9 +16,8 @@ module Rigor
16
16
  def self.fetch: (loader: untyped, store: untyped) -> untyped
17
17
 
18
18
  # The generation cap this producer declares to `Cache::Store#evict!`
19
- # (issue #151). `rigor sig-gen` infers the literal `2` from the base
20
- # body; the contract is the wider `Integer`, since a subclass may
21
- # override it.
19
+ # (issue #151). The base body answers `2`; the contract is the wider
20
+ # `Integer`, since the cap is a knob a subclass may turn.
22
21
  def self.generation_cap: () -> Integer
23
22
  end
24
23
  end
@@ -0,0 +1,100 @@
1
+ module Rigor
2
+ module Effects
3
+ # `effects.envelopes:` entries resolved against the label vocabulary — the configured stratum of
4
+ # the envelope precedence (ADR-103 WD1).
5
+ module ConfigEnvelopes
6
+ CONFIG_PATH: String
7
+
8
+ # One entry, resolved against the vocabulary. `bound` is `LabelSet::TOP` when some member of
9
+ # `effect:` is unrecognised — the fail-open rule.
10
+ class Entry < ::Data
11
+ # sig-gen gap: #1150 — `Data.define` member reads carry no type; `build` proves each of these.
12
+ def index: () -> Integer
13
+
14
+ # sig-gen gap: #1150 — as above (path glob, or nil when `namespace:` is set).
15
+ def match: () -> String?
16
+
17
+ # sig-gen gap: #1150 — as above (constant-path glob, or nil when `match:` is set).
18
+ def namespace: () -> String?
19
+
20
+ # sig-gen gap: #1150 — as above (`LabelSet::TOP` on an unrecognised label).
21
+ def bound: () -> LabelSet
22
+
23
+ # sig-gen gap: #1150 — as above (the `effect:` list exactly as written).
24
+ def labels: () -> Array[String]
25
+
26
+ # sig-gen gap: #1150 — as above (well-formed spellings the registry did not know).
27
+ def unknown_labels: () -> Array[String]
28
+
29
+ # sig-gen gap: #1150 — as above; keyword form mirrors the member declarations.
30
+ def self.new: (
31
+ index: Integer,
32
+ match: String?,
33
+ namespace: String?,
34
+ bound: LabelSet,
35
+ labels: Array[String],
36
+ unknown_labels: Array[String]
37
+ ) -> instance
38
+ | (
39
+ Integer index,
40
+ String? match,
41
+ String? namespace,
42
+ LabelSet bound,
43
+ Array[String] labels,
44
+ Array[String] unknown_labels
45
+ ) -> instance
46
+
47
+ # sig-gen gap: #1150 — as above.
48
+ def self.[]: (
49
+ index: Integer,
50
+ match: String?,
51
+ namespace: String?,
52
+ bound: LabelSet,
53
+ labels: Array[String],
54
+ unknown_labels: Array[String]
55
+ ) -> instance
56
+ | (
57
+ Integer index,
58
+ String? match,
59
+ String? namespace,
60
+ LabelSet bound,
61
+ Array[String] labels,
62
+ Array[String] unknown_labels
63
+ ) -> instance
64
+
65
+ # `.rigor.yml effects.envelopes[N]` — the location spelling diagnostics name.
66
+ def location: () -> String
67
+
68
+ # The bound quoted back in the config's own spelling.
69
+ def spelling: () -> String
70
+
71
+ def top?: () -> bool
72
+ end
73
+
74
+ # `entries` are the shape-validated `Configuration#effects_envelopes` rows (String-keyed
75
+ # Hashes); `registry` is the `Effects::Registry` vocabulary — unsigned, so `untyped`.
76
+ def self?.build: (entries: Array[Hash[String, untyped]], registry: untyped) -> Array[Entry]
77
+
78
+ # One envelope per selected class, keyed by class name. `sources` is `Runner#effect_sources`'s
79
+ # shape; `project_root` is what those paths are relativised against.
80
+ def self?.for_classes: (
81
+ entries: Array[Entry],
82
+ class_names: Array[String],
83
+ ?sources: Hash[String, Array[String]],
84
+ ?project_root: String
85
+ ) -> Hash[String, Envelope]
86
+
87
+ # The {Envelope} one entry puts on one class.
88
+ def self?.envelope_for: (Entry entry, String class_name) -> Envelope
89
+
90
+ # Whether one entry selects a class — `paths` is `Array()`d, so `untyped` is honest.
91
+ def self?.selects?: (Entry entry, String class_name, untyped paths) -> bool
92
+
93
+ # `File.fnmatch?` with `FNM_PATHNAME` — the ADR-28 path-glob shape.
94
+ def self?.path_match?: (String glob, String path) -> bool
95
+
96
+ # Constant-path glob over the `::`-separated FQN; both arguments are `to_s`d.
97
+ def self?.namespace_match?: (untyped glob, untyped class_name) -> bool
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,60 @@
1
+ module Rigor
2
+ module Effects
3
+ # The propagated result of the fixpoint walk: every method's direct summary plus the transitive
4
+ # `proven` / `undischarged` / `declared` lanes, the exhaustiveness bit, and the resolved callee keys.
5
+ class EffectTable
6
+ # One row of the closed table.
7
+ class Entry < ::Data
8
+ # sig-gen gap: #1150 — `Data.define` member reads carry no type.
9
+ def key: () -> String
10
+ # sig-gen gap: #1150
11
+ def direct: () -> Summary
12
+ # sig-gen gap: #1150
13
+ def proven: () -> LabelSet
14
+ # sig-gen gap: #1150
15
+ def undischarged: () -> LabelSet
16
+ # sig-gen gap: #1150
17
+ def declared: () -> LabelSet
18
+ # sig-gen gap: #1150
19
+ def exhaustive: () -> bool
20
+ # sig-gen gap: #1150 — `causes` are frozen `[cause, detail]` pairs.
21
+ def causes: () -> Array[[String, String?]]
22
+ # sig-gen gap: #1150 — resolved callee keys (`"Class#m"` strings).
23
+ def edges: () -> Array[String]
24
+ # sig-gen gap: #1150
25
+ def unclaimed: () -> bool
26
+
27
+ # sig-gen gap: #1150 — the custom `initialize` supplies defaults for `undischarged` (=
28
+ # `proven`), `declared` (= empty) and `unclaimed` (= false); it accepts kwargs only, so the
29
+ # member constructor has no positional arm.
30
+ def self.new: (key: String, direct: Summary, proven: LabelSet, exhaustive: bool,
31
+ causes: Array[[String, String?]], edges: Array[String],
32
+ ?undischarged: LabelSet?, ?declared: LabelSet?, ?unclaimed: bool) -> instance
33
+ # sig-gen gap: #1150 — as above.
34
+ def self.[]: (key: String, direct: Summary, proven: LabelSet, exhaustive: bool,
35
+ causes: Array[[String, String?]], edges: Array[String],
36
+ ?undischarged: LabelSet?, ?declared: LabelSet?, ?unclaimed: bool) -> instance
37
+
38
+ def unclaimed?: () -> bool
39
+
40
+ # The declared labels worth printing beside `proven` — those the proven lane does not already
41
+ # admit.
42
+ def rendered_declared: () -> LabelSet
43
+
44
+ def exhaustive?: () -> bool
45
+ def trivial?: () -> bool
46
+ end
47
+
48
+ def self.empty: () -> EffectTable
49
+
50
+ def initialize: (Hash[String, Entry] entries) -> void
51
+
52
+ def []: (String key) -> Entry?
53
+ def keys: () -> Array[String]
54
+ def each: () { (Entry) -> untyped } -> void
55
+ include Enumerable[Entry]
56
+ def size: () -> Integer
57
+ def empty?: () -> bool
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,97 @@
1
+ module Rigor
2
+ module Effects
3
+ # An author-declared upper bound on one method's effect labels (ADR-103 WD1). A `Data` record —
4
+ # see lib/rigor/effects/envelope.rb for the member semantics.
5
+ class Envelope < ::Data
6
+ # {#source} for a bound written in `.rigor.yml` rather than on a declaration.
7
+ CONFIG_SOURCE: :config_envelope
8
+
9
+ # sig-gen gap: #1150 — `Data.define` member reads carry no type; `build` proves each of these.
10
+ def owner_key: () -> String
11
+
12
+ # sig-gen gap: #1150 — as above; `LabelSet::TOP` means "no envelope" (the fail-open reading).
13
+ def bound: () -> LabelSet
14
+
15
+ # sig-gen gap: #1150 — as above; the four documented producers are the closed set.
16
+ def source: () -> (:pure_annotation | :effect_annotation | :class_annotation | :config_envelope)
17
+
18
+ # sig-gen gap: #1150 — as above (`path:line`, the `.rigor.yml` key path, or nil).
19
+ def location: () -> String?
20
+
21
+ # sig-gen gap: #1150 — as above (the author's own annotation text, or nil).
22
+ def spelling: () -> String?
23
+
24
+ # sig-gen gap: #1150 — as above (sorted, de-duplicated by `build`; #384 reads them).
25
+ def unknown_labels: () -> Array[String]
26
+
27
+ # sig-gen gap: #1150 — as above (every token the tag listed, recognised or not).
28
+ def declared_labels: () -> Array[String]
29
+
30
+ # sig-gen gap: #1150 — as above; keyword form mirrors the member declarations.
31
+ def self.new: (
32
+ owner_key: String,
33
+ bound: LabelSet,
34
+ source: (:pure_annotation | :effect_annotation | :class_annotation | :config_envelope),
35
+ location: String?,
36
+ spelling: String?,
37
+ unknown_labels: Array[String],
38
+ declared_labels: Array[String]
39
+ ) -> instance
40
+ | (
41
+ String owner_key,
42
+ LabelSet bound,
43
+ (:pure_annotation | :effect_annotation | :class_annotation | :config_envelope) source,
44
+ String? location,
45
+ String? spelling,
46
+ Array[String] unknown_labels,
47
+ Array[String] declared_labels
48
+ ) -> instance
49
+
50
+ # sig-gen gap: #1150 — as above.
51
+ def self.[]: (
52
+ owner_key: String,
53
+ bound: LabelSet,
54
+ source: (:pure_annotation | :effect_annotation | :class_annotation | :config_envelope),
55
+ location: String?,
56
+ spelling: String?,
57
+ unknown_labels: Array[String],
58
+ declared_labels: Array[String]
59
+ ) -> instance
60
+ | (
61
+ String owner_key,
62
+ LabelSet bound,
63
+ (:pure_annotation | :effect_annotation | :class_annotation | :config_envelope) source,
64
+ String? location,
65
+ String? spelling,
66
+ Array[String] unknown_labels,
67
+ Array[String] declared_labels
68
+ ) -> instance
69
+
70
+ # Normalising constructor — sorts/dedupes `unknown_labels` and freezes `declared_labels`.
71
+ def self.build: (
72
+ owner_key: String,
73
+ bound: LabelSet,
74
+ source: (:pure_annotation | :effect_annotation | :class_annotation | :config_envelope),
75
+ ?location: String?,
76
+ ?spelling: String?,
77
+ ?unknown_labels: Array[String],
78
+ ?declared_labels: Array[String]
79
+ ) -> Envelope
80
+
81
+ # Whether this reads as ⊤ — no bound at all.
82
+ def top?: () -> bool
83
+
84
+ # `label` is `to_s`-compared through {LabelSet#admits?}; `mutate.local` always tolerates.
85
+ def tolerates?: (untyped label) -> bool
86
+
87
+ # The members of `label_set` this envelope does NOT admit, sorted.
88
+ def exceeded_by: (LabelSet label_set) -> Array[String]
89
+
90
+ # Whether the bound was written in `.rigor.yml`.
91
+ def config?: () -> bool
92
+
93
+ # The same bound on another method key — the class-level distribution seam.
94
+ def rebind: (String key) -> Envelope
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,33 @@
1
+ module Rigor
2
+ module Effects
3
+ # The envelopes a call site may import as a `≤` bound (ADR-103 WD6; #386) — per-method
4
+ # annotation, class-level annotation, `effects.envelopes:`, then the accepted signature stratum.
5
+ class EnvelopeIndex
6
+ # The index a run with no declaration of any kind uses — and the fail-soft answer for a build
7
+ # that raised.
8
+ def self.empty: () -> EnvelopeIndex
9
+
10
+ # Reads every stratum this index serves, once per process. `environment` supplies the accepted
11
+ # stratum through its RBS loader (nil drops it, fail-quiet); `plugin_facts` is the plugins'
12
+ # compiled `Effects::PluginFacts` contributions (nil where no plugin set was loaded).
13
+ def self.build: (configuration: Configuration, ?environment: Rigor::Environment?,
14
+ ?plugin_facts: PluginFacts?) -> EnvelopeIndex
15
+
16
+ def initialize: (
17
+ ?method_envelopes: Hash[String, Envelope],
18
+ ?class_envelopes: Hash[String, Envelope],
19
+ ?config_entries: Array[ConfigEnvelopes::Entry],
20
+ ?accepted: Hash[String, Envelope]
21
+ ) -> void
22
+
23
+ # Whether no stratum has anything to say — the scan's fast path.
24
+ def empty?: () -> bool
25
+
26
+ # The envelope bounding `owner`'s `selector`, or nil — never a ⊤ envelope.
27
+ def []: (String? owner, bool singleton, untyped selector) -> Envelope?
28
+
29
+ # Whether ANY stratum carries an annotation for this key — ⊤ envelopes included (#391).
30
+ def annotated?: (String? owner, bool singleton, untyped selector) -> bool
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,81 @@
1
+ module Rigor
2
+ module Effects
3
+ # The per-file unit of the collection window (ADR-103): the direct summaries, the call edges, and
4
+ # the as-written ancestry a file contributes. {merge_all} folds a run's collections in one pass.
5
+ class FileCollection
6
+ # An ancestry entry that names nothing and can never resolve (#1039).
7
+ OPAQUE_ANCESTOR: String
8
+
9
+ # One recorded call edge: who the receiver's class is, which lane (`:instance` / `:singleton`)
10
+ # the selector dispatches on, and the bits that decide what an unresolved edge seeds.
11
+ class Edge < ::Data
12
+ # sig-gen gap: #1150 — `Data.define` member reads carry no type.
13
+ def receiver_class: () -> String?
14
+ # sig-gen gap: #1150
15
+ def kind: () -> (:instance | :singleton)
16
+ # sig-gen gap: #1150
17
+ def selector: () -> String
18
+ # sig-gen gap: #1150
19
+ def self_call: () -> bool
20
+ # sig-gen gap: #1150
21
+ def super_call: () -> bool
22
+ # sig-gen gap: #1150
23
+ def unclaimed: () -> bool
24
+ # sig-gen gap: #1150
25
+ def constant_receiver: () -> bool
26
+ # sig-gen gap: #1150 — the `[cause, detail]` pair an unresolved edge seeds, when the row
27
+ # named a `taint:`.
28
+ def taint_if_unresolved: () -> [String, String?]?
29
+ # sig-gen gap: #1150 — the plugin's lookup-order retry selectors (#1065).
30
+ def fallback_selectors: () -> Array[String]?
31
+
32
+ # sig-gen gap: #1150 — member constructor. The custom `initialize` accepts kwargs only and
33
+ # defaults every member after `self_call`, so there is no positional arm.
34
+ def self.new: (receiver_class: String?, kind: (:instance | :singleton), selector: String,
35
+ self_call: bool, ?super_call: bool, ?unclaimed: bool,
36
+ ?constant_receiver: bool, ?taint_if_unresolved: [String, String?]?,
37
+ ?fallback_selectors: Array[String]?) -> instance
38
+ # sig-gen gap: #1150 — as above.
39
+ def self.[]: (receiver_class: String?, kind: (:instance | :singleton), selector: String,
40
+ self_call: bool, ?super_call: bool, ?unclaimed: bool,
41
+ ?constant_receiver: bool, ?taint_if_unresolved: [String, String?]?,
42
+ ?fallback_selectors: Array[String]?) -> instance
43
+ end
44
+
45
+ # The collection a file with nothing to say contributes.
46
+ def self.empty: (?String? path) -> FileCollection
47
+
48
+ # sig-gen gap: #1154 — `initialize` freezes the kwarg tables rather than assigning them
49
+ # verbatim, so sig-gen proposes the default constant's shape for each reader.
50
+ attr_reader path: String?
51
+ # sig-gen gap: #1154 — `{ "Class#m" => Summary }`.
52
+ attr_reader summaries: Hash[String, Summary]
53
+ # sig-gen gap: #1154 — `{ "Class#m" => [Edge] }`, sorted and de-duplicated.
54
+ attr_reader edges: Hash[String, Array[Edge]]
55
+ # sig-gen gap: #1154 — `{ class_name => superclass_name }`, `OPAQUE_ANCESTOR` included.
56
+ attr_reader superclasses: Hash[String, String]
57
+ # sig-gen gap: #1154 — `{ class_name => [module_name] }`, include/prepend merged.
58
+ attr_reader includes: Hash[String, Array[String]]
59
+
60
+ def initialize: (?path: String?, ?summaries: Hash[String, Summary],
61
+ ?edges: Hash[String, Array[Edge]], ?superclasses: Hash[String, String],
62
+ ?includes: Hash[String, Array[String]], ?failed: bool) -> void
63
+
64
+ # Whether the collector gave up on this file entirely (the fail-soft path).
65
+ def failed?: () -> bool
66
+
67
+ # Whether this collection contributes nothing.
68
+ def empty?: () -> bool
69
+
70
+ # Two-collection fold — {merge_all} for a whole run.
71
+ def merge: (FileCollection other) -> FileCollection
72
+
73
+ # Folds a run's collections in one linear pass; order-independent except `superclasses`.
74
+ def self.merge_all: (Enumerable[FileCollection] collections) -> FileCollection
75
+
76
+ def ==: (untyped other) -> bool
77
+ alias eql? ==
78
+ def hash: () -> Integer
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,26 @@
1
+ module Rigor
2
+ module Effects
3
+ # The effect-label grammar and segment-aware prefix subsumption (ADR-103 WD1). Every predicate is
4
+ # total — a malformed input is answered, never raised on — so the parameters are `untyped` on
5
+ # purpose.
6
+ module Label
7
+ PATTERN: Regexp
8
+
9
+ def self?.valid?: (untyped str) -> bool
10
+
11
+ # `[]` for a malformed label, the segments otherwise.
12
+ def self?.segments: (untyped label) -> Array[String]
13
+
14
+ def self?.subsumes?: (untyped bound, untyped label) -> bool
15
+
16
+ # One segment shallower; nil for a root and for a malformed label.
17
+ def self?.parent: (untyped label) -> String?
18
+
19
+ # Proper ancestors, outermost first; `[]` for a root and for a malformed label.
20
+ def self?.ancestors: (untyped label) -> Array[String]
21
+
22
+ # The outermost segment; nil for a malformed label.
23
+ def self?.root: (untyped label) -> String?
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,46 @@
1
+ module Rigor
2
+ module Effects
3
+ # An immutable, sorted, de-duplicated set of effect labels (ADR-103 WD1) — the carrier of a
4
+ # summary lane and of an envelope's bound. `TOP` is the unbounded sentinel: it admits every
5
+ # label, absorbs every join, and answers `[]` from `to_a`.
6
+ class LabelSet
7
+ # `labels` is any enumerable of label Strings (`#to_a` is called on it); `top:` is internal —
8
+ # it exists to build {TOP} and is not part of the public surface.
9
+ def initialize: (?untyped labels, ?top: bool) -> void
10
+
11
+ TOP: LabelSet
12
+ EMPTY: LabelSet
13
+
14
+ def top?: () -> bool
15
+
16
+ # {TOP} is not empty: it records nothing because it stands for everything.
17
+ def empty?: () -> bool
18
+
19
+ # The members, sorted. {TOP} yields `[]` — consult {top?} first.
20
+ def to_a: () -> Array[String]
21
+
22
+ # Exact membership — `include?` is not subsumption ({admits?} is).
23
+ def include?: (untyped label) -> bool
24
+
25
+ # Whether some member subsumes `label`. {TOP} admits every well-formed label.
26
+ def admits?: (untyped label) -> bool
27
+
28
+ # Union — {TOP} absorbs. May return `self`/`other` without allocating.
29
+ def join: (LabelSet other) -> LabelSet
30
+
31
+ # The members `other` does not already admit — the declared lane's rendering rule.
32
+ def excluding_subsumed_by: (LabelSet other) -> LabelSet
33
+
34
+ # The envelope check, modulo policy discharge. {TOP} is bounded only by {TOP}.
35
+ def subsumed_by?: (LabelSet bound_set) -> bool
36
+
37
+ def ==: (untyped other) -> bool
38
+
39
+ # `alias eql? ==` — no sig-gen shape for alias rows; unmarked residue.
40
+ def eql?: (untyped other) -> bool
41
+
42
+ def hash: () -> Integer
43
+ def inspect: () -> String
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,24 @@
1
+ module Rigor
2
+ module Effects
3
+ # The `Owner#selector` / `Owner.selector` key spelling (ADR-103 WD14). `key` parameters accept any
4
+ # object — every entry point `to_s`s its input — so they are `untyped` on purpose.
5
+ module MethodKey
6
+ TEMPLATE_UNIT_PREFIX: String
7
+
8
+ # `[owner, separator, selector]`, or nil when `key` is not a method key at all.
9
+ def self?.split: (untyped key) -> [String, String, String]?
10
+
11
+ def self?.valid?: (untyped key) -> bool
12
+
13
+ # The owner half of a method key, or nil.
14
+ def self?.owner: (untyped key) -> String?
15
+
16
+ # `view:`-prefixed template-unit keys are NOT method keys (#393).
17
+ def self?.template_unit?: (untyped key) -> bool
18
+
19
+ # The name an `effects.envelopes:` entry selects a key by — the owner class for a method key,
20
+ # the unit key itself for a template unit.
21
+ def self?.envelope_owner: (untyped key) -> String?
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,50 @@
1
+ module Rigor
2
+ module Effects
3
+ # Where one bundle of labels in a summary came from (ADR-103 WD14): a callee/construct `name`
4
+ # plus which `source` coloured it.
5
+ class Origin < ::Data
6
+ CONSTRUCT: :construct
7
+ CATALOGUE: :catalogue
8
+ ATTRIBUTION: :attribution
9
+ ENVELOPE: :envelope
10
+ PLUGIN: :plugin
11
+
12
+ # sig-gen gap: #1150 — `Data.define` member reads carry no type; every factory below proves
13
+ # `name` a `to_s`d String and `source` one of the five constants.
14
+ def name: () -> String
15
+
16
+ # sig-gen gap: #1150 — as above; the five source constants are the closed set.
17
+ def source: () -> (:construct | :catalogue | :attribution | :envelope | :plugin)
18
+
19
+ # sig-gen gap: #1150 — as above.
20
+ def self.new: (
21
+ name: String,
22
+ source: (:construct | :catalogue | :attribution | :envelope | :plugin)
23
+ ) -> instance
24
+ | (
25
+ String name,
26
+ (:construct | :catalogue | :attribution | :envelope | :plugin) source
27
+ ) -> instance
28
+
29
+ # sig-gen gap: #1150 — as above.
30
+ def self.[]: (
31
+ name: String,
32
+ source: (:construct | :catalogue | :attribution | :envelope | :plugin)
33
+ ) -> instance
34
+ | (
35
+ String name,
36
+ (:construct | :catalogue | :attribution | :envelope | :plugin) source
37
+ ) -> instance
38
+
39
+ # `name` is `to_s`d, so any object is acceptable — `untyped` is the honest parameter.
40
+ def self.construct: (untyped name) -> Origin
41
+ def self.catalogue: (untyped name) -> Origin
42
+ def self.attribution: (untyped name) -> Origin
43
+ def self.envelope: (untyped name) -> Origin
44
+ def self.plugin: (untyped name) -> Origin
45
+
46
+ # `"source:name"` — the rendering the report and the JSON payload key on.
47
+ def to_s: () -> String
48
+ end
49
+ end
50
+ end