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,263 @@
1
+ # Bundled RBS for the Grape / grape-entity declaration DSL (issue #1099).
2
+ #
3
+ # Grape's class-level endpoint DSL is dynamic at runtime: `Grape::API` subclasses forward every
4
+ # declaration call to the base `Grape::API::Instance` class object via `delegate_missing_to` /
5
+ # `override_all_methods!` (`lib/grape/api.rb`), and the Instance class gets the real definitions
6
+ # from the `included do ... end` bodies of `Grape::DSL::{Routing,Validations,Configuration,
7
+ # Helpers,Callbacks,Middleware,RequestResponse}`. Both sides answer the same singleton surface, so
8
+ # the signatures live once in `Grape::DSL::ClassMethods` and are `extend`ed onto both classes.
9
+ #
10
+ # Return carriers follow the runtime implementation (grape 2.4.0, grape-entity 1.0): setup-style
11
+ # declarations return the bookkeeping collection or the stored setting value, so `::Object?` /
12
+ # `::Array[untyped]` is the honest reading — `void` would be dishonest AND is collapsed to
13
+ # `Dynamic[top]` by the engine's void-value-use recovery, which is exactly what this plugin exists
14
+ # to prevent.
15
+ #
16
+ # Provenance (docs/agents/type-authoring.md): `rigor sig-gen` cannot produce this file — the DSL
17
+ # methods it declares have no `def` in the gems' source (they are generated through
18
+ # `override_all_methods!` / `delegate_missing_to` / `StrictHashConfiguration`), so every entry was
19
+ # hand-derived by reading the grape 2.4.x / grape-entity 1.0 source. Members that do not exist at
20
+ # that version's runtime location are deliberately absent — declaring them would let a genuinely
21
+ # failing call resolve silently.
22
+ #
23
+ # Block `self` bindings are NOT modelled here — they come from the manifest's `block_as_methods`
24
+ # entries (`params` bodies on `Grape::Validations::ParamsScope`, `namespace` bodies on the
25
+ # `Grape::API::Instance` class object, verb bodies on `Grape::Endpoint`).
26
+
27
+ module Grape
28
+ module DSL
29
+ # Class-level declaration surface shared by `Grape::API` subclasses and `Grape::API::Instance`.
30
+ module ClassMethods
31
+ # Validations — `params` opens a `Grape::Validations::ParamsScope` and `instance_eval`s the
32
+ # block on it; returns the new scope (dsl/validations.rb).
33
+ def params: () ?{ () -> untyped } -> Grape::Validations::ParamsScope
34
+ def contract: (?untyped) ?{ () -> untyped } -> ::Object?
35
+
36
+ # Routing — the HTTP verbs are generated over `Grape::HTTP_SUPPORTED_METHODS` and delegate to
37
+ # `route` (`def route(methods, paths = ['/'], route_options = {}, &block)`).
38
+ def get: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
39
+ def put: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
40
+ def post: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
41
+ def delete: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
42
+ def head: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
43
+ def patch: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
44
+ def options: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
45
+ def route: (untyped, ?untyped, ?untyped) ?{ () -> untyped } -> ::Object?
46
+
47
+ # Namespace family — `namespace`/`scope`/`route_param`/`version`/`given`/`mounted`
48
+ # `instance_eval` their block on the Instance class object and return the block's value.
49
+ # `group`/`resource`/`resources`/`segment` are aliases of `namespace`; `scope` routes
50
+ # through `within_namespace { nest(block) }` (dsl/routing.rb).
51
+ def namespace: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
52
+ def route_param: (untyped, **untyped) ?{ () -> untyped } -> ::Object?
53
+ def group: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
54
+ def resource: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
55
+ def resources: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
56
+ def segment: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
57
+ def version: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
58
+ def given: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
59
+ def mounted: () { () -> untyped } -> ::Object?
60
+ def mount: (untyped, *untyped) -> ::Object?
61
+ def scope: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
62
+ def prefix: (?untyped) -> ::Object?
63
+
64
+ # Settings / configuration (dsl/settings.rb, dsl/configuration.rb).
65
+ def route_setting: (untyped, ?untyped) -> ::Object?
66
+ def unset_route_setting: (untyped) -> ::Object?
67
+ def global_setting: (untyped, ?untyped) -> ::Object?
68
+ def unset_global_setting: (untyped) -> ::Object?
69
+ # `description` / `entity` / `detail` / `failure` / `success` and friends are NOT API-level
70
+ # methods — they belong to the anonymous `config_context` a `desc` block `instance_exec`s on
71
+ # (`Grape::Util::StrictHashConfiguration`). That surface is deferred (README); declaring the
72
+ # names here would silently resolve calls that fail at runtime.
73
+ def desc: (untyped, ?untyped) ?{ () -> untyped } -> ::Object?
74
+ def content_type: (untyped, untyped) -> ::Object?
75
+ def default_format: (?untyped) -> ::Object?
76
+ def format: (?untyped) -> ::Object?
77
+ def formatter: (untyped, untyped) -> ::Object?
78
+ def parser: (untyped, untyped) -> ::Object?
79
+ def default_error_formatter: (?untyped) -> ::Object?
80
+ def default_error_status: (?untyped) -> ::Object?
81
+ def error_formatter: (untyped, untyped) -> ::Object?
82
+ def cascade: (?untyped) -> ::Object?
83
+ def do_not_route_head!: () -> ::Object?
84
+ def do_not_route_options!: () -> ::Object?
85
+ def do_not_document!: () -> ::Object?
86
+ def http_basic: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
87
+ def auth: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
88
+ def http_digest: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
89
+ def rescue_from: (*untyped, **untyped) ?{ (*untyped) -> untyped } -> ::Object?
90
+ # `represent` forwards to `Entity.represent`, whose result is an entity, an array of
91
+ # entities, or a `{root => inner}` Hash depending on the call — untyped is the honest
92
+ # carrier (a `::Object` return invents `undefined method` findings on every chained call).
93
+ # Runtime arity is `represent(model_class, options)` (dsl/request_response.rb).
94
+ def represent: (untyped, untyped) -> untyped
95
+
96
+ # Helpers / middleware / callbacks.
97
+ def helpers: (*untyped) ?{ () -> untyped } -> ::Object?
98
+ def use: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
99
+ def middleware: () -> ::Object?
100
+ def insert_before: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
101
+ def insert_after: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
102
+ def before: () { () -> untyped } -> ::Object?
103
+ def before_validation: () { () -> untyped } -> ::Object?
104
+ def after_validation: () { () -> untyped } -> ::Object?
105
+ def after: () { () -> untyped } -> ::Object?
106
+ def finally: () { () -> untyped } -> ::Object?
107
+ end
108
+
109
+ module Desc
110
+ # The `instance_exec` target of a `desc 'x' do ... end` config block. At runtime this is an
111
+ # anonymous class built by `StrictHashConfiguration.config_class(*Desc::ROUTE_ATTRIBUTES)`
112
+ # (`dsl/desc.rb` `desc_container`) — a CLOSED surface of one-argument setters that store and
113
+ # return the assigned value (`@settings[name] = new_value`), plus the `success`/`failure`
114
+ # aliases singleton-defined on the context. Names outside `ROUTE_ATTRIBUTES` raise
115
+ # `NoMethodError` at runtime, so this receiver stays out of `open_receivers`: an undeclared
116
+ # call inside a `desc` block genuinely fails.
117
+ class ConfigContext
118
+ def body_name: (untyped) -> ::Object?
119
+ def consumes: (untyped) -> ::Object?
120
+ def default: (untyped) -> ::Object?
121
+ def deprecated: (untyped) -> ::Object?
122
+ def description: (untyped) -> ::Object?
123
+ def detail: (untyped) -> ::Object?
124
+ def entity: (untyped) -> ::Object?
125
+ def headers: (untyped) -> ::Object?
126
+ def hidden: (untyped) -> ::Object?
127
+ def http_codes: (untyped) -> ::Object?
128
+ def is_array: (untyped) -> ::Object?
129
+ def named: (untyped) -> ::Object?
130
+ def nickname: (untyped) -> ::Object?
131
+ def params: (untyped) -> ::Object?
132
+ def produces: (untyped) -> ::Object?
133
+ def security: (untyped) -> ::Object?
134
+ def summary: (untyped) -> ::Object?
135
+ def tags: (untyped) -> ::Object?
136
+ def success: (*untyped) -> ::Object?
137
+ def failure: (*untyped) -> ::Object?
138
+ def configuration: () -> untyped
139
+ def to_hash: () -> ::Hash[untyped, untyped]
140
+ end
141
+ end
142
+ end
143
+
144
+ class API
145
+ extend DSL::ClassMethods
146
+
147
+ # The class object a `Grape::API` subclass's declaration calls are forwarded to. `namespace`
148
+ # bodies `instance_eval` on this class object, so the same `extend`ed surface covers calls made
149
+ # inside them.
150
+ class Instance
151
+ extend DSL::ClassMethods
152
+ end
153
+ end
154
+
155
+ module Validations
156
+ # The receiver `params`/`requires`/`optional`/`given`/`with` blocks `instance_eval` on. Its
157
+ # DSL lives in `Grape::DSL::Parameters`; the declarations here cover the block-relevant and
158
+ # commonly-called subset.
159
+ class ParamsScope
160
+ def requires: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
161
+ def optional: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
162
+ def given: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
163
+ def with: (*untyped, **untyped) ?{ () -> untyped } -> ::Object?
164
+ def use: (*untyped) -> ::Object?
165
+ def mutually_exclusive: (*untyped) -> ::Object?
166
+ def exactly_one_of: (*untyped) -> ::Object?
167
+ def at_least_one_of: (*untyped) -> ::Object?
168
+ def all_or_none_of: (*untyped) -> ::Object?
169
+ end
170
+ end
171
+
172
+ # Runtime route context — verb bodies execute as `Grape::Endpoint` instance methods
173
+ # (`Grape::Endpoint#run` evaluates the stored block inside the endpoint instance). The methods
174
+ # here are `Grape::DSL::InsideRoute`, `Grape::DSL::Headers`, `Grape::DSL::Settings`, and the
175
+ # `def_delegators :request` surface (`params`/`headers`/`cookies`).
176
+ class Endpoint
177
+ def params: () -> ::Hash[untyped, untyped]
178
+ def headers: () -> ::Hash[untyped, untyped]
179
+ # `Endpoint#cookies` delegates to `Grape::Request#cookies`, which builds a `Grape::Cookies`
180
+ # wrapper — not a Hash (`lib/grape/cookies.rb`, `lib/grape/request.rb`).
181
+ def cookies: () -> Grape::Cookies
182
+ def env: () -> ::Hash[untyped, untyped]
183
+ # `request` is a `Grape::Request` (Rack::Request subclass) at runtime — untyped rather than
184
+ # `::Object` so `request.params`/`request.GET` chains don't read as undefined-method findings.
185
+ def request: () -> untyped
186
+ def declared: (*untyped, **untyped) -> ::Hash[untyped, untyped]
187
+ def version: () -> ::Object?
188
+ def error!: (*untyped, **untyped) -> bot
189
+ def redirect: (untyped url, ?permanent: untyped, ?body: untyped) -> ::Object?
190
+ def status: (?untyped) -> ::Object?
191
+ def content_type: (?untyped) -> ::Object?
192
+ def body: (?untyped) -> ::Object?
193
+ # `present` returns the representation (entity, Hash, or the bare object) — untyped.
194
+ def present: (*untyped, **untyped) -> untyped
195
+ # `route` is the `Grape::Router::Route` for the current endpoint — untyped.
196
+ def route: () -> untyped
197
+ def header: (?untyped, ?untyped) -> ::Object?
198
+ def route_setting: (untyped, ?untyped) -> ::Object?
199
+ def stream: (?untyped) -> ::Object?
200
+ def sendfile: (?untyped) -> ::Object?
201
+ # `error_response` lives on `Grape::Middleware::Error`, not on the endpoint — not declared here.
202
+ end
203
+
204
+ # The Rack-cookie wrapper `Grape::Request#cookies` returns (`def_delegators :cookies` for `[]`
205
+ # and `each`, plus its own `[]=` / `delete` / `response_cookies`). Not a Hash.
206
+ class Cookies
207
+ def []: (untyped) -> untyped
208
+ def []=: (untyped, untyped) -> untyped
209
+ def each: (*untyped) ?{ (*untyped) -> untyped } -> untyped
210
+ def response_cookies: () { (untyped, untyped) -> untyped } -> untyped
211
+ def delete: (untyped, **untyped) -> untyped
212
+ end
213
+
214
+ # grape-entity's declaration target (`class Foo < Grape::Entity`). `expose` bodies run via
215
+ # `block.call` — `self` stays the Entity subclass's class object — so nested `expose` calls
216
+ # resolve through the same singleton surface without a `block_as_methods` entry.
217
+ class Entity
218
+ def self.expose: (*untyped, **untyped) ?{ () -> untyped } -> ::Array[untyped]
219
+ def self.unexpose: (*untyped) -> ::Object?
220
+ def self.unexpose_all: () -> ::Object?
221
+ def self.with_options: (untyped) { () -> untyped } -> ::Object?
222
+ def self.documentation: () -> ::Hash[untyped, untyped]
223
+ # Returns `formatters[name.to_sym] = block` — the registered Proc.
224
+ def self.format_with: (untyped) { (untyped) -> untyped } -> ::Proc
225
+ def self.root: (untyped, ?untyped) -> ::Object?
226
+ def self.root_element: (untyped) -> ::Object?
227
+ # Result is an Entity instance, an Array of them, or a `{root => inner}` Hash
228
+ # (`lib/grape_entity/entity.rb` `self.represent`) — untyped, not `::Object`, so chained
229
+ # `serializable_hash` / `map` / exposed-attribute reads stay quiet.
230
+ def self.represent: (*untyped, **untyped) -> untyped
231
+ def self.present_collection: (?untyped, ?untyped) -> ::Object?
232
+ # Runtime returns `Exposure::NestingExposure::NestedExposures` — an `Enumerable` wrapper with
233
+ # `find_by` / `select_by` / `delete_by` that Array does not have.
234
+ def self.root_exposures: () -> Exposure::NestingExposure::NestedExposures
235
+
236
+ # The instance-side output surface — `serializable_hash` is the primary representation
237
+ # output (`nil` when the wrapped object is nil); `as_json`/`to_json` delegate to it.
238
+ def serializable_hash: (?untyped) -> ::Hash[untyped, untyped]?
239
+ def as_json: (*untyped, **untyped) -> untyped
240
+
241
+ module Exposure
242
+ class NestingExposure
243
+ # `Enumerable` wrapper over the exposure list (grape-entity `nested_exposures.rb`):
244
+ # `each`/`to_ary`/`to_a`/`[]`/`size`/`empty?`/`==` delegate to the inner Array, and
245
+ # `find_by`/`select_by`/`delete_by`/`<<`/`clear` are its own API.
246
+ class NestedExposures
247
+ include Enumerable[untyped]
248
+ def find_by: (untyped) -> untyped
249
+ def select_by: (untyped) -> untyped
250
+ def <<: (untyped) -> untyped
251
+ def delete_by: (*untyped) -> untyped
252
+ def clear: () -> untyped
253
+ def to_ary: () -> ::Array[untyped]
254
+ def to_a: () -> ::Array[untyped]
255
+ def []: (*untyped) -> untyped
256
+ def ==: (untyped) -> bool
257
+ def size: () -> ::Integer
258
+ def empty?: () -> bool
259
+ end
260
+ end
261
+ end
262
+ end
263
+ end
@@ -40,16 +40,18 @@ module Rigor
40
40
 
