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.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/data/capability_roles/capability_roles.rbs +36 -0
- data/data/core_overlay/enumerable.rbs +51 -0
- data/data/core_overlay/enumerator.rbs +84 -0
- data/data/core_overlay/hash_rbs3.rbs +41 -0
- data/data/core_overlay/process.rbs +40 -0
- data/data/core_overlay/string_io.rbs +33 -0
- data/data/effects/core.yml +3 -3
- data/data/gem_overlay/activesupport/core_ext.rbs +236 -17
- data/docs/handbook/02-everyday-types.md +17 -14
- data/docs/handbook/03-narrowing.md +132 -14
- data/docs/handbook/04-tuples-and-shapes.md +8 -6
- data/docs/handbook/05-methods-and-blocks.md +1 -1
- data/docs/handbook/06-classes.md +2 -2
- data/docs/handbook/07-rbs-and-extended.md +19 -1
- data/docs/handbook/10-sorbet.md +9 -10
- data/docs/handbook/11-sig-gen.md +525 -13
- data/docs/handbook/README.md +1 -1
- data/docs/handbook/appendix-elixir.md +2 -2
- data/docs/handbook/appendix-go.md +2 -2
- data/docs/handbook/appendix-java-csharp.md +2 -2
- data/docs/handbook/appendix-mypy.md +2 -2
- data/docs/handbook/appendix-phpstan.md +1 -1
- data/docs/handbook/appendix-rust.md +1 -1
- data/docs/handbook/appendix-type-theory.md +4 -4
- data/docs/handbook/appendix-typescript.md +1 -1
- data/docs/llms.txt +2 -0
- data/docs/manual/02-cli-reference.md +95 -6
- data/docs/manual/03-configuration.md +18 -0
- data/docs/manual/04-diagnostics.md +15 -0
- data/docs/manual/07-plugins.md +15 -5
- data/docs/manual/08-skills.md +23 -2
- data/docs/manual/10-mcp-server.md +3 -2
- data/docs/manual/11-ci.md +9 -0
- data/docs/manual/15-type-protection-coverage.md +8 -0
- data/docs/manual/16-rbs-extended-annotations.md +46 -8
- data/docs/manual/18-removing-dead-code.md +10 -8
- data/docs/manual/19-effect-labels.md +10 -0
- data/docs/manual/plugins/README.md +7 -0
- data/docs/manual/plugins/rigor-actioncable.md +8 -1
- data/docs/manual/plugins/rigor-actionmailer.md +7 -0
- data/docs/manual/plugins/rigor-actionpack.md +261 -0
- data/docs/manual/plugins/rigor-active-model-serializers.md +153 -0
- data/docs/manual/plugins/rigor-activejob.md +7 -0
- data/docs/manual/plugins/rigor-activerecord.md +138 -4
- data/docs/manual/plugins/rigor-activestorage.md +8 -1
- data/docs/manual/plugins/rigor-activesupport-core-ext.md +43 -7
- data/docs/manual/plugins/rigor-grape.md +106 -0
- data/docs/manual/plugins/rigor-graphql.md +23 -2
- data/docs/manual/plugins/rigor-pundit.md +8 -1
- data/docs/manual/plugins/rigor-rails-i18n.md +10 -5
- data/docs/manual/plugins/rigor-rails-routes.md +7 -0
- data/docs/manual/plugins/rigor-rbs-inline.md +229 -1
- data/docs/manual/plugins/rigor-sidekiq.md +8 -1
- data/docs/manual/plugins/rigor-sorbet.md +21 -5
- data/exe/rigor +19 -4
- data/lib/rigor/analysis/baseline.rb +3 -3
- data/lib/rigor/analysis/check_rules/always_truthy_condition_collector.rb +1 -1
- data/lib/rigor/analysis/check_rules/dead_version_guard_arms.rb +1 -5
- data/lib/rigor/analysis/check_rules/declaration_sourced_guard.rb +167 -2
- data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +10 -2
- data/lib/rigor/analysis/check_rules/lexical_method_sites.rb +189 -0
- data/lib/rigor/analysis/check_rules/main_pass_collector.rb +6 -4
- data/lib/rigor/analysis/check_rules/published_constant_guard.rb +15 -6
- data/lib/rigor/analysis/check_rules/rule_ids.rb +21 -6
- data/lib/rigor/analysis/check_rules/rule_walk.rb +41 -5
- data/lib/rigor/analysis/check_rules/self_closedness_scanner.rb +1 -1
- data/lib/rigor/analysis/check_rules/shadowed_rescue_collector.rb +1 -1
- data/lib/rigor/analysis/check_rules/source_arity.rb +323 -0
- data/lib/rigor/analysis/check_rules/special_global_setters.rb +146 -0
- data/lib/rigor/analysis/check_rules/unreachable_clause_collector.rb +38 -4
- data/lib/rigor/analysis/check_rules/void_value_use_collector.rb +0 -1
- data/lib/rigor/analysis/check_rules.rb +718 -79
- data/lib/rigor/analysis/crash_signature.rb +8 -24
- data/lib/rigor/analysis/dependency_recorder.rb +23 -0
- data/lib/rigor/analysis/dependency_source_inference/boundary_cross_reporter.rb +1 -1
- data/lib/rigor/analysis/dependency_source_inference/builder.rb +0 -2
- data/lib/rigor/analysis/dependency_source_inference/gem_resolver.rb +0 -2
- data/lib/rigor/analysis/dependency_source_inference/index.rb +5 -5
- data/lib/rigor/analysis/dependency_source_inference/return_type_heuristic.rb +1 -2
- data/lib/rigor/analysis/dependency_source_inference/walker.rb +4 -4
- data/lib/rigor/analysis/effects_cache_probe.rb +3 -4
- data/lib/rigor/analysis/erb_template_detector.rb +1 -2
- data/lib/rigor/analysis/fact_store.rb +15 -1
- data/lib/rigor/analysis/incremental.rb +42 -0
- data/lib/rigor/analysis/incremental_session.rb +117 -26
- data/lib/rigor/analysis/plugin_fact_fingerprint.rb +0 -1
- data/lib/rigor/analysis/project_scan.rb +11 -1
- data/lib/rigor/analysis/reachability/graph.rb +3 -5
- data/lib/rigor/analysis/reachability/plugin_roots.rb +5 -5
- data/lib/rigor/analysis/reachability/project_files.rb +2 -2
- data/lib/rigor/analysis/reachability/scan.rb +5 -5
- data/lib/rigor/analysis/reachability/scan_cache.rb +3 -2
- data/lib/rigor/analysis/reachability/signature_scan.rb +2 -2
- data/lib/rigor/analysis/result.rb +1 -3
- data/lib/rigor/analysis/rule_catalog.rb +131 -1
- data/lib/rigor/analysis/run_cache_key.rb +21 -12
- data/lib/rigor/analysis/run_cache_probe.rb +3 -5
- data/lib/rigor/analysis/runner/buffer_pool_dispatcher.rb +6 -8
- data/lib/rigor/analysis/runner/declaration_position.rb +1 -2
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +340 -33
- data/lib/rigor/analysis/runner/effect_annotation_residual_pass.rb +2 -3
- data/lib/rigor/analysis/runner/effect_envelope_pass.rb +18 -14
- data/lib/rigor/analysis/runner/pool_coordinator.rb +357 -97
- data/lib/rigor/analysis/runner/project_pre_passes.rb +38 -13
- data/lib/rigor/analysis/runner/run_snapshots.rb +6 -1
- data/lib/rigor/analysis/runner.rb +407 -51
- data/lib/rigor/analysis/template_unit_collector.rb +303 -0
- data/lib/rigor/analysis/template_unit_paths.rb +91 -0
- data/lib/rigor/analysis/template_unit_positions.rb +293 -0
- data/lib/rigor/analysis/template_units.rb +399 -0
- data/lib/rigor/analysis/worker_session.rb +62 -20
- data/lib/rigor/bleeding_edge.rb +10 -24
- data/lib/rigor/builtins/hkt_builtins.rb +3 -2
- data/lib/rigor/builtins/imported_refinements.rb +159 -21
- data/lib/rigor/builtins/predefined_constant_refinements.rb +5 -7
- data/lib/rigor/builtins/regex_refinement.rb +21 -13
- data/lib/rigor/builtins/static_return_refinements.rb +7 -6
- data/lib/rigor/cache/annotation_location.rb +2 -4
- data/lib/rigor/cache/descriptor.rb +63 -20
- data/lib/rigor/cache/engine_source.rb +33 -5
- data/lib/rigor/cache/file_digest.rb +9 -1
- data/lib/rigor/cache/incremental_snapshot.rb +72 -6
- data/lib/rigor/cache/rbs_cache_producer.rb +4 -0
- data/lib/rigor/cache/rbs_class_ancestor_table.rb +0 -3
- data/lib/rigor/cache/rbs_class_type_param_names.rb +0 -3
- data/lib/rigor/cache/rbs_constant_table.rb +0 -3
- data/lib/rigor/cache/rbs_descriptor.rb +112 -14
- data/lib/rigor/cache/rbs_environment.rb +8 -4
- data/lib/rigor/cache/rbs_known_class_names.rb +0 -3
- data/lib/rigor/cache/store.rb +76 -32
- data/lib/rigor/ci_detector.rb +1 -0
- data/lib/rigor/cli/annotate_command.rb +5 -6
- data/lib/rigor/cli/check_command.rb +57 -10
- data/lib/rigor/cli/check_invocation.rb +6 -11
- data/lib/rigor/cli/check_runner_factory.rb +1 -5
- data/lib/rigor/cli/coverage_command.rb +1 -1
- data/lib/rigor/cli/coverage_mutation.rb +12 -3
- data/lib/rigor/cli/coverage_scan.rb +1 -5
- data/lib/rigor/cli/diff_command.rb +1 -1
- data/lib/rigor/cli/doc_links.rb +4 -4
- data/lib/rigor/cli/docs_command.rb +6 -6
- data/lib/rigor/cli/doctor_command.rb +85 -38
- data/lib/rigor/cli/effects_command.rb +2 -2
- data/lib/rigor/cli/effects_diff_renderer.rb +3 -3
- data/lib/rigor/cli/effects_snapshot_command.rb +1 -1
- data/lib/rigor/cli/explain_command.rb +34 -1
- data/lib/rigor/cli/fused_protection_report.rb +7 -1
- data/lib/rigor/cli/lsp_command.rb +1 -1
- data/lib/rigor/cli/mcp_command.rb +1 -1
- data/lib/rigor/cli/measurement_integrity_warning.rb +4 -5
- data/lib/rigor/cli/mutation_fork_scan.rb +6 -6
- data/lib/rigor/cli/mutation_protection_report.rb +7 -1
- data/lib/rigor/cli/plugin_command.rb +4 -4
- data/lib/rigor/cli/plugins_command.rb +2 -1
- data/lib/rigor/cli/prism_colorizer.rb +1 -2
- data/lib/rigor/cli/protection_fork_scan.rb +6 -6
- data/lib/rigor/cli/show_bleedingedge_command.rb +1 -1
- data/lib/rigor/cli/sig_gen_command.rb +212 -31
- data/lib/rigor/cli/skill_command.rb +2 -2
- data/lib/rigor/cli/skill_deep_probe.rb +4 -4
- data/lib/rigor/cli/skill_describe.rb +35 -35
- data/lib/rigor/cli/trace_command.rb +4 -4
- data/lib/rigor/cli/trace_renderer.rb +5 -6
- data/lib/rigor/cli/triage_command.rb +1 -1
- data/lib/rigor/cli/type_of_command.rb +29 -11
- data/lib/rigor/cli/type_of_renderer.rb +20 -9
- data/lib/rigor/cli/type_of_template_probe.rb +189 -0
- data/lib/rigor/cli/type_scan_command.rb +4 -4
- data/lib/rigor/cli/unused_command.rb +11 -3
- data/lib/rigor/cli/upgrade_command.rb +1 -1
- data/lib/rigor/cli.rb +89 -9
- data/lib/rigor/config_audit.rb +30 -5
- data/lib/rigor/configuration/severity_profile.rb +25 -9
- data/lib/rigor/configuration.rb +109 -7
- data/lib/rigor/effects/ancestry_recorder.rb +191 -0
- data/lib/rigor/effects/attribution.rb +12 -5
- data/lib/rigor/effects/callee_rule.rb +368 -0
- data/lib/rigor/effects/catalog.rb +7 -4
- data/lib/rigor/effects/collector.rb +11 -5
- data/lib/rigor/effects/config_envelopes.rb +15 -10
- data/lib/rigor/effects/definition_context.rb +179 -0
- data/lib/rigor/effects/definition_lines.rb +25 -6
- data/lib/rigor/effects/effect_table.rb +11 -4
- data/lib/rigor/effects/entry_points.rb +0 -2
- data/lib/rigor/effects/envelope_check.rb +9 -9
- data/lib/rigor/effects/envelope_index.rb +20 -8
- data/lib/rigor/effects/file_collection.rb +59 -5
- data/lib/rigor/effects/framework_units.rb +5 -7
- data/lib/rigor/effects/identity.rb +20 -6
- data/lib/rigor/effects/inline_anchor.rb +7 -7
- data/lib/rigor/effects/label_intent.rb +3 -4
- data/lib/rigor/effects/liskov_check.rb +8 -8
- data/lib/rigor/effects/local_ownership.rb +38 -12
- data/lib/rigor/effects/method_key.rb +22 -1
- data/lib/rigor/effects/mutation_classifier.rb +23 -12
- data/lib/rigor/effects/plugin_facts.rb +47 -37
- data/lib/rigor/effects/propagator.rb +297 -19
- data/lib/rigor/effects/registry.rb +1 -1
- data/lib/rigor/effects/scanner.rb +122 -73
- data/lib/rigor/effects/signature_sources.rb +4 -6
- data/lib/rigor/effects/snapshot.rb +12 -11
- data/lib/rigor/effects/snapshot_diff.rb +1 -1
- data/lib/rigor/effects/summary.rb +27 -4
- data/lib/rigor/effects/unit_scan.rb +393 -38
- data/lib/rigor/effects/unknown_label_check.rb +3 -8
- data/lib/rigor/effects/unknown_label_report.rb +3 -4
- data/lib/rigor/effects/visibility.rb +101 -0
- data/lib/rigor/environment/bundle_sig_discovery.rb +6 -6
- data/lib/rigor/environment/class_registry.rb +3 -1
- data/lib/rigor/environment/failure_slot.rb +2 -2
- data/lib/rigor/environment/installed_gem_set.rb +85 -0
- data/lib/rigor/environment/lockfile_resolver.rb +68 -4
- data/lib/rigor/environment/member_consistency/comparator.rb +708 -0
- data/lib/rigor/environment/member_consistency.rb +298 -0
- data/lib/rigor/environment/missing_gem_constant_index.rb +4 -4
- data/lib/rigor/environment/rbs_collection_discovery.rb +5 -5
- data/lib/rigor/environment/rbs_coverage_report.rb +5 -5
- data/lib/rigor/environment/rbs_hierarchy.rb +3 -1
- data/lib/rigor/environment/rbs_loader.rb +674 -79
- data/lib/rigor/environment.rb +174 -24
- data/lib/rigor/flow_contribution/merger.rb +0 -2
- data/lib/rigor/flow_contribution.rb +11 -13
- data/lib/rigor/hashing/xxh3.rb +264 -0
- data/lib/rigor/inference/acceptance.rb +292 -17
- data/lib/rigor/inference/block_auto_splat.rb +216 -0
- data/lib/rigor/inference/block_call_timing.rb +338 -0
- data/lib/rigor/inference/block_parameter_binder.rb +75 -30
- data/lib/rigor/inference/block_repetition.rb +71 -0
- data/lib/rigor/inference/body_fixpoint.rb +7 -6
- data/lib/rigor/inference/budget_trace.rb +3 -6
- data/lib/rigor/inference/builtins/method_catalog.rb +2 -1
- data/lib/rigor/inference/builtins/string_catalog.rb +1 -1
- data/lib/rigor/inference/captured_locals.rb +389 -18
- data/lib/rigor/inference/closure_escape_analyzer.rb +159 -17
- data/lib/rigor/inference/content_join.rb +200 -27
- data/lib/rigor/inference/coverage_scanner.rb +4 -6
- data/lib/rigor/inference/def_return_typer.rb +11 -7
- data/lib/rigor/inference/define_method_block_self.rb +64 -0
- data/lib/rigor/inference/dynamic_origin.rb +1 -1
- data/lib/rigor/inference/element_read_widening.rb +180 -0
- data/lib/rigor/inference/error_info.rb +196 -0
- data/lib/rigor/inference/expression_typer.rb +2124 -468
- data/lib/rigor/inference/external_ancestor_resolution.rb +267 -0
- data/lib/rigor/inference/fork_map.rb +5 -7
- data/lib/rigor/inference/fresh_frame_blocks.rb +127 -0
- data/lib/rigor/inference/global_write_census.rb +239 -0
- data/lib/rigor/inference/guard_rebinding.rb +447 -0
- data/lib/rigor/inference/hash_lookup_mutation.rb +88 -0
- data/lib/rigor/inference/hkt_reducer.rb +2 -3
- data/lib/rigor/inference/hkt_registry.rb +4 -7
- data/lib/rigor/inference/index_write_widening.rb +16 -7
- data/lib/rigor/inference/indexed_narrowing.rb +61 -9
- data/lib/rigor/inference/jump_targets.rb +82 -0
- data/lib/rigor/inference/last_line/implicit_self.rb +210 -0
- data/lib/rigor/inference/last_line/self_evidence.rb +329 -0
- data/lib/rigor/inference/last_line.rb +340 -0
- data/lib/rigor/inference/last_status.rb +144 -0
- data/lib/rigor/inference/macro_block_self_type.rb +168 -21
- data/lib/rigor/inference/match_rebinding/calls.rb +281 -0
- data/lib/rigor/inference/match_rebinding/frame.rb +148 -0
- data/lib/rigor/inference/match_rebinding/operands.rb +236 -0
- data/lib/rigor/inference/match_rebinding/self_calls.rb +83 -0
- data/lib/rigor/inference/match_rebinding.rb +392 -0
- data/lib/rigor/inference/method_dispatcher/alias_strict_nominals.rb +36 -0
- data/lib/rigor/inference/method_dispatcher/block_folding.rb +87 -33
- data/lib/rigor/inference/method_dispatcher/cgi_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/constant_folding.rb +305 -19
- data/lib/rigor/inference/method_dispatcher/data_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/facet_distribution.rb +147 -0
- data/lib/rigor/inference/method_dispatcher/file_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/hash_transform_keys_folding.rb +191 -0
- data/lib/rigor/inference/method_dispatcher/iterator_dispatch.rb +6 -2
- data/lib/rigor/inference/method_dispatcher/json_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/kernel_dispatch.rb +7 -1
- data/lib/rigor/inference/method_dispatcher/match_data_folding.rb +159 -0
- data/lib/rigor/inference/method_dispatcher/math_folding.rb +41 -3
- data/lib/rigor/inference/method_dispatcher/method_folding.rb +2 -5
- data/lib/rigor/inference/method_dispatcher/overload_selector.rb +165 -111
- data/lib/rigor/inference/method_dispatcher/process_folding.rb +56 -0
- data/lib/rigor/inference/method_dispatcher/proven_overload.rb +72 -0
- data/lib/rigor/inference/method_dispatcher/random_folding.rb +82 -0
- data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +1046 -69
- data/lib/rigor/inference/method_dispatcher/receiver_affinity.rb +25 -4
- data/lib/rigor/inference/method_dispatcher/reduce_folding.rb +2 -8
- data/lib/rigor/inference/method_dispatcher/regexp_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/self_substitute.rb +142 -0
- data/lib/rigor/inference/method_dispatcher/set_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +129 -54
- data/lib/rigor/inference/method_dispatcher/shellwords_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/singleton_mixin_dispatch.rb +1 -2
- data/lib/rigor/inference/method_dispatcher/struct_folding.rb +5 -6
- data/lib/rigor/inference/method_dispatcher/struct_materialization.rb +85 -4
- data/lib/rigor/inference/method_dispatcher/time_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/universal_object_dispatch.rb +1 -2
- data/lib/rigor/inference/method_dispatcher/uri_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher.rb +225 -25
- data/lib/rigor/inference/method_parameter_binder.rb +12 -9
- data/lib/rigor/inference/multi_target_binder.rb +341 -55
- data/lib/rigor/inference/mutation_rejoin.rb +171 -0
- data/lib/rigor/inference/mutation_widening.rb +156 -85
- data/lib/rigor/inference/narrowing.rb +835 -162
- data/lib/rigor/inference/operand_effects.rb +167 -0
- data/lib/rigor/inference/operand_walk.rb +88 -0
- data/lib/rigor/inference/optimistic_origin.rb +153 -16
- data/lib/rigor/inference/origin_lookup.rb +2 -3
- data/lib/rigor/inference/parameter_inference_collector.rb +7 -7
- data/lib/rigor/inference/pre_eval_constants.rb +6 -5
- data/lib/rigor/inference/precision_scanner.rb +3 -4
- data/lib/rigor/inference/project_method_ownership.rb +136 -0
- data/lib/rigor/inference/project_patched_methods.rb +9 -4
- data/lib/rigor/inference/project_patched_scanner.rb +10 -6
- data/lib/rigor/inference/protection_scanner.rb +1 -2
- data/lib/rigor/inference/range_constant.rb +57 -0
- data/lib/rigor/inference/rbs_type_translator.rb +49 -11
- data/lib/rigor/inference/receiver_alias.rb +93 -4
- data/lib/rigor/inference/receiver_blind_block.rb +219 -0
- data/lib/rigor/inference/refinement_mutation.rb +76 -0
- data/lib/rigor/inference/repeated_or_writes.rb +463 -0
- data/lib/rigor/inference/return_barrier.rb +54 -0
- data/lib/rigor/inference/rewrite_mutation.rb +120 -0
- data/lib/rigor/inference/scope_indexer.rb +5228 -627
- data/lib/rigor/inference/statement_evaluator.rb +3452 -595
- data/lib/rigor/inference/stored_block_call.rb +54 -0
- data/lib/rigor/inference/string_mutation.rb +97 -0
- data/lib/rigor/inference/struct_fold_safety.rb +6 -7
- data/lib/rigor/inference/synthetic_method_index.rb +1 -2
- data/lib/rigor/inference/synthetic_method_scanner.rb +4 -6
- data/lib/rigor/inference/unknown_store_widening.rb +200 -0
- data/lib/rigor/inference/unthreaded_rebinds.rb +282 -0
- data/lib/rigor/inference/version_guard.rb +28 -21
- data/lib/rigor/inference/void_origin.rb +3 -3
- data/lib/rigor/inference/void_tail_summary.rb +2 -4
- data/lib/rigor/language_server/buffer_table.rb +4 -4
- data/lib/rigor/language_server/completion_provider.rb +1 -1
- data/lib/rigor/language_server/debouncer.rb +0 -1
- data/lib/rigor/language_server/diagnostic_publisher.rb +7 -6
- data/lib/rigor/language_server/document_symbol_provider.rb +1 -1
- data/lib/rigor/language_server/folding_range_provider.rb +1 -1
- data/lib/rigor/language_server/hover_provider.rb +1 -1
- data/lib/rigor/language_server/hover_renderer.rb +4 -4
- data/lib/rigor/language_server/incremental_sync.rb +6 -6
- data/lib/rigor/language_server/project_context.rb +7 -8
- data/lib/rigor/language_server/publish_batcher.rb +2 -2
- data/lib/rigor/language_server/selection_range_provider.rb +2 -2
- data/lib/rigor/language_server/server.rb +9 -9
- data/lib/rigor/language_server/signature_help_provider.rb +1 -1
- data/lib/rigor/language_server/uri.rb +1 -1
- data/lib/rigor/mcp/server.rb +2 -1
- data/lib/rigor/plugin/base.rb +258 -26
- data/lib/rigor/plugin/box_probe.rb +91 -0
- data/lib/rigor/plugin/bundled_catalog.rb +167 -0
- data/lib/rigor/plugin/effect_attribution.rb +65 -11
- data/lib/rigor/plugin/effect_entry_points.rb +3 -3
- data/lib/rigor/plugin/fact_store.rb +6 -6
- data/lib/rigor/plugin/io_boundary.rb +93 -8
- data/lib/rigor/plugin/isolation.rb +29 -6
- data/lib/rigor/plugin/loader.rb +33 -13
- data/lib/rigor/plugin/macro/block_as_method.rb +45 -6
- data/lib/rigor/plugin/macro/heredoc_template.rb +1 -1
- data/lib/rigor/plugin/macro/trait_registry.rb +1 -1
- data/lib/rigor/plugin/manifest.rb +94 -11
- data/lib/rigor/plugin/registry.rb +76 -12
- data/lib/rigor/plugin/source_rbs_synthesis_reporter.rb +21 -4
- data/lib/rigor/plugin/template_unit.rb +196 -0
- data/lib/rigor/plugin/trust_policy.rb +2 -4
- data/lib/rigor/plugin/type_node_resolver.rb +3 -3
- data/lib/rigor/plugin.rb +1 -0
- data/lib/rigor/plugin_gap_advisory.rb +96 -0
- data/lib/rigor/project_environment.rb +138 -0
- data/lib/rigor/protection/analysis_guard.rb +93 -14
- data/lib/rigor/protection/closure_kill_oracle.rb +67 -23
- data/lib/rigor/protection/dependency_closure.rb +5 -8
- data/lib/rigor/protection/diagnostic_oracle.rb +2 -2
- data/lib/rigor/protection/discovery_seed.rb +14 -12
- data/lib/rigor/protection/kill_signature.rb +1 -4
- data/lib/rigor/protection/measurement_integrity.rb +1 -3
- data/lib/rigor/protection/mutation_cache.rb +7 -11
- data/lib/rigor/protection/mutation_scanner.rb +12 -15
- data/lib/rigor/protection/mutator.rb +2 -1
- data/lib/rigor/protection/test_suite_oracle.rb +5 -5
- data/lib/rigor/rbs_extended/conformance_checker.rb +4 -3
- data/lib/rigor/rbs_extended/envelope_scanner.rb +4 -6
- data/lib/rigor/rbs_extended/reporter.rb +36 -10
- data/lib/rigor/rbs_extended.rb +88 -21
- data/lib/rigor/reflection/constant_ancestors.rb +97 -0
- data/lib/rigor/reflection/constant_path.rb +139 -0
- data/lib/rigor/reflection.rb +93 -110
- data/lib/rigor/runtime/jit.rb +6 -8
- data/lib/rigor/scope/discovery_index.rb +165 -2
- data/lib/rigor/scope.rb +1041 -32
- data/lib/rigor/sig_gen/alias_index.rb +289 -0
- data/lib/rigor/sig_gen/classification.rb +22 -5
- data/lib/rigor/sig_gen/declaration_equivalence.rb +127 -0
- data/lib/rigor/sig_gen/effect_annotation.rb +202 -0
- data/lib/rigor/sig_gen/generator.rb +673 -53
- data/lib/rigor/sig_gen/inline_declarations.rb +184 -0
- data/lib/rigor/sig_gen/layout_index.rb +3 -4
- data/lib/rigor/sig_gen/meta_class_shape.rb +3 -5
- data/lib/rigor/sig_gen/method_candidate.rb +47 -3
- data/lib/rigor/sig_gen/observation_collector.rb +18 -16
- data/lib/rigor/sig_gen/path_mapper.rb +4 -6
- data/lib/rigor/sig_gen/rbs_validity.rb +4 -4
- data/lib/rigor/sig_gen/renderer.rb +128 -14
- data/lib/rigor/sig_gen/skip_reason_catalog.rb +154 -0
- data/lib/rigor/sig_gen/superclass_spelling.rb +27 -0
- data/lib/rigor/sig_gen/type_elaborator.rb +1 -3
- data/lib/rigor/sig_gen/write_result.rb +19 -3
- data/lib/rigor/sig_gen/writer.rb +189 -41
- data/lib/rigor/sig_gen.rb +3 -0
- data/lib/rigor/signature_path_audit.rb +153 -6
- data/lib/rigor/source/literals.rb +0 -23
- data/lib/rigor/source/node_children.rb +0 -2
- data/lib/rigor/source/node_locator.rb +5 -11
- data/lib/rigor/source/node_walker.rb +0 -6
- data/lib/rigor/source/parameter_envelope.rb +72 -0
- data/lib/rigor/source.rb +1 -0
- data/lib/rigor/triage/catalogue.rb +1 -3
- data/lib/rigor/triage.rb +3 -5
- data/lib/rigor/type/accepts_result.rb +24 -6
- data/lib/rigor/type/combinator.rb +144 -5
- data/lib/rigor/type/data_class.rb +2 -2
- data/lib/rigor/type/data_instance.rb +4 -4
- data/lib/rigor/type/difference.rb +1 -0
- data/lib/rigor/type/float_range.rb +128 -0
- data/lib/rigor/type/hash_shape.rb +6 -6
- data/lib/rigor/type/integer_range.rb +13 -8
- data/lib/rigor/type/nominal.rb +8 -2
- data/lib/rigor/type/refined.rb +4 -3
- data/lib/rigor/type/struct_class.rb +3 -3
- data/lib/rigor/type/struct_instance.rb +4 -4
- data/lib/rigor/type.rb +1 -0
- data/lib/rigor/type_node/generic.rb +1 -1
- data/lib/rigor/type_node/range_literal.rb +25 -0
- data/lib/rigor/type_node/resolver_chain.rb +1 -1
- data/lib/rigor/type_node.rb +1 -0
- data/lib/rigor/version.rb +1 -1
- data/lib/rigor.rb +1 -0
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/analyzer.rb +0 -4
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_discoverer.rb +0 -1
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_index.rb +0 -2
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/effects.rb +1 -0
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +10 -5
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/analyzer.rb +0 -4
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_discoverer.rb +3 -5
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_index.rb +1 -4
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb +14 -4
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb +32 -30
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_discoverer.rb +0 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_index.rb +1 -3
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_scan.rb +96 -0
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/effects.rb +65 -8
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/erb_compiler.rb +270 -0
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/render_locals.rb +402 -0
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/view_assigns.rb +370 -0
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/view_units.rb +132 -0
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +264 -3
- data/plugins/rigor-actionpack/sig/action_controller.rbs +71 -0
- data/plugins/rigor-actionpack/sig/action_view.rbs +43 -0
- data/plugins/rigor-active-model-serializers/lib/rigor/plugin/active_model_serializers/serializer_discoverer.rb +220 -0
- data/plugins/rigor-active-model-serializers/lib/rigor/plugin/active_model_serializers/serializer_index.rb +56 -0
- data/plugins/rigor-active-model-serializers/lib/rigor/plugin/active_model_serializers.rb +263 -0
- data/plugins/rigor-active-model-serializers/lib/rigor-active-model-serializers.rb +7 -0
- data/plugins/rigor-active-model-serializers/sig/active_model_serializers.rbs +45 -0
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/analyzer.rb +0 -4
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/effects.rb +2 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_discoverer.rb +0 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_index.rb +0 -2
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/recurring_scan.rb +1 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob.rb +10 -5
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/analyzer.rb +35 -3
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/effects.rb +72 -12
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +383 -7
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_index.rb +14 -6
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_parser.rb +1 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/structure_sql_parser.rb +1 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +322 -41
- data/plugins/rigor-activerecord/sig/active_record/framework.rbs +123 -0
- data/plugins/rigor-activerecord/sig/active_record/relation.rbs +206 -31
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +26 -14
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext/effects.rb +9 -2
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb +9 -2
- data/plugins/rigor-activesupport-core-ext/sig/active_support/core_ext.rbs +290 -19
- data/plugins/rigor-devise/lib/rigor/plugin/devise.rb +1 -0
- data/plugins/rigor-dry-monads/lib/rigor/plugin/dry_monads.rb +3 -0
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema/schema_scanner.rb +9 -7
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema.rb +7 -3
- data/plugins/rigor-dry-struct/lib/rigor/plugin/dry_struct.rb +1 -0
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types/alias_scanner.rb +8 -6
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types.rb +11 -7
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation/contract_scanner.rb +13 -11
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation.rb +9 -4
- data/plugins/rigor-ethon/lib/rigor/plugin/ethon.rb +2 -0
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/analyzer.rb +0 -5
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_discoverer.rb +0 -1
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_index.rb +0 -1
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot.rb +8 -1
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi/types.rb +1 -1
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi.rb +36 -4
- data/plugins/rigor-ffi-rzmq/lib/rigor/plugin/ffi_rzmq.rb +1 -0
- data/plugins/rigor-grape/lib/rigor/plugin/grape.rb +141 -0
- data/plugins/rigor-grape/lib/rigor-grape.rb +6 -0
- data/plugins/rigor-grape/sig/grape.rbs +263 -0
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql/type_scanner.rb +8 -6
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql.rb +78 -5
- data/plugins/rigor-graphql/sig/graphql.rbs +485 -0
- data/plugins/rigor-hanami/lib/rigor/plugin/hanami.rb +1 -0
- data/plugins/rigor-mangrove/lib/rigor/plugin/mangrove.rb +2 -1
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest/assertion_analyzer.rb +2 -3
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest.rb +1 -0
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/analyzer.rb +0 -5
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/authorization_scan.rb +2 -2
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_discoverer.rb +0 -1
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_index.rb +0 -1
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit.rb +12 -7
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/analyzer.rb +0 -12
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_index.rb +1 -3
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_loader.rb +0 -1
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n.rb +36 -37
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/acronyms.rb +5 -5
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/analyzer.rb +0 -10
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/devise_routes.rb +5 -3
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/doorkeeper_routes.rb +3 -2
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/grape_api_discoverer.rb +2 -2
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_discoverer.rb +2 -2
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_table.rb +9 -10
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/routes_parser.rb +2 -3
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +10 -17
- data/plugins/rigor-railties/lib/rigor/plugin/railties.rb +1 -0
- data/plugins/rigor-rbnacl/lib/rigor/plugin/rbnacl.rb +13 -1
- data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline/same_line_annotations.rb +149 -0
- data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb +324 -18
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/analyzer.rb +0 -3
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_scope_index.rb +0 -3
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_type_resolver.rb +1 -5
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb +2 -3
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec.rb +1 -0
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails/have_http_status_analyzer.rb +0 -3
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails.rb +1 -0
- data/plugins/rigor-sassc/lib/rigor/plugin/sassc.rb +1 -0
- data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers/analyzer.rb +1 -9
- data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers.rb +1 -0
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/analyzer.rb +0 -4
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/effects.rb +1 -1
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/schedule_scan.rb +2 -1
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_discoverer.rb +0 -1
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_index.rb +0 -2
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq.rb +10 -5
- data/plugins/rigor-sinatra/lib/rigor/plugin/sinatra.rb +1 -0
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/absurd_recognizer.rb +2 -5
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/assertion_recognizer.rb +1 -4
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog.rb +3 -9
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog_walker.rb +4 -4
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sig_parser.rb +1 -2
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sigil_detector.rb +3 -5
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/type_translator.rb +7 -5
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +51 -6
- data/plugins/rigor-sorbet/sig/sorbet.rbs +277 -0
- data/plugins/rigor-statesman/lib/rigor/plugin/statesman.rb +1 -0
- data/sig/rigor/analysis/baseline.rbs +69 -7
- data/sig/rigor/analysis/fact_store.rbs +1 -1
- data/sig/rigor/analysis/project_scan.rbs +74 -0
- data/sig/rigor/analysis/reachability/scan_cache.rbs +12 -0
- data/sig/rigor/cache.rbs +2 -3
- data/sig/rigor/effects/config_envelopes.rbs +100 -0
- data/sig/rigor/effects/effect_table.rbs +60 -0
- data/sig/rigor/effects/envelope.rbs +97 -0
- data/sig/rigor/effects/envelope_index.rbs +33 -0
- data/sig/rigor/effects/file_collection.rbs +81 -0
- data/sig/rigor/effects/label.rbs +26 -0
- data/sig/rigor/effects/label_set.rbs +46 -0
- data/sig/rigor/effects/method_key.rbs +24 -0
- data/sig/rigor/effects/origin.rbs +50 -0
- data/sig/rigor/effects/plugin_facts.rbs +141 -0
- data/sig/rigor/effects/registry.rbs +68 -0
- data/sig/rigor/effects/summary.rbs +50 -0
- data/sig/rigor/effects/taint_cause.rbs +12 -0
- data/sig/rigor/environment.rbs +17 -10
- data/sig/rigor/inference/optimistic_origin.rbs +10 -0
- data/sig/rigor/inference.rbs +9 -14
- data/sig/rigor/plugin/additional_initializer.rbs +36 -0
- data/sig/rigor/plugin/base.rbs +30 -7
- data/sig/rigor/plugin/effect_ancestry.rbs +27 -0
- data/sig/rigor/plugin/effect_attribution.rbs +66 -0
- data/sig/rigor/plugin/effect_edge.rbs +33 -0
- data/sig/rigor/plugin/effect_entry_points.rbs +25 -0
- data/sig/rigor/plugin/io_boundary.rbs +4 -0
- data/sig/rigor/plugin/loader.rbs +3 -3
- data/sig/rigor/plugin/manifest.rbs +51 -11
- data/sig/rigor/plugin/protocol_contract.rbs +68 -0
- data/sig/rigor/plugin/registry.rbs +62 -1
- data/sig/rigor/plugin.rbs +1 -1
- data/sig/rigor/rbs_extended.rbs +1 -1
- data/sig/rigor/reflection.rbs +9 -6
- data/sig/rigor/scope.rbs +148 -12
- data/sig/rigor/sig_gen/skip_reason_catalog.rbs +21 -0
- data/sig/rigor/source.rbs +4 -4
- data/sig/rigor/testing.rbs +10 -4
- data/sig/rigor/type.rbs +33 -1
- data/sig/rigor.rbs +39 -20
- data/skills/rigor-ask/SKILL.md +16 -11
- data/skills/rigor-baseline-reduce/SKILL.md +4 -6
- data/skills/rigor-ci-setup/SKILL.md +17 -21
- data/skills/rigor-doctor/SKILL.md +24 -22
- data/skills/rigor-doctor/references/01-checks.md +97 -33
- data/skills/rigor-editor-setup/SKILL.md +6 -4
- data/skills/rigor-mcp-setup/SKILL.md +5 -4
- data/skills/rigor-monkeypatch-resolve/SKILL.md +5 -3
- data/skills/rigor-next-steps/SKILL.md +4 -2
- data/skills/rigor-plugin-author/SKILL.md +19 -23
- data/skills/rigor-plugin-author/references/01-plan-and-scaffold.md +9 -8
- data/skills/rigor-plugin-author/references/02-walker-and-types.md +25 -27
- data/skills/rigor-plugin-author/references/03-test-and-ship.md +6 -8
- data/skills/rigor-plugin-review/SKILL.md +6 -4
- data/skills/rigor-plugin-review/references/01-best-practices-checklist.md +2 -1
- data/skills/rigor-plugin-tune/SKILL.md +4 -2
- data/skills/rigor-project-init/SKILL.md +15 -10
- data/skills/rigor-project-init/references/01-detect.md +13 -9
- data/skills/rigor-project-init/references/02-configure.md +43 -14
- data/skills/rigor-project-init/references/03-baseline-and-bugs.md +14 -14
- data/skills/rigor-project-init/references/04-sig-uplift.md +27 -14
- data/skills/rigor-project-init/references/06-agent-contract.md +67 -0
- data/skills/rigor-protection-uplift/SKILL.md +4 -6
- data/skills/rigor-rbs-setup/SKILL.md +4 -2
- data/skills/rigor-type-oracle/SKILL.md +226 -0
- data/skills/rigor-type-oracle/references/01-oracle-commands.md +265 -0
- data/skills/rigor-type-oracle/references/02-agents-md-fragment.md +52 -0
- data/skills/rigor-type-oracle/references/03-gap-protocol.md +125 -0
- data/skills/rigor-unused-adjudicate/SKILL.md +12 -7
- data/skills/rigor-upgrade/SKILL.md +13 -8
- metadata +133 -3
- data/lib/rigor/cli/probe_environment.rb +0 -85
- data/sig/rigor/inference/builtins/numeric_catalog.rbs +0 -3
|
@@ -75,12 +75,12 @@ Use the sections like this:
|
|
|
75
75
|
| --- | --- | --- |
|
|
76
76
|
| `activesupport-core-ext` | ActiveSupport core-class monkey-patches not loaded. | Go back to Phase 3/4: add `rigor-activesupport-core-ext` to `plugins:` (it is an RBS-bundle plugin), re-run triage. This is a config gap, not a bug. |
|
|
77
77
|
| `gem-without-rbs` | A dependency ships no RBS. | If `rbs_collection.lock.yaml` was present and Phase 1 installed the collection, re-run `rigor triage` — the hint may shrink or disappear. Otherwise: Phase 8 escalation — `bundle exec rbs collection install`, or `dependencies.source_inference:`, or open a Rigor issue. |
|
|
78
|
-
| `project-monkey-patch-known` | **High confidence.** The engine proved the called method *is* defined by a project file (a reopened core/stdlib/gem class) but is not applied cross-file. The hint **names the defining file(s)**. | Phase
|
|
79
|
-
| `project-monkey-patch` | An in-project monkey-patch / refinement Rigor did not see, inferred from the *spread* of the same method across ≥3 files (no proven def site). | Phase
|
|
80
|
-
| `unresolved-toplevel` | Toplevel calls (outside any `def`/`class`/`module`) that resolve to nothing visible — usually a script relying on a monkey-patch or a `require`d helper Rigor did not walk (ADR-34). | Phase
|
|
78
|
+
| `project-monkey-patch-known` | **High confidence.** The engine proved the called method *is* defined by a project file (a reopened core/stdlib/gem class) but is not applied cross-file. The hint **names the defining file(s)**. | Phase 6a — copy the named file(s) straight into `pre_eval:`. No detective work needed; the diagnostic already found the source. |
|
|
79
|
+
| `project-monkey-patch` | An in-project monkey-patch / refinement Rigor did not see, inferred from the *spread* of the same method across ≥3 files (no proven def site). | Phase 6a — find the defining file (grep for `def <method>` / `class <Receiver>`), register it via `pre_eval:`, or (if it is a DSL) write a project plugin. |
|
|
80
|
+
| `unresolved-toplevel` | Toplevel calls (outside any `def`/`class`/`module`) that resolve to nothing visible — usually a script relying on a monkey-patch or a `require`d helper Rigor did not walk (ADR-34). | Phase 6a — if a project file defines these (toplevel `def`, or a patch on `Object`/`Kernel`), list it in `pre_eval:`. If nothing defines them, treat as genuine typos / missing requires (Phase 8). |
|
|
81
81
|
| `activerecord-relation-misinference` | An ActiveRecord relation inferred as `Array`. | Ensure `rigor-activerecord` is enabled (Phase 3). If it persists, it is an engine gap — open a Rigor issue. |
|
|
82
82
|
| `systemic-file-cluster` | One file × one rule, large count. | Acknowledge mode: a clean baseline bucket. Strict mode: a single fix may clear many — review that file first. |
|
|
83
|
-
| `genuine-bugs` | Low-count rules scattered across files. | **Phase
|
|
83
|
+
| `genuine-bugs` | Low-count rules scattered across files. | **Phase 8** — these are the localised bugs Rigor caught. Review first, in both modes. Note: the hint groups all low-count rules regardless of severity — filter for `error` severity when prioritising actionable items. |
|
|
84
84
|
|
|
85
85
|
If triage flags `activesupport-core-ext` (or any config gap),
|
|
86
86
|
**fix the config and re-run `rigor triage` before continuing**. The
|
|
@@ -170,8 +170,8 @@ bundle exec rbs collection install # if rbs is in Gemfile
|
|
|
170
170
|
# or: rbs collection install
|
|
171
171
|
```
|
|
172
172
|
|
|
173
|
-
Re-run `rigor triage`. If the `gem-without-rbs` count drops,
|
|
174
|
-
|
|
173
|
+
Re-run `rigor triage`. If the `gem-without-rbs` count drops, carry
|
|
174
|
+
the new, smaller count into Phase 7.
|
|
175
175
|
|
|
176
176
|
## Phase 7 — Generate the baseline (acknowledge mode only)
|
|
177
177
|
|
|
@@ -215,7 +215,8 @@ So ordinary coding cannot quietly grow the diagnostic count: the
|
|
|
215
215
|
baseline is a ceiling, not a blanket. Reducing it later is the
|
|
216
216
|
`rigor-baseline-reduce` skill's job.
|
|
217
217
|
|
|
218
|
-
|
|
218
|
+
Recommend committing `.rigor-baseline.yml` — it documents project
|
|
219
|
+
state; list it in the Final step's file inventory.
|
|
219
220
|
|
|
220
221
|
Print the suppression summary for the user: "N diagnostics recorded
|
|
221
222
|
as baseline; M will surface on subsequent runs."
|
|
@@ -288,18 +289,17 @@ sig issue.
|
|
|
288
289
|
|
|
289
290
|
#### `call.argument-type-mismatch` on regex capture variables (`$1`, `$~`)
|
|
290
291
|
|
|
291
|
-
Rigor
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
the form:
|
|
292
|
+
Rigor narrows `$1`, `$~`, and similar capture variables to non-nil
|
|
293
|
+
after a successful `=~` match and inside a `when /re/` branch. Where
|
|
294
|
+
the match is guaranteed by some other shape Rigor does not track, they
|
|
295
|
+
stay `String | nil`, and a diagnostic of the form:
|
|
295
296
|
|
|
296
297
|
```
|
|
297
298
|
expected String, got String | nil (on $1 / $~)
|
|
298
299
|
```
|
|
299
300
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
baseline.
|
|
301
|
+
is an **engine FP** (ADR-24 WD3 / known limitation). Note it as noise rather than
|
|
302
|
+
surfacing it as a bug; it belongs in the baseline.
|
|
303
303
|
|
|
304
304
|
### Escalation path A — application-specific metaprogramming
|
|
305
305
|
|
|
@@ -28,7 +28,8 @@ rigor sig-gen lib # adjust path to match the paths: key
|
|
|
28
28
|
Typical output at this point: most `new_method` candidates have
|
|
29
29
|
literal or concrete return types (`"hello"`, `42`, `:done`, `nil`).
|
|
30
30
|
Methods whose return type cannot be inferred show up with
|
|
31
|
-
`skip_reason:
|
|
31
|
+
`skip_reason: "sig.skipped.untyped-return"` — these are the sig
|
|
32
|
+
precision targets.
|
|
32
33
|
|
|
33
34
|
To get a breakdown in JSON:
|
|
34
35
|
|
|
@@ -50,6 +51,12 @@ rigor sig-gen --format json lib | ruby -e '
|
|
|
50
51
|
|
|
51
52
|
## Step 5-b — Write the baseline sigs
|
|
52
53
|
|
|
54
|
+
If the project's `Steepfile` reads inline annotations (`inline: true`
|
|
55
|
+
beside `signature "sig"`), first add `sig_gen:` / `inline_declared: skip`
|
|
56
|
+
to `.rigor.yml`. Otherwise sig-gen copies every `# @rbs` / `#:`
|
|
57
|
+
declaration into `sig/`, and Steep reports each copied method as
|
|
58
|
+
`DuplicatedMethodDefinition`.
|
|
59
|
+
|
|
53
60
|
```sh
|
|
54
61
|
rigor sig-gen --write lib
|
|
55
62
|
```
|
|
@@ -63,12 +70,18 @@ head -40 sig/lib/your_class.rbs
|
|
|
63
70
|
|
|
64
71
|
At this point, `attr_reader` and `attr_accessor` methods that rely on
|
|
65
72
|
ivar types set from `initialize` parameters will likely still be
|
|
66
|
-
absent (
|
|
73
|
+
absent (skipped as `sig.skipped.untyped-return`). Step 5-c fixes that.
|
|
74
|
+
An `attr_writer` or `attr_accessor` stays skipped even then unless its
|
|
75
|
+
ivar is assigned from an `initialize` parameter: the writer stores
|
|
76
|
+
whatever its caller passes, so the ivar reads untyped. That covers
|
|
77
|
+
`@count = 0` and `@logger = Logger.new` alike, and any other method
|
|
78
|
+
that returns the ivar.
|
|
67
79
|
|
|
68
80
|
## Step 5-c — Precision uplift with --params=observed
|
|
69
81
|
|
|
70
82
|
`--params=observed` tells sig-gen to collect observed argument types
|
|
71
|
-
from
|
|
83
|
+
from the call sites in the project's test roots — the `test_paths:`
|
|
84
|
+
Phase 4 wrote (`--observe=PATH` overrides them for one run). The most
|
|
72
85
|
important use case: **`attr_reader` / `attr_writer` / `attr_accessor`
|
|
73
86
|
methods whose `@ivar` is assigned from an `initialize` parameter**.
|
|
74
87
|
|
|
@@ -88,7 +101,8 @@ Person.new("Alice", 30)
|
|
|
88
101
|
Person.new("Bob", 25)
|
|
89
102
|
```
|
|
90
103
|
|
|
91
|
-
Without observations: `attr_reader :name` → skipped as
|
|
104
|
+
Without observations: `attr_reader :name` → skipped as
|
|
105
|
+
`sig.skipped.untyped-return`
|
|
92
106
|
(the ivar's type is unknown because the blank inference scope never
|
|
93
107
|
sees the parameter values).
|
|
94
108
|
|
|
@@ -129,9 +143,9 @@ there are a few options depending on the cause:
|
|
|
129
143
|
| Pattern | Cause | Fix |
|
|
130
144
|
|---|---|---|
|
|
131
145
|
| `attr_reader :x` with `@x` never set in `initialize` | ivar set from a DB query, config read, or side effect | Add a hand-written sig: create (or edit) `sig/your_class.rbs` with `attr_reader x: String` |
|
|
132
|
-
| Deep method chains on untyped receivers | Cascade from a gem with no RBS | `rbs collection install`; Phase
|
|
146
|
+
| Deep method chains on untyped receivers | Cascade from a gem with no RBS | `rbs collection install`; Phase 8 escalation path B |
|
|
133
147
|
| Recursive or mutually recursive methods | Return type not inferrable without a base case | Add a `# @rbs return: YourType` inline annotation, or a hand-written sig |
|
|
134
|
-
| Dynamic methods (`define_method`, DSL) | Metaprogramming Rigor cannot follow | Phase
|
|
148
|
+
| Dynamic methods (`define_method`, DSL) | Metaprogramming Rigor cannot follow | Phase 8 escalation path A (project plugin) |
|
|
135
149
|
|
|
136
150
|
Do not spend long on residual `untyped` methods at this stage — a
|
|
137
151
|
handful of `untyped` returns in `sig/` does not block adoption. The
|
|
@@ -140,12 +154,10 @@ reach perfect sig coverage.
|
|
|
140
154
|
|
|
141
155
|
## Step 5-e — Commit the sig/ directory
|
|
142
156
|
|
|
143
|
-
Once you are satisfied with the initial sig quality
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
git commit -m "Add initial RBS sigs from rigor sig-gen (--params=observed)"
|
|
148
|
-
```
|
|
157
|
+
Once you are satisfied with the initial sig quality, recommend
|
|
158
|
+
committing `sig/`: list it in the Final step's file inventory
|
|
159
|
+
(`SKILL.md` § "Final step") rather than committing it here — the user
|
|
160
|
+
confirms every commit.
|
|
149
161
|
|
|
150
162
|
A committed `sig/` is a first-class project artefact: it improves
|
|
151
163
|
inference quality on every subsequent run and is maintained alongside
|
|
@@ -164,8 +176,9 @@ the source (add new sig files when adding classes; update sigs with
|
|
|
164
176
|
|
|
165
177
|
## Output of this module
|
|
166
178
|
|
|
167
|
-
A
|
|
168
|
-
inferrable methods. Remaining
|
|
179
|
+
A `sig/` directory, ready to commit, with RBS skeletons for all
|
|
180
|
+
statically inferrable methods. Remaining `sig.skipped.untyped-return`
|
|
181
|
+
methods are noted for
|
|
169
182
|
potential manual annotation; they do not block Phase 6.
|
|
170
183
|
|
|
171
184
|
Proceed to Phase 6 ([`03-baseline-and-bugs.md`](03-baseline-and-bugs.md)).
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# 06 — Install the agent type-contract into AGENTS.md / CLAUDE.md
|
|
2
|
+
|
|
3
|
+
Covers **Phase 8a**. Input: an onboarded project (config written, sigs
|
|
4
|
+
generated, baseline decided). Output: one section in the file the
|
|
5
|
+
project's coding agents read at startup.
|
|
6
|
+
|
|
7
|
+
## Why this is part of onboarding
|
|
8
|
+
|
|
9
|
+
Everything the earlier phases produced — `sig/`, the baseline, the
|
|
10
|
+
severity profile — is a record of what Rigor *proved*. The moment an AI
|
|
11
|
+
agent starts contributing to the project, it can write types that Rigor
|
|
12
|
+
never proved: a `@param currency [String]` in a doc comment, an
|
|
13
|
+
rbs-inline `#:` that Rigor then ingests as a live contract. Those enter
|
|
14
|
+
the same files, look identical to derived types, and are believed.
|
|
15
|
+
|
|
16
|
+
The fix is not a tool. It is one paragraph in the project's agent
|
|
17
|
+
contract, so the rule is in context every session rather than only when
|
|
18
|
+
a skill happens to trigger: **a type not obtained from Rigor is a guess,
|
|
19
|
+
and a guessed type is never written.**
|
|
20
|
+
|
|
21
|
+
## The text
|
|
22
|
+
|
|
23
|
+
The canonical fragment is served by the installed Rigor, so it stays
|
|
24
|
+
current with the CLI it names:
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
rigor skill --full rigor-type-oracle
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Its `references/02-agents-md-fragment.md` section carries the paragraph
|
|
31
|
+
and the five bullets. Copy that block **verbatim** — including its
|
|
32
|
+
single-long-line shape, which is deliberate (some renderers turn a
|
|
33
|
+
newline inside a paragraph into a line break).
|
|
34
|
+
|
|
35
|
+
Do not paraphrase it from memory, and do not shorten it: the five bullets
|
|
36
|
+
are the load-bearing part — expression, method signature, parameter,
|
|
37
|
+
the gap rule, and provenance.
|
|
38
|
+
|
|
39
|
+
## Where it goes
|
|
40
|
+
|
|
41
|
+
| Project state | What to do |
|
|
42
|
+
| --- | --- |
|
|
43
|
+
| `AGENTS.md` exists | **Append** the section at the end. Do not reorganise the file. |
|
|
44
|
+
| Only `CLAUDE.md` exists | Append it there. |
|
|
45
|
+
| Both exist | Put it in `AGENTS.md`. Add `@AGENTS.md` to `CLAUDE.md` only if it is not already pulled in. |
|
|
46
|
+
| Neither exists | **Create `AGENTS.md`** with this as its first section. |
|
|
47
|
+
| A types / type-checking section already exists | Merge into it; keep the five bullets intact. Never write a second, competing rule. |
|
|
48
|
+
|
|
49
|
+
Never overwrite unrelated content. If the project already states a rule
|
|
50
|
+
about type authorship that contradicts this one, stop and show the user
|
|
51
|
+
the conflict — the project's own rule wins until they say otherwise.
|
|
52
|
+
|
|
53
|
+
## Report it in the final step
|
|
54
|
+
|
|
55
|
+
This is a change to the file that governs every future agent session in
|
|
56
|
+
the repo, so it belongs in Phase 9's file inventory, not in a silent
|
|
57
|
+
diff. Recommend committing it: the point is that every contributor's
|
|
58
|
+
agent reads the same rule.
|
|
59
|
+
|
|
60
|
+
## When to skip
|
|
61
|
+
|
|
62
|
+
- The project has no coding-agent contract file **and** the user has said
|
|
63
|
+
they do not use AI agents on it. Offer once, accept "no".
|
|
64
|
+
- The user declined it earlier in this session.
|
|
65
|
+
|
|
66
|
+
Otherwise install it — an unonboarded agent is the one contributor that
|
|
67
|
+
cannot be trained by review.
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rigor-protection-uplift
|
|
3
|
-
description:
|
|
4
|
-
Close the
|
|
3
|
+
description: >-
|
|
4
|
+
Close the protection gaps reported by `rigor coverage --protection`, using generated signatures before
|
|
5
|
+
minimal residual annotations and a no-new-diagnostics gate. Use when increasing bug-catching coverage
|
|
6
|
+
in an adopting project; not for Rigor's own tree, bundled plugins, or first-time setup.
|
|
5
7
|
license: MPL-2.0
|
|
6
8
|
metadata:
|
|
7
9
|
version: 0.1.0
|
|
@@ -40,10 +42,6 @@ copy — just proceed. If `rigor` is not on `PATH`, this task needs it: run
|
|
|
40
42
|
|
|
41
43
|
## When NOT to use
|
|
42
44
|
|
|
43
|
-
- **Rigor's own `lib/`, or the bundled `plugins/` / `examples/`** — the
|
|
44
|
-
self-check tree. Hand-authoring types there collides with the
|
|
45
|
-
sig-gen-first ethos; run `rigor sig-gen` directly and treat residual
|
|
46
|
-
gaps as engine signal to report, not a private fix.
|
|
47
45
|
- **"Make my code more precise" with no protection goal** — that is
|
|
48
46
|
`rigor coverage` (precision), not `--protection`.
|
|
49
47
|
- **A project with no Rigor config yet** — onboard first with
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rigor-rbs-setup
|
|
3
|
-
description:
|
|
4
|
-
Install community RBS for
|
|
3
|
+
description: >-
|
|
4
|
+
Install community RBS for a project's gems so Rigor can type dependencies that currently become
|
|
5
|
+
`Dynamic`. Use when `rbs collection` is missing or untyped gems limit coverage; not for first-time
|
|
6
|
+
Rigor setup or a gem with no community RBS entry.
|
|
5
7
|
license: MPL-2.0
|
|
6
8
|
metadata:
|
|
7
9
|
version: 0.1.0
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rigor-type-oracle
|
|
3
|
+
description: >-
|
|
4
|
+
Obtain a Ruby type from Rigor before writing or asserting it, using `type-of`, `annotate`, or `sig-gen`
|
|
5
|
+
as appropriate. Use when adding RBS, inline annotations, Sorbet/YARD types, type-shaped docs, or
|
|
6
|
+
type-justified guards; not for Rigor setup or baseline reduction.
|
|
7
|
+
license: MPL-2.0
|
|
8
|
+
metadata:
|
|
9
|
+
version: 0.1.0
|
|
10
|
+
homepage: https://github.com/rigortype/rigor
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Rigor Type Oracle
|
|
14
|
+
|
|
15
|
+
You are about to write a type. Stop and ask Rigor first.
|
|
16
|
+
|
|
17
|
+
This project has a deterministic type oracle installed. Reading the
|
|
18
|
+
source and concluding "`currency` is a String, `pattern` is a Regexp" is
|
|
19
|
+
*plausible-guess* behaviour: it is right often enough to feel safe and
|
|
20
|
+
wrong often enough to poison a signature file, a doc comment, or a
|
|
21
|
+
reviewer's mental model. Rigor already knows the answer — for every
|
|
22
|
+
expression, at every line, from the same engine that will check the code
|
|
23
|
+
tomorrow. Asking it costs one command.
|
|
24
|
+
|
|
25
|
+
**The rule: a type you did not obtain from Rigor is a guess, and a
|
|
26
|
+
guessed type is never written anywhere.** Not in `sig/`, not in an inline
|
|
27
|
+
annotation (`#:`, `# @rbs`), not in a Sorbet `sig`, not in a YARD tag,
|
|
28
|
+
not in a doc sentence, not in a review comment, and not as the stated
|
|
29
|
+
reason for a nil check or an `is_a?` guard.
|
|
30
|
+
|
|
31
|
+
## First: load the version-current copy
|
|
32
|
+
|
|
33
|
+
This skill's exact commands, flags, output spellings, and skip-reason ids
|
|
34
|
+
drift between Rigor releases, so follow the copy that ships with the
|
|
35
|
+
**installed** Rigor rather than any vendored or frozen copy of this file.
|
|
36
|
+
Get the complete current procedure in one call:
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
rigor skill --full rigor-type-oracle # this body + all its references/, inline
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
If you already loaded this skill *via* `rigor skill` you have the current
|
|
43
|
+
copy — just proceed (read any `references/NN-*.md` from the directory the
|
|
44
|
+
header names). If `rigor` is not on `PATH`, this task needs it: run
|
|
45
|
+
**`rigor-next-steps`** to install Rigor first, then come back.
|
|
46
|
+
|
|
47
|
+
## When to use
|
|
48
|
+
|
|
49
|
+
Trigger on the *act*, not on the user saying the word "type". You are in
|
|
50
|
+
scope the moment you are about to write or assert one:
|
|
51
|
+
|
|
52
|
+
- Writing or editing RBS under `sig/`.
|
|
53
|
+
- Writing an inline annotation — rbs-inline `#:`, `# @rbs`, a
|
|
54
|
+
`%a{rigor:v1:…}` override.
|
|
55
|
+
- Writing a Sorbet `sig do … end`, or any other type DSL.
|
|
56
|
+
- Writing a YARD / RDoc `@param` / `@return` / `@raise`, or any doc
|
|
57
|
+
sentence that names a type ("returns an Array of entries").
|
|
58
|
+
- Stating a type in a review comment, a PR description, or a chat answer.
|
|
59
|
+
- Justifying a nil check, an `is_a?` / `respond_to?` guard, or a
|
|
60
|
+
defensive `to_s` with "this should be an X".
|
|
61
|
+
- Being asked "what type is this?", "what does this method return?",
|
|
62
|
+
"add types to this class", "document this file".
|
|
63
|
+
|
|
64
|
+
## When NOT to use
|
|
65
|
+
|
|
66
|
+
- **Setting Rigor up on a project that has none** → `rigor-next-steps`
|
|
67
|
+
(which routes to `rigor-project-init`). You cannot ask an oracle that
|
|
68
|
+
is not installed.
|
|
69
|
+
- **Working an existing `.rigor-baseline.yml` down** →
|
|
70
|
+
`rigor-baseline-reduce`. That is fixing diagnostics, not sourcing a
|
|
71
|
+
type.
|
|
72
|
+
- **Raising type protection from a `coverage --protection` list** →
|
|
73
|
+
`rigor-protection-uplift`. It owns the "where should a type go, and how
|
|
74
|
+
do I verify it" loop; this skill owns "where does the type itself come
|
|
75
|
+
from".
|
|
76
|
+
|
|
77
|
+
## The three allowed sources
|
|
78
|
+
|
|
79
|
+
Every type you write comes from exactly one of these. There is no fourth.
|
|
80
|
+
|
|
81
|
+
| What you need | Ask Rigor with | What you write |
|
|
82
|
+
| --- | --- | --- |
|
|
83
|
+
| The type of an **expression** at a point | `rigor type-of FILE:LINE:COL` — or `rigor annotate FILE` for every line at once | the `type:` it prints, verbatim |
|
|
84
|
+
| The **signature of a method** | `rigor sig-gen --print FILE` | the RBS it prints, verbatim — never what you expected it to print |
|
|
85
|
+
| A **parameter's intended type** | `rigor sig-gen --observe PATH --params=observed` (call-site derivation) | the observed type, *reviewed and widened*, kept only while `rigor check` stays green |
|
|
86
|
+
|
|
87
|
+
The parameter row is the one genuine gap. Inference reads a method
|
|
88
|
+
*body*, and a body does not state what its callers are allowed to pass —
|
|
89
|
+
so Rigor spells parameters `untyped` by design ([ADR-5](https://github.com/rigortype/rigor/blob/master/docs/adr/5-robustness-principle.md):
|
|
90
|
+
strict on returns, lenient on parameters). `--params=observed` derives
|
|
91
|
+
them from the call sites instead, which is evidence rather than
|
|
92
|
+
invention — but it is *narrow* evidence (it can emit literal types such
|
|
93
|
+
as `("JPY")`), so it is the one place you review and widen before
|
|
94
|
+
adopting, under the gate that `rigor check` gains no new diagnostic.
|
|
95
|
+
|
|
96
|
+
Exact command forms, flags, position syntax, JSON shapes, and how to read
|
|
97
|
+
each output: [`references/01-oracle-commands.md`](references/01-oracle-commands.md).
|
|
98
|
+
|
|
99
|
+
## The gap protocol — a gap is a finding, not a blank to fill
|
|
100
|
+
|
|
101
|
+
`Dynamic[top]`, `untyped`, and a `sig.skipped.*` classification are
|
|
102
|
+
**answers**. They mean "Rigor cannot prove a type here", which is
|
|
103
|
+
information about the project or about the engine. Filling that hole with
|
|
104
|
+
your own reading converts a known unknown into a confident falsehood, and
|
|
105
|
+
it does so in a file the next reader will trust.
|
|
106
|
+
|
|
107
|
+
So when the oracle comes back empty:
|
|
108
|
+
|
|
109
|
+
1. **Report it.** Give the exact command and its exact output.
|
|
110
|
+
2. **Find out why**, when it matters: `rigor trace --format=json --line=N FILE`
|
|
111
|
+
replays how the type was built; `rigor explain <rule>` documents a
|
|
112
|
+
diagnostic that fired nearby.
|
|
113
|
+
3. **Route it.** A project-side gap has a sibling skill that closes it
|
|
114
|
+
(missing gem RBS → `rigor-rbs-setup`; an unconfigured framework →
|
|
115
|
+
`rigor-plugin-tune`; the project's own monkey-patches →
|
|
116
|
+
`rigor-monkeypatch-resolve`; a project DSL → `rigor-plugin-author`).
|
|
117
|
+
An engine-side gap is a Rigor issue.
|
|
118
|
+
|
|
119
|
+
Which output means which gap, the full routing table, and how to word the
|
|
120
|
+
issue: [`references/03-gap-protocol.md`](references/03-gap-protocol.md).
|
|
121
|
+
|
|
122
|
+
## Provenance — every type you state carries its command
|
|
123
|
+
|
|
124
|
+
When you tell a human a type, tell them how to re-derive it. One line is
|
|
125
|
+
enough:
|
|
126
|
+
|
|
127
|
+
> `entries_matching` returns `Array[untyped] | []`
|
|
128
|
+
> (`rigor sig-gen --print lib/demo/budget_ledger.rb`).
|
|
129
|
+
|
|
130
|
+
This is not ceremony. It is the difference between an assertion the
|
|
131
|
+
reader must trust and a claim they can re-run in three seconds — and it
|
|
132
|
+
is what makes a wrong answer *findable* instead of permanent.
|
|
133
|
+
|
|
134
|
+
## With the MCP server connected, use the tools
|
|
135
|
+
|
|
136
|
+
If the Rigor MCP server is wired up (`rigor-mcp-setup`), `rigor_type_of`,
|
|
137
|
+
`rigor_annotate`, `rigor_sig_gen`, `rigor_check`, and `rigor_explain` are
|
|
138
|
+
the same oracle as tool calls — prefer them over shelling out, and treat
|
|
139
|
+
their results exactly as this skill treats CLI output. Argument shapes:
|
|
140
|
+
[`references/01-oracle-commands.md`](references/01-oracle-commands.md)
|
|
141
|
+
§ "The MCP tools".
|
|
142
|
+
|
|
143
|
+
## Worked example
|
|
144
|
+
|
|
145
|
+
Asked to document `Demo::BudgetLedger`, the guessing path writes
|
|
146
|
+
`@param currency [String]`, `@return [Numeric]`, `@param pattern
|
|
147
|
+
[Regexp]`. Here is the oracle path.
|
|
148
|
+
|
|
149
|
+
```sh
|
|
150
|
+
rigor annotate lib/demo/budget_ledger.rb
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
```ruby
|
|
154
|
+
def initialize(currency, opening_balance: 0) #=> Dynamic[top]
|
|
155
|
+
@currency = currency #=> Dynamic[top]
|
|
156
|
+
@entries = [] #=> []
|
|
157
|
+
def balance(as_of: nil) #=> Dynamic[top]
|
|
158
|
+
def entries_matching(pattern) #=> Array[Dynamic[top]] | []
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
```sh
|
|
162
|
+
rigor sig-gen --print lib/demo/budget_ledger.rb
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
rigor sig-gen: skipped 2 method(s) it could not type or would not overwrite
|
|
167
|
+
(sig.skipped.untyped-return: 2). Run with --format=json to see each one with
|
|
168
|
+
its skip_reason.
|
|
169
|
+
class Demo::BudgetLedger
|
|
170
|
+
def initialize: (untyped, ?opening_balance: untyped) -> void
|
|
171
|
+
def record: (untyped, ?memo: untyped, ?at: untyped) -> Demo::BudgetLedger
|
|
172
|
+
def entries_matching: (untyped) -> (Array[untyped] | [])
|
|
173
|
+
end
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
What you now know, and may write: `record` returns
|
|
177
|
+
`Demo::BudgetLedger`; `entries_matching` returns `Array[untyped] | []`.
|
|
178
|
+
What you must **report rather than write**: `balance` and `overdrawn?`
|
|
179
|
+
were skipped as `sig.skipped.untyped-return` — `@opening_balance` is
|
|
180
|
+
`Dynamic[top]`, so the arithmetic proves nothing. `currency` is not
|
|
181
|
+
`String` on any evidence Rigor has; it is `untyped`, and the YARD tag is
|
|
182
|
+
`@param currency — the ledger's currency` with no type at all.
|
|
183
|
+
|
|
184
|
+
Call-site derivation closes the parameter half where specs exist:
|
|
185
|
+
|
|
186
|
+
```sh
|
|
187
|
+
rigor sig-gen --print --params=observed --observe spec lib/demo/budget_ledger.rb
|
|
188
|
+
# def initialize: ("JPY", ?opening_balance: 100) -> void
|
|
189
|
+
# def entries_matching: (Regexp) -> (Array[untyped] | [])
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
`entries_matching: (Regexp)` is now *derived*, and adoptable. The
|
|
193
|
+
`("JPY")` / `100` literals are the narrowness warned about above — widen
|
|
194
|
+
them to `String` / `Integer` before adopting, and keep the change only
|
|
195
|
+
while `rigor check` stays green.
|
|
196
|
+
|
|
197
|
+
## When the user insists on a hand-written type anyway
|
|
198
|
+
|
|
199
|
+
They may. It is their code, and a human can know an intended contract
|
|
200
|
+
that no static reading can prove. Do not argue past one exchange:
|
|
201
|
+
|
|
202
|
+
1. Say once what Rigor actually reports for that site, with the command.
|
|
203
|
+
2. Write what they asked for.
|
|
204
|
+
3. Run `rigor check` on the touched paths and report the result.
|
|
205
|
+
4. **Say which lines the check covers.** A green `rigor check` proves
|
|
206
|
+
that the annotation contradicts nothing Rigor can currently see — it
|
|
207
|
+
does not prove the contract. Where the surrounding types are
|
|
208
|
+
`untyped`, there is nothing to contradict, and you must say so rather
|
|
209
|
+
than let a green run read as confirmation.
|
|
210
|
+
|
|
211
|
+
If the check *does* go red, the annotation modeled the wrong contract:
|
|
212
|
+
report it and revert, never suppress the diagnostic.
|
|
213
|
+
|
|
214
|
+
The same holds for an inline annotation a human wrote as documentation —
|
|
215
|
+
`#: void`, `#: :asc | :desc`, a parameter contract. It is their intent,
|
|
216
|
+
checked by `rigor check`, not a guess for you to "correct" to what inference
|
|
217
|
+
shows. Leave it; if the check finds a contradiction, report that.
|
|
218
|
+
|
|
219
|
+
## Installing the rule in the project
|
|
220
|
+
|
|
221
|
+
An agent that never loads this skill still guesses. The durable fix is
|
|
222
|
+
one paragraph in the project's `AGENTS.md` / `CLAUDE.md`, so the rule is
|
|
223
|
+
in context every session rather than only when a skill happens to
|
|
224
|
+
trigger. The text to paste:
|
|
225
|
+
[`references/02-agents-md-fragment.md`](references/02-agents-md-fragment.md).
|
|
226
|
+
`rigor-project-init` installs it during onboarding.
|