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
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
# 01 — The oracle commands, exactly
|
|
2
|
+
|
|
3
|
+
Every command form here was taken from `rigor <cmd> --help` on the
|
|
4
|
+
version this file ships with. If a flag below is missing from your
|
|
5
|
+
`--help`, trust `--help`.
|
|
6
|
+
|
|
7
|
+
All five commands are **read-only**: they analyse and print. None of them
|
|
8
|
+
writes to your source tree. (`rigor sig-gen --write` does, and is the one
|
|
9
|
+
form this skill never reaches for on its own — see § "Writing, not just
|
|
10
|
+
reading".)
|
|
11
|
+
|
|
12
|
+
## `rigor type-of` — the type of one expression
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
rigor type-of FILE:LINE[:COL] [FILE:LINE[:COL] ...]
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
| Option | Effect |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| `--format=text\|json` | `text` (default) or a JSON object per position. |
|
|
21
|
+
| `--trace` | Also record fail-soft fallbacks via the tracer. |
|
|
22
|
+
| `--config=PATH` | Explicit `.rigor.yml`. |
|
|
23
|
+
| `--tmp-file=PATH` / `--instead-of=PATH` | Editor mode: analyse an unsaved buffer as if it were the project path. Paired. |
|
|
24
|
+
|
|
25
|
+
**Position syntax.** `FILE:LINE:COL`, both **1-based**. The column may be
|
|
26
|
+
omitted (`FILE:LINE`). Several positions in one invocation — that is the
|
|
27
|
+
cheap way to ask about a whole method.
|
|
28
|
+
|
|
29
|
+
Text output:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
lib/demo/budget_ledger.rb:19:7
|
|
33
|
+
node: Prism::LocalVariableWriteNode
|
|
34
|
+
type: Array[Dynamic[top]]
|
|
35
|
+
erased: Array[untyped]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
- `node` — the Prism node the position resolved to. Check it: if it is
|
|
39
|
+
not the expression you meant, your column is off, and the `type` below
|
|
40
|
+
it answers a different question.
|
|
41
|
+
- `type` — Rigor's internal type. **This is the answer.**
|
|
42
|
+
- `erased` — the same type spelled as RBS. **This is what you write into
|
|
43
|
+
a `.rbs` file or an annotation.** `Dynamic[top]` erases to `untyped`.
|
|
44
|
+
|
|
45
|
+
JSON output is the same five fields:
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
{ "file": "…", "line": 19, "column": 7,
|
|
49
|
+
"node": "Prism::LocalVariableWriteNode",
|
|
50
|
+
"type": "Array[Dynamic[top]]", "erased": "Array[untyped]" }
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## `rigor annotate` — every line of a file at once
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
rigor annotate FILE
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
| Option | Effect |
|
|
60
|
+
| --- | --- |
|
|
61
|
+
| `--format=text\|json` | `text` (default), or JSON as a `{ line => type }` map. |
|
|
62
|
+
| `--[no-]color` | Force / disable ANSI colour (auto-detects a tty; honours `NO_COLOR`). |
|
|
63
|
+
| `--[no-]bat` | Force / disable highlighting through `bat`. |
|
|
64
|
+
| `--config=PATH` | Explicit `.rigor.yml`. |
|
|
65
|
+
|
|
66
|
+
Output is the source with each line's **last-expression type** appended
|
|
67
|
+
after `#=>`:
|
|
68
|
+
|
|
69
|
+
```ruby
|
|
70
|
+
def initialize(currency, opening_balance: 0) #=> Dynamic[top]
|
|
71
|
+
@currency = currency #=> Dynamic[top]
|
|
72
|
+
@entries = [] #=> []
|
|
73
|
+
end #=> :initialize
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Two reading rules that catch people out:
|
|
77
|
+
|
|
78
|
+
- `#=>` is the type of the line's **last expression**, not of the
|
|
79
|
+
variable being assigned and not of the method being defined. A `def`
|
|
80
|
+
line's `#=>` is the *return* type of the method; the `end` line's
|
|
81
|
+
`#=>` is the symbol the `def` expression itself evaluates to
|
|
82
|
+
(`:initialize`) — that is Ruby, not a Rigor quirk. Ignore it.
|
|
83
|
+
- One `#=>` per line. For a multi-expression line, or for a
|
|
84
|
+
sub-expression in the middle, go back to `type-of` with a column.
|
|
85
|
+
|
|
86
|
+
Reach for `annotate` first when the task is "document this file" or "add
|
|
87
|
+
types to this class": one call types everything, and the lines that come
|
|
88
|
+
back `Dynamic[top]` are your gap list before you have written a word.
|
|
89
|
+
|
|
90
|
+
## `rigor sig-gen` — the signature of a method
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
rigor sig-gen [paths]
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
| Option | Effect |
|
|
97
|
+
| --- | --- |
|
|
98
|
+
| `--print` | RBS to stdout. **Default** — you may omit it. |
|
|
99
|
+
| `--diff` | Unified diff against the existing RBS. Read-only. |
|
|
100
|
+
| `--write` | Write to `sig/<path>.rbs`. The only mode that touches the filesystem. |
|
|
101
|
+
| `--overwrite` | Allow a tighter return to replace user-authored RBS. |
|
|
102
|
+
| `--include-private` | Emit private / protected instance methods too (default: public only). |
|
|
103
|
+
| `--params=untyped\|observed\|observed-strict` | Parameter policy. Default `untyped`. `observed-strict` is reserved and currently a usage error. |
|
|
104
|
+
| `--observe=PATH` | Directory / file to scan for call-site observations. Repeatable. Defaults to the configured `test_paths:` (unset: whichever of `spec/` and `test/` exist). |
|
|
105
|
+
| `--new-files` / `--new-methods` / `--tighter-returns` | Emit only that classification. |
|
|
106
|
+
| `--format=text\|json` | Text RBS, or the structured candidate report. |
|
|
107
|
+
| `--config=PATH` | Explicit `.rigor.yml`. |
|
|
108
|
+
|
|
109
|
+
Text output is RBS you paste as-is:
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
class Demo::BudgetLedger
|
|
113
|
+
# [new]
|
|
114
|
+
def record: (untyped, ?memo: untyped, ?at: untyped) -> Demo::BudgetLedger
|
|
115
|
+
# [new]
|
|
116
|
+
def entries_matching: (untyped) -> (Array[untyped] | [])
|
|
117
|
+
end
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Read stderr.** A skip summary goes there, not to stdout:
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
rigor sig-gen: skipped 2 method(s) it could not type or would not overwrite
|
|
124
|
+
(sig.skipped.untyped-return: 2). Run with --format=json to see each one with
|
|
125
|
+
its skip_reason.
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
A method that is missing from the printed RBS was **skipped**, and a
|
|
129
|
+
skip is a finding. `--format=json` names each one:
|
|
130
|
+
|
|
131
|
+
```json
|
|
132
|
+
{ "class": "Demo::BudgetLedger", "method": "balance", "kind": "instance",
|
|
133
|
+
"classification": "skipped", "skip_reason": "sig.skipped.untyped-return" }
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Classifications (the JSON `classification` values): `new_file`,
|
|
137
|
+
`new_method`, `tighter_return`, `equivalent` (nothing to tighten;
|
|
138
|
+
silently dropped), `skipped`. Skip reasons and what
|
|
139
|
+
each one means for you: [`03-gap-protocol.md`](03-gap-protocol.md).
|
|
140
|
+
|
|
141
|
+
### Deriving a parameter type from call sites
|
|
142
|
+
|
|
143
|
+
```sh
|
|
144
|
+
rigor sig-gen --print --params=observed --observe spec lib/demo/budget_ledger.rb
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`observed` collects argument types from every call site under the
|
|
148
|
+
`--observe` paths, unions them per parameter position, and emits the
|
|
149
|
+
union. The recogniser understands RSpec shapes — `RSpec.describe Foo`,
|
|
150
|
+
bare `describe Foo`, `subject { … }` / `subject(:name) { … }`,
|
|
151
|
+
`let(:name)` / `let!(:name)`, and `described_class.new(...)` — so a
|
|
152
|
+
normal spec suite is already an observation corpus. No plugin needed.
|
|
153
|
+
|
|
154
|
+
The result is *evidence*, and it is narrow evidence:
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
def initialize: ("JPY", ?opening_balance: 100) -> void
|
|
158
|
+
def entries_matching: (Regexp) -> (Array[untyped] | [])
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
`(Regexp)` is a real derivation and adoptable. `("JPY")` and `100` are
|
|
162
|
+
literal types — the union of what today's callers happen to pass, frozen
|
|
163
|
+
as a contract. Widen those to the class before adopting
|
|
164
|
+
(`String`, `Integer`), per [ADR-5](https://github.com/rigortype/rigor/blob/master/docs/adr/5-robustness-principle.md):
|
|
165
|
+
lenient on parameters. The gate on any widening is that `rigor check`
|
|
166
|
+
gains no new diagnostic.
|
|
167
|
+
|
|
168
|
+
### Writing, not just reading
|
|
169
|
+
|
|
170
|
+
This skill's job ends at *knowing* the type. `--write` is an edit to the
|
|
171
|
+
project and belongs to whoever asked for it — propose `--diff` first, and
|
|
172
|
+
run `rigor check` after. `--write` only ever writes inside the configured
|
|
173
|
+
signature paths (`sig/` by default).
|
|
174
|
+
|
|
175
|
+
## `rigor trace` — why the type is what it is
|
|
176
|
+
|
|
177
|
+
```sh
|
|
178
|
+
rigor trace FILE
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
| Option | Effect |
|
|
182
|
+
| --- | --- |
|
|
183
|
+
| `--format=text\|json` | `text` is an interactive animation; **use `json`** for the raw event stream. |
|
|
184
|
+
| `--line=N` | Only replay events whose source range starts on line `N`. |
|
|
185
|
+
| `--verbose` | Include every expression enter/result frame. |
|
|
186
|
+
| `--delay=SECONDS` | Autoplay the text animation (default: step on key press). |
|
|
187
|
+
| `--config=PATH` | Explicit `.rigor.yml`. |
|
|
188
|
+
|
|
189
|
+
An agent wants `--format=json --line=N`: the text mode waits on
|
|
190
|
+
keystrokes. Each event carries `kind`, `depth`, a `location`, the node
|
|
191
|
+
`stack`, and a `data` payload — a `bind` event, for example, names the
|
|
192
|
+
local and the type it received:
|
|
193
|
+
|
|
194
|
+
```json
|
|
195
|
+
{ "kind": "bind", "depth": 2,
|
|
196
|
+
"location": { "start_line": 20, "start_column": 25, "…": "…" },
|
|
197
|
+
"stack": ["CallNode", "CallNode"],
|
|
198
|
+
"data": { "name": "amount", "type": "Dynamic[top]" } }
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Reach for it when `type-of` gave you `Dynamic[top]` and you need to name
|
|
202
|
+
*where* the precision was lost before reporting the gap.
|
|
203
|
+
|
|
204
|
+
## `rigor explain` — what a diagnostic rule means
|
|
205
|
+
|
|
206
|
+
```sh
|
|
207
|
+
rigor explain [<rule>]
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
| Option | Effect |
|
|
211
|
+
| --- | --- |
|
|
212
|
+
| `--format=text\|json` | Default `text`. |
|
|
213
|
+
|
|
214
|
+
With no argument it lists every rule. With a rule id, a legacy alias, or
|
|
215
|
+
a family prefix (`call`, `flow`, `assert`, `dump`, `def`) it prints the
|
|
216
|
+
rule's firing conditions, the severity per profile, the evidence tier,
|
|
217
|
+
and how to suppress it.
|
|
218
|
+
|
|
219
|
+
**`explain` has two catalogues.** A `sig.skipped.*` id is a sig-gen
|
|
220
|
+
*skip reason*, not a diagnostic rule, but `rigor explain
|
|
221
|
+
sig.skipped.untyped-return` answers it from a second catalogue (no
|
|
222
|
+
severity, no profile, nothing to suppress). The table in
|
|
223
|
+
[`03-gap-protocol.md`](03-gap-protocol.md) is the summary.
|
|
224
|
+
|
|
225
|
+
## `rigor check` — the gate, not the oracle
|
|
226
|
+
|
|
227
|
+
```sh
|
|
228
|
+
rigor check [paths]
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
You need one flag family here: `--format=text|json|sarif|github|gitlab|checkstyle|junit|teamcity`,
|
|
232
|
+
plus `--explain` to surface fail-soft fallback events as `:info`
|
|
233
|
+
diagnostics. Everything else (`--baseline*`, `--workers`, `--incremental`,
|
|
234
|
+
the cache flags) belongs to other skills.
|
|
235
|
+
|
|
236
|
+
`check` never *sources* a type. Its role here is the verification half:
|
|
237
|
+
after any annotation lands, `rigor check PATHS` must gain **no new
|
|
238
|
+
diagnostic** versus before. Green is a non-contradiction proof, not a
|
|
239
|
+
correctness proof — say which lines it actually covers.
|
|
240
|
+
|
|
241
|
+
## The MCP tools
|
|
242
|
+
|
|
243
|
+
With the Rigor MCP server wired up (`rigor-mcp-setup`), the same oracle
|
|
244
|
+
is available as tool calls. Prefer them over shelling out; the results
|
|
245
|
+
are the CLI's, so read them exactly as above.
|
|
246
|
+
|
|
247
|
+
| Tool | Required arguments | Optional | Returns |
|
|
248
|
+
| --- | --- | --- | --- |
|
|
249
|
+
| `rigor_type_of` | `file` (string), `line` (integer, 1-based), `col` (integer, 1-based) | `config` | The inferred type at that location. |
|
|
250
|
+
| `rigor_annotate` | `file` (string) | `config` | The source with each line's last-expression type appended. |
|
|
251
|
+
| `rigor_sig_gen` | — (defaults to the configured paths) | `paths` (array of strings), `params` (`"untyped"` \| `"observed"`), `config` | The JSON candidate report — classifications, `rbs`, `inferred_return`, `skip_reason`. |
|
|
252
|
+
| `rigor_check` | `paths` (array of strings) | `config` | The JSON diagnostic report. |
|
|
253
|
+
| `rigor_explain` | — (omit `rule` to list every rule) | `rule` (string) | The rule catalogue entry, as JSON. |
|
|
254
|
+
|
|
255
|
+
Two shape differences from the CLI worth knowing:
|
|
256
|
+
|
|
257
|
+
- `rigor_sig_gen` returns the **JSON candidate report**, always — there
|
|
258
|
+
is no `--print` text mode and no `--diff`. Read `rbs` per candidate.
|
|
259
|
+
- `rigor_sig_gen` exposes `params` but **not** `observe`; observation
|
|
260
|
+
reads the configured `test_paths:` (unset: whichever of `spec/` and
|
|
261
|
+
`test/` exist). To observe anything else, declare it in `test_paths:`
|
|
262
|
+
or use the CLI's `--observe`.
|
|
263
|
+
|
|
264
|
+
`rigor_triage` and `rigor_coverage` are also served, and belong to
|
|
265
|
+
`rigor-baseline-reduce` / `rigor-protection-uplift` rather than here.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# 02 — The paragraph to keep in the project's agent contract
|
|
2
|
+
|
|
3
|
+
A skill only binds an agent that loaded it. The rule below binds every
|
|
4
|
+
session, because it lives in the file the agent reads at startup —
|
|
5
|
+
`AGENTS.md`, or `CLAUDE.md` for Claude Code (which pulls `AGENTS.md` in
|
|
6
|
+
with `@AGENTS.md` when both exist).
|
|
7
|
+
|
|
8
|
+
Paste it verbatim. `rigor-project-init` installs it during onboarding; if
|
|
9
|
+
the project is already onboarded, add it now.
|
|
10
|
+
|
|
11
|
+
## Where it goes
|
|
12
|
+
|
|
13
|
+
- **`AGENTS.md` exists** → append the section at the end. Do not
|
|
14
|
+
reorganise the file.
|
|
15
|
+
- **Only `CLAUDE.md` exists** → append it there.
|
|
16
|
+
- **Both exist** → put it in `AGENTS.md`; add `@AGENTS.md` to `CLAUDE.md`
|
|
17
|
+
only if it is not already pulled in.
|
|
18
|
+
- **Neither exists** → create `AGENTS.md` with this as its first section.
|
|
19
|
+
- **A "Types" / "Type checking" section already exists** → merge into it
|
|
20
|
+
rather than adding a second one, and keep the five bullets intact.
|
|
21
|
+
|
|
22
|
+
Never overwrite unrelated content, and never rewrite a rule the project
|
|
23
|
+
already wrote for itself — show the user the conflict instead.
|
|
24
|
+
|
|
25
|
+
## The fragment
|
|
26
|
+
|
|
27
|
+
```markdown
|
|
28
|
+
## Types come from Rigor, not from reading code
|
|
29
|
+
|
|
30
|
+
This project is type-checked by [Rigor](https://github.com/rigortype/rigor). A type you did not obtain from Rigor is a guess, and a guessed type is never written anywhere: not in `sig/`, not in an inline annotation (`#:`, `# @rbs`), not in a doc comment, not in a review comment, and not as the reason for a nil check or an `is_a?` guard.
|
|
31
|
+
|
|
32
|
+
- The type of an expression: `rigor type-of FILE:LINE:COL`, or `rigor annotate FILE` for a whole file.
|
|
33
|
+
- The signature of a method: `rigor sig-gen --print FILE`; paste what it prints, never what you expect.
|
|
34
|
+
- A parameter type is the one thing inference does not give you: derive it from the call sites with `rigor sig-gen --observe PATH` and keep it only while `rigor check` stays green.
|
|
35
|
+
- When Rigor answers `Dynamic[top]` or `untyped`, or `sig-gen` skips the method, do not fill the gap. Report the exact command and its output; the gap is the finding.
|
|
36
|
+
- Every type you state to a human carries the command that produced it, so it can be re-run.
|
|
37
|
+
|
|
38
|
+
The `rigor-type-oracle` skill (`rigor skill --full rigor-type-oracle`) has the full procedure. With the Rigor MCP server connected, `rigor_type_of`, `rigor_annotate`, and `rigor_sig_gen` are the same oracle as tool calls.
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Two notes for whoever installs it
|
|
42
|
+
|
|
43
|
+
- **The single-long-line shape is deliberate.** Each bullet is one line,
|
|
44
|
+
however long. Some of these files are rendered as Markdown by tools
|
|
45
|
+
that turn a newline inside a paragraph into a line break, so a
|
|
46
|
+
column-wrapped bullet reads ragged. Do not re-wrap it to fit an editor
|
|
47
|
+
ruler.
|
|
48
|
+
- **Tell the user it landed.** It is a change to the file that governs
|
|
49
|
+
every future agent session in the repo — it belongs in the "here is
|
|
50
|
+
what I created, and whether to commit it" report, not in a silent diff.
|
|
51
|
+
It should be committed: the point is that every contributor's agent
|
|
52
|
+
reads the same rule.
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# 03 — The gap protocol
|
|
2
|
+
|
|
3
|
+
Rigor answering "I don't know" is not the oracle failing. It is the
|
|
4
|
+
oracle telling you something the code alone would not have: precision is
|
|
5
|
+
lost *here*, for *this* reason. That is worth more than the annotation
|
|
6
|
+
you were about to write, and it is worth exactly nothing if you paper
|
|
7
|
+
over it.
|
|
8
|
+
|
|
9
|
+
**The rule: never convert a gap into a type.** Report it, locate it,
|
|
10
|
+
route it.
|
|
11
|
+
|
|
12
|
+
## Which output means which gap
|
|
13
|
+
|
|
14
|
+
### `Dynamic[top]` (erased: `untyped`)
|
|
15
|
+
|
|
16
|
+
Rigor has no class information for this expression at all. It is the
|
|
17
|
+
top type, and it is contagious: a `Dynamic[top]` receiver makes every
|
|
18
|
+
method call on it `Dynamic[top]` too, so one unresolved source can
|
|
19
|
+
account for a whole file of "unknown".
|
|
20
|
+
|
|
21
|
+
Common causes, in the order worth checking:
|
|
22
|
+
|
|
23
|
+
- A **method parameter** — parameters are `untyped` by design unless RBS
|
|
24
|
+
or observation says otherwise. Not a defect; use call-site derivation.
|
|
25
|
+
- An **ivar** assigned from a parameter (`@currency = currency`) — the
|
|
26
|
+
same gap, one hop later.
|
|
27
|
+
- A call into a **gem with no RBS** — the dominant cause on a real
|
|
28
|
+
project.
|
|
29
|
+
- A call into a **framework Rigor is not configured for** — Rails
|
|
30
|
+
without the Rails plugins enabled, say.
|
|
31
|
+
- The project's **own monkey-patch or DSL**, which the analyzer never saw
|
|
32
|
+
defined.
|
|
33
|
+
|
|
34
|
+
### `untyped` inside an otherwise-precise type
|
|
35
|
+
|
|
36
|
+
`Array[untyped]`, `Hash[Symbol, untyped]`: the container is proven, the
|
|
37
|
+
element is not. Write the container. Do **not** invent the element — an
|
|
38
|
+
`Array[String]` you guessed is worse than the `Array[untyped]` Rigor
|
|
39
|
+
proved, because it will be believed.
|
|
40
|
+
|
|
41
|
+
### A method missing from `sig-gen` output — the `sig.skipped.*` reasons
|
|
42
|
+
|
|
43
|
+
Read stderr for the count, `--format=json` for the per-method reason.
|
|
44
|
+
|
|
45
|
+
| Reason | What it means | What you do |
|
|
46
|
+
| --- | --- | --- |
|
|
47
|
+
| `sig.skipped.untyped-return` | The body's last expression types as `Dynamic[top]`; emitting `untyped` would be noise. | The commonest gap. Trace the return expression back to its `Dynamic[top]` source and route *that*. Never write a return type here. |
|
|
48
|
+
| `sig.skipped.user-authored` | An RBS declaration already exists and `--overwrite` was not given. | Not a gap. The hand-written type is the project's answer — read `sig/`, and if it disagrees with inference, raise the disagreement rather than silently retyping. |
|
|
49
|
+
| `sig.skipped.unrenderable-rbs` | Rigor rendered a signature that does not parse as RBS, so it was dropped rather than written. | **A bug in Rigor**, not in the code. Report it with the method and the file. |
|
|
50
|
+
| `sig.skipped.complex-shape` | Reserved; the generator does not produce it today. | If you ever see one, it is worth reporting as a surprise. |
|
|
51
|
+
| `skipped_outside_sig_root` | A `--write` target outside the configured signature paths. | Configuration, not inference. |
|
|
52
|
+
|
|
53
|
+
`rigor explain <id>` answers each of these ids directly (the command
|
|
54
|
+
carries a second catalogue for the skip reasons alongside the
|
|
55
|
+
diagnostic rules); this table is the summary.
|
|
56
|
+
|
|
57
|
+
### `equivalent`, and silence
|
|
58
|
+
|
|
59
|
+
A `tighter-return` candidate that never appears was classified
|
|
60
|
+
`equivalent`: the inferred return is not a strict subtype of what `sig/`
|
|
61
|
+
already declares. The existing declaration stands. Silence here means
|
|
62
|
+
"nothing to change", not "nothing is known" — check `sig/` before calling
|
|
63
|
+
it a gap.
|
|
64
|
+
|
|
65
|
+
## Locating the gap before you report it
|
|
66
|
+
|
|
67
|
+
Two commands turn "somewhere upstream" into a line number.
|
|
68
|
+
|
|
69
|
+
```sh
|
|
70
|
+
rigor annotate FILE # walk the #=> column upward to the first Dynamic[top]
|
|
71
|
+
rigor trace --format=json --line=N FILE
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
`annotate` is usually enough: the first line in the chain that reports
|
|
75
|
+
`Dynamic[top]` is the source, and everything below it is cascade. Use
|
|
76
|
+
`trace` when the loss happens *within* a line — its `bind` events name
|
|
77
|
+
each local and the type it received, so you can see which argument
|
|
78
|
+
arrived unknown.
|
|
79
|
+
|
|
80
|
+
If a diagnostic fired near the site, `rigor explain <rule>` gives its
|
|
81
|
+
firing conditions, which frequently name the cause outright.
|
|
82
|
+
|
|
83
|
+
## Routing table — project-side gaps have an owner
|
|
84
|
+
|
|
85
|
+
Once you know the source, the fix is almost never "write the type here".
|
|
86
|
+
|
|
87
|
+
| The gap's source | Route to | Why |
|
|
88
|
+
| --- | --- | --- |
|
|
89
|
+
| A dependency gem ships no RBS | **`rigor-rbs-setup`** | `rbs collection install` brings in community RBS; this is the single biggest `Dynamic` reduction on most projects. |
|
|
90
|
+
| A framework Rigor isn't configured for (Rails, RSpec, dry-rb…) | **`rigor-plugin-tune`** | The bundled plugin for it is probably just not enabled in `.rigor.dist.yml`. |
|
|
91
|
+
| `undefined-method` on the project's own monkey-patches | **`rigor-monkeypatch-resolve`** | Wiring the defining files into `pre_eval:` makes them visible. |
|
|
92
|
+
| The project's own DSL / `define_method` factory / `method_missing` | **`rigor-plugin-author`** | Rigor does not bundle per-application plugins; a project-owned plugin is the durable fix. |
|
|
93
|
+
| The site is protected-coverage work, not a documentation task | **`rigor-protection-uplift`** | It owns the "minimal true annotation + double gate" loop. |
|
|
94
|
+
| The setup itself looks wrong (zero RBS classes, config not taking) | **`rigor-doctor`** | Validate before concluding anything about inference. |
|
|
95
|
+
| None of the above — Rigor should have inferred this | A Rigor issue | See below. |
|
|
96
|
+
|
|
97
|
+
Offer the route; do not silently switch tasks. The user asked you to
|
|
98
|
+
document a class, and "the reason I cannot is X, and here is the skill
|
|
99
|
+
that fixes X" is the answer to that request.
|
|
100
|
+
|
|
101
|
+
## Reporting an engine-side gap
|
|
102
|
+
|
|
103
|
+
When the type is derivable from the source and Rigor still says
|
|
104
|
+
`Dynamic[top]`, that is a completeness gap in the engine, and it is worth
|
|
105
|
+
more to the project than any annotation. File it at
|
|
106
|
+
<https://github.com/rigortype/rigor/issues> with these five parts:
|
|
107
|
+
|
|
108
|
+
1. **The file and line** — the smallest reproduction you can get to,
|
|
109
|
+
ideally a standalone snippet rather than a pointer into a private
|
|
110
|
+
repo.
|
|
111
|
+
2. **The exact command**, as run: `rigor type-of demo.rb:12:5`,
|
|
112
|
+
`rigor sig-gen --print demo.rb`.
|
|
113
|
+
3. **The exact output**, pasted, including the stderr skip line.
|
|
114
|
+
4. **What the correct type is, and what proves it** — the Ruby-level
|
|
115
|
+
reasoning a reader can verify. "`Array#sum` over `Integer` elements is
|
|
116
|
+
`Integer`", not "it should obviously be Integer".
|
|
117
|
+
5. **What the report proves** — one sentence naming the *class* of gap,
|
|
118
|
+
not just the instance: "block-parameter destructuring loses the
|
|
119
|
+
element type", "a keyword default of `Time.now` does not seed the
|
|
120
|
+
parameter". This is the part that makes the issue actionable, because
|
|
121
|
+
it says what a fix would generalise to.
|
|
122
|
+
|
|
123
|
+
Also say `rigor --version`, and note whether `sig/` and the relevant
|
|
124
|
+
plugins were in play — a gap that only appears without community RBS is a
|
|
125
|
+
different bug from one that survives it.
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rigor-unused-adjudicate
|
|
3
|
-
description:
|
|
4
|
-
|
|
3
|
+
description: >-
|
|
4
|
+
Adjudicate a `rigor unused` report safely before proposing dead-code removal. Use when interpreting or
|
|
5
|
+
reviewing Rigor's unused classes/modules/constants, or when a cleanup is based on that report; not for
|
|
6
|
+
a specific deletion already known to be safe or for ordinary `rigor check` diagnostics.
|
|
5
7
|
license: MPL-2.0
|
|
6
8
|
metadata:
|
|
7
9
|
version: 0.2.0
|
|
@@ -31,11 +33,14 @@ and skipping one is how a live class ends up on a deletion list.
|
|
|
31
33
|
|
|
32
34
|
Run the report and answer these against the project in front of you.
|
|
33
35
|
|
|
34
|
-
**Are framework roots actually supplied?**
|
|
35
|
-
`roots: N (M from plugins,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
**Are framework roots actually supplied?** When a plugin contributes roots, the
|
|
37
|
+
summary's `roots:` line grows a parenthetical: `roots: N (M from plugins, K
|
|
38
|
+
matched no declaration)`. The parenthetical is omitted entirely when no plugin
|
|
39
|
+
contributed — so on a framework application, a bare `roots: N` with **no**
|
|
40
|
+
`(… from plugins …)` note means nothing is naming your controllers, jobs or
|
|
41
|
+
policies, and most of the report is noise. Stop and fix the plugin
|
|
42
|
+
configuration — `rigor docs 07-plugins` — rather than adjudicating hundreds of
|
|
43
|
+
rows.
|
|
39
44
|
|
|
40
45
|
**Does the project ship signatures?** If `signature_paths:` is configured, also
|
|
41
46
|
run with it emptied and compare:
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rigor-upgrade
|
|
3
|
-
description:
|
|
4
|
-
Adopt a new
|
|
3
|
+
description: >-
|
|
4
|
+
Adopt a new `rigortype` version by comparing its diagnostics with the committed baseline and separating
|
|
5
|
+
new catches from signature-quality false positives. Use after a Rigor gem upgrade; not for first-time
|
|
6
|
+
setup or routine baseline reduction.
|
|
5
7
|
license: MPL-2.0
|
|
6
8
|
metadata:
|
|
7
9
|
version: 0.1.0
|
|
@@ -50,12 +52,15 @@ rigor --version
|
|
|
50
52
|
### Phase 2 — see the delta against the committed baseline
|
|
51
53
|
|
|
52
54
|
```sh
|
|
53
|
-
rigor check
|
|
54
|
-
rigor
|
|
55
|
+
rigor check # everything outside the committed baseline's envelope
|
|
56
|
+
rigor baseline drift # per-bucket movement against .rigor-baseline.yml
|
|
55
57
|
```
|
|
56
58
|
|
|
57
|
-
|
|
58
|
-
what the
|
|
59
|
+
With `baseline:` wired, `rigor check` already hides what the baseline
|
|
60
|
+
covers, so what it prints is **new** relative to the baseline — that set
|
|
61
|
+
is what the upgrade changed. `rigor baseline drift` adds the bucket view:
|
|
62
|
+
buckets now over their recorded count, and buckets the new version
|
|
63
|
+
cleared or shrank.
|
|
59
64
|
|
|
60
65
|
### Phase 3 — sort the new diagnostics
|
|
61
66
|
|
|
@@ -80,8 +85,8 @@ envelope so the regeneration does not bury what you just fixed:
|
|
|
80
85
|
rigor baseline regenerate
|
|
81
86
|
```
|
|
82
87
|
|
|
83
|
-
|
|
84
|
-
team adopts the same post-upgrade baseline.
|
|
88
|
+
Recommend committing the updated `.rigor-baseline.yml` together with any
|
|
89
|
+
fixes, so the team adopts the same post-upgrade baseline.
|
|
85
90
|
|
|
86
91
|
## Note
|
|
87
92
|
|