41
41
  module_function
42
42
 
43
- # @param paths [Array<String>] absolute paths to `.rb` files the project's `paths:` resolves to.
44
- # @return [Hash{Symbol => Hash}] frozen 4-key result: `:types` (per-`Schema::Object` field
43
+ # @param paths — absolute paths to `.rb` files the project's `paths:` resolves to.
44
+ # @param io_boundary — the plugin's {Rigor::Plugin::IoBoundary}; every source read goes
45
+ # through it (#630) so each scanned file is a recorded cache dependency.
46
+ # @return frozen 4-key result: `:types` (per-`Schema::Object` field
45
47
  # table), `:enums` (per-`Schema::Enum` value list), `:input_objects`
46
48
  # (per-`Schema::InputObject` argument table), `:mutations` (per-`Schema::Mutation`
47
49
  # arguments+fields table). Any subset may be empty when no recognisable declaration of that
48
50
  # kind is found.
49
- def scan(paths:)
51
+ def scan(paths:, io_boundary:)
50
52
  acc = empty_accumulator
51
53
  paths.each do |path|
52
- merge_accumulator(acc, scan_file(path))
54
+ merge_accumulator(acc, scan_file(path, io_boundary))
53
55
  end
54
56
  freeze_accumulator(acc)
55
57
  end
@@ -75,8 +77,8 @@ module Rigor
75
77
  end
76
78
  private_class_method :freeze_accumulator
77
79
 
78
- def scan_file(path)
79
- source = File.read(path)
80
+ def scan_file(path, io_boundary)
81
+ source = io_boundary.read_file(path)
80
82
  parse_result = Prism.parse(source, filepath: path)
81
83
  return empty_accumulator unless parse_result.errors.empty?
82
84
 
@@ -40,6 +40,21 @@ module Rigor
40
40
  # required: ...` declarations.
41
41
  # - No user-facing diagnostics yet.
42
42
  #
43
+ # ## Shipped DSL signature (`sig/graphql.rbs`)
44
+ #
45
+ # Since graphql-ruby ships no RBS, the manifest's `signature_paths:` contributes the class-level
46
+ # DSL surface — `field`/`argument`/`value`/`implements`/`description`/`graphql_name` and friends —
47
+ # following graphql-ruby's real `Member`-rooted ancestry so subclass bodies stop reading every
48
+ # DSL call as `Dynamic[top]`. Return types are the real carriers (`field` → `Schema::Field`,
49
+ # `Enum.value` → `Schema::EnumValue`, setter/getter macros → their configured value) rather than
50
+ # `void`, which the engine recovers as `top`. Scope and deferrals are documented at the top of
51
+ # the sig file.
52
+ #
53
+ # The declared classes stay in `open_receivers:` because graphql-ruby's real surface is open:
54
+ # schema plugins (`use`-able extensions) and user base classes add class-level DSL methods this
55
+ # signature does not enumerate, so `call.undefined-method` must not read these classes as
56
+ # closed.
57
+ #
43
58
  # ## Deferred (demand-driven)
44
59
  #
45
60
  # - **`resolver:` / `mutation:` reroute** recognition.
@@ -50,16 +65,72 @@ module Rigor
50
65
  class Graphql < Rigor::Plugin::Base
51
66
  manifest(
52
67
  id: "graphql",
53
- version: "0.1.0",
68
+ target_gems: ["graphql"],
69
+ # 0.2.0, 2026-09-20 (#1100) — `signature_paths:` contributes the graphql-ruby class-level DSL
70
+ # surface (`field`/`argument`/`value`/…), typed with the real carriers (`Field`/`Argument`/
71
+ # `EnumValue`/…) so DSL calls stop reading `Dynamic[top]` inside recognised subclasses.
72
+ version: "0.2.0",
54
73
  description: "Recognises `class T < GraphQL::Schema::{Object,Enum,InputObject,Mutation}` " \
55
74
  "subclasses; publishes the per-type field-type table, the per-enum value " \
56
75
  "list, the per-input-object argument table, and the per-mutation arguments+fields " \
57
- "table.",
76
+ "table; ships the graphql-ruby class-level DSL signature surface.",
77
+ signature_paths: ["sig"],
78
+ # ADR-43 WD4 — the classes the bundled sig covers completely enough that a Ruby-source subclass
79
+ # (`class PostType < GraphQL::Schema::Object`) may bridge inherited calls to the RBS ancestor.
80
+ # Listing one turns on `call.undefined-method`/arity checks for inherited DSL calls on every
81
+ # subclass — justified here because the sig IS the authority (graphql-ruby ships none).
82
+ rbs_complete_ancestors: %w[
83
+ GraphQL::Schema
84
+ GraphQL::Schema::Member
85
+ GraphQL::Schema::Object
86
+ GraphQL::Schema::Resolver
87
+ GraphQL::Schema::Mutation
88
+ GraphQL::Schema::RelayClassicMutation
89
+ GraphQL::Schema::Subscription
90
+ GraphQL::Schema::InputObject
91
+ GraphQL::Schema::Enum
92
+ GraphQL::Schema::EnumValue
93
+ GraphQL::Schema::Union
94
+ GraphQL::Schema::Scalar
95
+ GraphQL::Schema::Directive
96
+ GraphQL::Schema::Field
97
+ GraphQL::Schema::Argument
98
+ GraphQL::Dataloader::Source
99
+ GraphQL::Types::Relay::BaseConnection
100
+ GraphQL::Types::Relay::BaseEdge
101
+ GraphQL::Types::Relay::PageInfo
102
+ GraphQL::Types::Relay::BaseField
103
+ ],
104
+ open_receivers: %w[
105
+ GraphQL::Schema
106
+ GraphQL::Schema::Member
107
+ GraphQL::Schema::Object
108
+ GraphQL::Schema::Resolver
109
+ GraphQL::Schema::Mutation
110
+ GraphQL::Schema::RelayClassicMutation
111
+ GraphQL::Schema::Subscription
112
+ GraphQL::Schema::InputObject
113
+ GraphQL::Schema::Enum
114
+ GraphQL::Schema::EnumValue
115
+ GraphQL::Schema::Union
116
+ GraphQL::Schema::Scalar
117
+ GraphQL::Schema::Directive
118
+ GraphQL::Schema::Field
119
+ GraphQL::Schema::Argument
120
+ GraphQL::Schema::Interface
121
+ GraphQL::Query
122
+ GraphQL::Query::Context
123
+ GraphQL::Dataloader
124
+ GraphQL::Dataloader::Source
125
+ GraphQL::Types::Relay::BaseConnection
126
+ GraphQL::Types::Relay::BaseEdge
127
+ GraphQL::Types::Relay::BaseField
128
+ ],
58
129
  produces: %i[graphql_type_table graphql_enum_table graphql_input_object_table graphql_mutation_table]
59
130
  )
60
131
 
61
132
  def prepare(services)
62
- scanned = TypeScanner.scan(paths: scannable_paths(services))
133
+ scanned = TypeScanner.scan(paths: scannable_paths(services), io_boundary: io_boundary)
63
134
  publish_if_present(services, :graphql_type_table, scanned.fetch(:types))
64
135
  publish_if_present(services, :graphql_enum_table, scanned.fetch(:enums))
65
136
  publish_if_present(services, :graphql_input_object_table, scanned.fetch(:input_objects))
@@ -78,11 +149,13 @@ module Rigor
78
149
  services.fact_store.publish(plugin_id: manifest.id, name: name, value: value)
79
150
  end
80
151
 
152
+ # ADR-45 WD1b (#613 / #630) — the classification probes go through the boundary, so an entry that
153
+ # is not there yet (or stops being a directory) is a recorded dependency of the scan's input set.
81
154
  def scannable_paths(services)
82
155
  @scannable_paths ||= services.configuration.paths.flat_map do |entry|
83
- if File.directory?(entry)
156
+ if io_boundary.directory?(entry)
84
157
  Dir.glob(File.join(entry, "**", "*.rb"), sort: true)
85
- elsif File.file?(entry) && entry.end_with?(".rb")
158
+ elsif io_boundary.file?(entry) && entry.end_with?(".rb")
86
159
  [entry]
87
160
  else
88
161
  []