rigortype 0.3.9 → 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/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 +127 -4
- data/docs/handbook/03-narrowing.md +95 -10
- data/docs/handbook/04-tuples-and-shapes.md +8 -6
- data/docs/handbook/07-rbs-and-extended.md +16 -11
- data/docs/handbook/10-sorbet.md +9 -10
- data/docs/handbook/11-sig-gen.md +454 -13
- data/docs/manual/02-cli-reference.md +63 -2
- data/docs/manual/03-configuration.md +7 -0
- data/docs/manual/04-diagnostics.md +4 -0
- data/docs/manual/07-plugins.md +1 -1
- data/docs/manual/10-mcp-server.md +3 -2
- data/docs/manual/16-rbs-extended-annotations.md +40 -7
- 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 +243 -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 +110 -4
- data/docs/manual/plugins/rigor-activestorage.md +8 -1
- data/docs/manual/plugins/rigor-activesupport-core-ext.md +11 -5
- 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 +212 -25
- 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 +1 -1
- data/lib/rigor/analysis/check_rules/declaration_sourced_guard.rb +167 -2
- data/lib/rigor/analysis/check_rules/lexical_method_sites.rb +189 -0
- data/lib/rigor/analysis/check_rules/main_pass_collector.rb +5 -3
- data/lib/rigor/analysis/check_rules/rule_ids.rb +20 -5
- data/lib/rigor/analysis/check_rules/rule_walk.rb +2 -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 +36 -2
- data/lib/rigor/analysis/check_rules.rb +520 -49
- data/lib/rigor/analysis/dependency_recorder.rb +23 -0
- data/lib/rigor/analysis/fact_store.rb +9 -0
- data/lib/rigor/analysis/incremental.rb +26 -0
- data/lib/rigor/analysis/incremental_session.rb +36 -4
- data/lib/rigor/analysis/project_scan.rb +11 -1
- data/lib/rigor/analysis/reachability/plugin_roots.rb +0 -1
- data/lib/rigor/analysis/reachability/scan_cache.rb +1 -0
- data/lib/rigor/analysis/rule_catalog.rb +127 -0
- data/lib/rigor/analysis/run_cache_key.rb +20 -11
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +167 -11
- data/lib/rigor/analysis/runner/effect_envelope_pass.rb +9 -4
- data/lib/rigor/analysis/runner/pool_coordinator.rb +107 -15
- data/lib/rigor/analysis/runner/project_pre_passes.rb +26 -7
- data/lib/rigor/analysis/runner.rb +278 -20
- 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 +53 -10
- data/lib/rigor/bleeding_edge.rb +0 -2
- data/lib/rigor/builtins/hkt_builtins.rb +1 -0
- data/lib/rigor/builtins/imported_refinements.rb +4 -0
- data/lib/rigor/builtins/regex_refinement.rb +17 -9
- data/lib/rigor/builtins/static_return_refinements.rb +2 -0
- data/lib/rigor/cache/descriptor.rb +6 -1
- data/lib/rigor/cache/engine_source.rb +29 -1
- data/lib/rigor/cache/incremental_snapshot.rb +33 -1
- data/lib/rigor/cache/rbs_cache_producer.rb +4 -0
- data/lib/rigor/cache/rbs_descriptor.rb +37 -7
- data/lib/rigor/cache/store.rb +0 -1
- data/lib/rigor/ci_detector.rb +1 -0
- data/lib/rigor/cli/doc_links.rb +1 -1
- data/lib/rigor/cli/docs_command.rb +4 -4
- data/lib/rigor/cli/plugin_command.rb +3 -3
- data/lib/rigor/cli/prism_colorizer.rb +0 -1
- data/lib/rigor/cli/sig_gen_command.rb +210 -29
- data/lib/rigor/cli/skill_command.rb +1 -1
- data/lib/rigor/cli/skill_describe.rb +0 -1
- data/lib/rigor/cli/type_of_command.rb +19 -5
- 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.rb +21 -3
- data/lib/rigor/configuration/severity_profile.rb +19 -3
- data/lib/rigor/configuration.rb +66 -3
- data/lib/rigor/effects/ancestry_recorder.rb +191 -0
- data/lib/rigor/effects/attribution.rb +11 -2
- 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 +9 -2
- data/lib/rigor/effects/definition_context.rb +179 -0
- data/lib/rigor/effects/effect_table.rb +11 -3
- data/lib/rigor/effects/envelope_check.rb +1 -1
- data/lib/rigor/effects/envelope_index.rb +15 -0
- data/lib/rigor/effects/file_collection.rb +59 -5
- data/lib/rigor/effects/framework_units.rb +1 -1
- data/lib/rigor/effects/identity.rb +16 -0
- data/lib/rigor/effects/local_ownership.rb +38 -12
- data/lib/rigor/effects/method_key.rb +21 -0
- data/lib/rigor/effects/mutation_classifier.rb +23 -12
- data/lib/rigor/effects/plugin_facts.rb +43 -31
- data/lib/rigor/effects/propagator.rb +295 -16
- data/lib/rigor/effects/registry.rb +1 -1
- data/lib/rigor/effects/scanner.rb +121 -72
- data/lib/rigor/effects/signature_sources.rb +1 -1
- data/lib/rigor/effects/snapshot.rb +2 -1
- data/lib/rigor/effects/summary.rb +27 -4
- data/lib/rigor/effects/unit_scan.rb +385 -30
- data/lib/rigor/effects/visibility.rb +101 -0
- data/lib/rigor/environment/lockfile_resolver.rb +17 -0
- data/lib/rigor/environment/member_consistency/comparator.rb +708 -0
- data/lib/rigor/environment/member_consistency.rb +298 -0
- data/lib/rigor/environment/rbs_loader.rb +399 -133
- data/lib/rigor/environment.rb +103 -38
- data/lib/rigor/hashing/xxh3.rb +264 -0
- data/lib/rigor/inference/acceptance.rb +139 -9
- 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 +73 -27
- data/lib/rigor/inference/block_repetition.rb +71 -0
- data/lib/rigor/inference/body_fixpoint.rb +2 -1
- data/lib/rigor/inference/budget_trace.rb +2 -1
- 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 +387 -15
- data/lib/rigor/inference/closure_escape_analyzer.rb +157 -13
- data/lib/rigor/inference/content_join.rb +200 -27
- 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/element_read_widening.rb +22 -10
- data/lib/rigor/inference/error_info.rb +196 -0
- data/lib/rigor/inference/expression_typer.rb +1532 -496
- data/lib/rigor/inference/external_ancestor_resolution.rb +267 -0
- 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/index_write_widening.rb +16 -3
- 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 +167 -17
- 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 +85 -24
- data/lib/rigor/inference/method_dispatcher/facet_distribution.rb +147 -0
- data/lib/rigor/inference/method_dispatcher/hash_transform_keys_folding.rb +191 -0
- data/lib/rigor/inference/method_dispatcher/iterator_dispatch.rb +4 -0
- data/lib/rigor/inference/method_dispatcher/match_data_folding.rb +159 -0
- data/lib/rigor/inference/method_dispatcher/overload_selector.rb +113 -73
- 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/rbs_dispatch.rb +881 -38
- data/lib/rigor/inference/method_dispatcher/self_substitute.rb +142 -0
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +128 -53
- data/lib/rigor/inference/method_dispatcher/struct_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher.rb +214 -13
- data/lib/rigor/inference/method_parameter_binder.rb +8 -3
- data/lib/rigor/inference/multi_target_binder.rb +340 -52
- data/lib/rigor/inference/mutation_rejoin.rb +4 -1
- data/lib/rigor/inference/mutation_widening.rb +70 -48
- data/lib/rigor/inference/narrowing.rb +540 -120
- 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 +152 -9
- data/lib/rigor/inference/parameter_inference_collector.rb +3 -2
- data/lib/rigor/inference/project_method_ownership.rb +136 -0
- data/lib/rigor/inference/project_patched_methods.rb +7 -2
- data/lib/rigor/inference/project_patched_scanner.rb +7 -3
- data/lib/rigor/inference/receiver_alias.rb +90 -1
- data/lib/rigor/inference/receiver_blind_block.rb +219 -0
- data/lib/rigor/inference/refinement_mutation.rb +15 -11
- 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 +4615 -551
- data/lib/rigor/inference/statement_evaluator.rb +3176 -490
- data/lib/rigor/inference/stored_block_call.rb +54 -0
- data/lib/rigor/inference/string_mutation.rb +44 -7
- data/lib/rigor/inference/unknown_store_widening.rb +200 -0
- data/lib/rigor/inference/unthreaded_rebinds.rb +282 -0
- data/lib/rigor/language_server/debouncer.rb +0 -1
- data/lib/rigor/language_server/diagnostic_publisher.rb +3 -2
- data/lib/rigor/language_server/hover_renderer.rb +3 -3
- data/lib/rigor/language_server/project_context.rb +5 -3
- data/lib/rigor/mcp/server.rb +2 -1
- data/lib/rigor/plugin/base.rb +168 -5
- data/lib/rigor/plugin/box_probe.rb +91 -0
- data/lib/rigor/plugin/bundled_catalog.rb +1 -1
- data/lib/rigor/plugin/effect_attribution.rb +58 -4
- data/lib/rigor/plugin/loader.rb +2 -1
- data/lib/rigor/plugin/macro/block_as_method.rb +45 -6
- data/lib/rigor/plugin/manifest.rb +71 -10
- data/lib/rigor/plugin/registry.rb +35 -1
- data/lib/rigor/plugin/source_rbs_synthesis_reporter.rb +9 -3
- data/lib/rigor/plugin/template_unit.rb +196 -0
- data/lib/rigor/plugin.rb +1 -0
- data/lib/rigor/protection/discovery_seed.rb +3 -1
- data/lib/rigor/protection/kill_signature.rb +0 -1
- data/lib/rigor/protection/mutation_cache.rb +1 -2
- data/lib/rigor/rbs_extended.rb +27 -0
- data/lib/rigor/reflection/constant_ancestors.rb +97 -0
- data/lib/rigor/reflection/constant_path.rb +19 -6
- data/lib/rigor/reflection.rb +72 -105
- data/lib/rigor/scope/discovery_index.rb +135 -2
- data/lib/rigor/scope.rb +859 -49
- 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 +558 -31
- data/lib/rigor/sig_gen/inline_declarations.rb +184 -0
- data/lib/rigor/sig_gen/method_candidate.rb +47 -3
- data/lib/rigor/sig_gen/observation_collector.rb +1 -1
- data/lib/rigor/sig_gen/renderer.rb +124 -9
- data/lib/rigor/sig_gen/skip_reason_catalog.rb +44 -1
- data/lib/rigor/sig_gen/write_result.rb +19 -3
- data/lib/rigor/sig_gen/writer.rb +166 -35
- data/lib/rigor/sig_gen.rb +3 -0
- data/lib/rigor/signature_path_audit.rb +1 -1
- data/lib/rigor/source/node_walker.rb +0 -3
- data/lib/rigor/source/parameter_envelope.rb +72 -0
- data/lib/rigor/source.rb +1 -0
- data/lib/rigor/type/combinator.rb +88 -12
- data/lib/rigor/type/difference.rb +1 -0
- data/lib/rigor/type/hash_shape.rb +1 -1
- data/lib/rigor/type/refined.rb +1 -0
- data/lib/rigor/version.rb +1 -1
- data/lib/rigor.rb +1 -0
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/effects.rb +1 -0
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +9 -5
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb +13 -4
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb +0 -1
- 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 +239 -4
- 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/effects.rb +1 -0
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob.rb +9 -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 +380 -3
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_index.rb +14 -6
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +281 -35
- data/plugins/rigor-activerecord/sig/active_record/relation.rbs +206 -31
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +25 -14
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext/effects.rb +9 -2
- data/plugins/rigor-activesupport-core-ext/sig/active_support/core_ext.rbs +171 -5
- data/plugins/rigor-dry-monads/lib/rigor/plugin/dry_monads.rb +2 -0
- data/plugins/rigor-ethon/lib/rigor/plugin/ethon.rb +1 -0
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi/types.rb +1 -1
- 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.rb +72 -2
- data/plugins/rigor-graphql/sig/graphql.rbs +485 -0
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest/assertion_analyzer.rb +2 -0
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit.rb +11 -7
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n.rb +35 -37
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/analyzer.rb +0 -1
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/devise_routes.rb +2 -0
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/doorkeeper_routes.rb +1 -0
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +9 -17
- 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 +217 -36
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/schedule_scan.rb +1 -0
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq.rb +9 -5
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sigil_detector.rb +0 -1
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +46 -1
- data/plugins/rigor-sorbet/sig/sorbet.rbs +277 -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/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 +12 -10
- data/sig/rigor/inference/optimistic_origin.rbs +10 -0
- data/sig/rigor/inference.rbs +6 -4
- 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 +1 -1
- data/sig/rigor/plugin/loader.rbs +3 -3
- data/sig/rigor/plugin/manifest.rbs +50 -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 +7 -6
- data/sig/rigor/scope.rbs +135 -20
- data/sig/rigor/sig_gen/skip_reason_catalog.rbs +14 -7
- data/sig/rigor/source.rbs +4 -4
- data/sig/rigor/testing.rbs +10 -4
- data/sig/rigor/type.rbs +6 -0
- data/sig/rigor.rbs +38 -20
- data/skills/rigor-ask/SKILL.md +8 -5
- 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 +12 -25
- 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 +9 -7
- data/skills/rigor-project-init/references/01-detect.md +13 -9
- data/skills/rigor-project-init/references/02-configure.md +33 -8
- 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-protection-uplift/SKILL.md +4 -6
- data/skills/rigor-rbs-setup/SKILL.md +4 -2
- data/skills/rigor-type-oracle/SKILL.md +4 -6
- data/skills/rigor-type-oracle/references/01-oracle-commands.md +12 -8
- data/skills/rigor-type-oracle/references/03-gap-protocol.md +0 -3
- data/skills/rigor-unused-adjudicate/SKILL.md +4 -2
- data/skills/rigor-upgrade/SKILL.md +13 -8
- metadata +108 -1
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rigor-plugin-review
|
|
3
|
-
description:
|
|
4
|
-
|
|
3
|
+
description: >-
|
|
4
|
+
Audit an existing Rigor plugin against the current authoring contract and produce a prioritized upgrade
|
|
5
|
+
path. Use when modernizing or reviewing a `rigor-*` plugin; not for authoring a new plugin, enabling
|
|
6
|
+
bundled plugins, or tuning project config.
|
|
5
7
|
license: MPL-2.0
|
|
6
8
|
metadata:
|
|
7
9
|
version: 0.1.0
|
|
@@ -120,7 +122,7 @@ green first, so you can prove each later step is a faithful refactor:
|
|
|
120
122
|
# external gem:
|
|
121
123
|
bundle exec rspec spec/
|
|
122
124
|
# in the rigor monorepo:
|
|
123
|
-
nix
|
|
125
|
+
nix develop --command bundle exec rspec spec/integration/<plugins|examples>/<id>_plugin_spec.rb
|
|
124
126
|
```
|
|
125
127
|
|
|
126
128
|
If there is no spec, **write one first** (per `rigor-plugin-author`
|
|
@@ -148,7 +150,7 @@ step**:
|
|
|
148
150
|
### Phase 5 — Verify
|
|
149
151
|
|
|
150
152
|
```sh
|
|
151
|
-
rigor check <plugin>/lib # ADR-43 contract self-check —
|
|
153
|
+
rigor check <plugin>/lib # ADR-43 contract self-check — must be clean
|
|
152
154
|
rigor plugins --strict # the plugin still loads
|
|
153
155
|
rigor plugins --capabilities # node-rule types / dynamic_return receivers look right
|
|
154
156
|
bundle exec rspec … # the oracle spec, still green
|
|
@@ -205,7 +205,8 @@ and put that in a CHANGELOG / migration note, not the class docstring.
|
|
|
205
205
|
|
|
206
206
|
- `rigor check <plugin>/lib` — the ADR-43 contract self-check resolves
|
|
207
207
|
the plugin's inherited `Plugin::Base` calls and warns on contract
|
|
208
|
-
misuse.
|
|
208
|
+
misuse. It must be clean; fix the cause rather than disabling the
|
|
209
|
+
rule.
|
|
209
210
|
- `rigor plugins --strict` — the plugin still activates.
|
|
210
211
|
- `rigor plugins --capabilities` — `node_rule_types` /
|
|
211
212
|
`dynamic_return_receivers` / `narrowing_facts_methods` reflect the
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rigor-plugin-tune
|
|
3
|
-
description:
|
|
4
|
-
|
|
3
|
+
description: >-
|
|
4
|
+
Match a configured project's `Gemfile.lock` to Rigor's bundled plugin catalogue and enable the plugins
|
|
5
|
+
its current dependencies need. Use after adding a gem or when plugin selection is stale; not for
|
|
6
|
+
first-time onboarding or authoring a new plugin.
|
|
5
7
|
license: MPL-2.0
|
|
6
8
|
metadata:
|
|
7
9
|
version: 0.1.0
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rigor-project-init
|
|
3
|
-
description:
|
|
4
|
-
Onboard a project to Rigor
|
|
3
|
+
description: >-
|
|
4
|
+
Onboard a project to Rigor from scratch by detecting the stack, selecting plugins and an adoption mode,
|
|
5
|
+
and writing the initial config and baseline or strict gate. Use for first-time Rigor setup; not for an
|
|
6
|
+
existing baseline or plugin authoring.
|
|
5
7
|
license: MPL-2.0
|
|
6
8
|
metadata:
|
|
7
9
|
version: 0.1.0
|
|
@@ -52,7 +54,7 @@ Do NOT trigger for:
|
|
|
52
54
|
`rigor-baseline-reduce` skill.
|
|
53
55
|
- **Writing a Rigor plugin** for the project's own DSL /
|
|
54
56
|
metaprogramming — that is the `rigor-plugin-author` skill. (This
|
|
55
|
-
skill *points at* plugin authoring as an escalation in Phase
|
|
57
|
+
skill *points at* plugin authoring as an escalation in Phase 8;
|
|
56
58
|
it does not do it.)
|
|
57
59
|
- **Tweaking an already-configured project** — ordinary edits to an
|
|
58
60
|
existing `.rigor.yml`; no onboarding pipeline needed.
|
|
@@ -77,7 +79,7 @@ adoption entirely.
|
|
|
77
79
|
|
|
78
80
|
So **before writing any config, present the user with two modes**
|
|
79
81
|
and let them choose. The mode drives the severity profile, whether a
|
|
80
|
-
baseline is generated, and how Phase
|
|
82
|
+
baseline is generated, and how Phase 8 frames the leftover
|
|
81
83
|
diagnostics.
|
|
82
84
|
|
|
83
85
|
| | **Acknowledge mode** (baseline adoption) | **Strict mode** (no compromise) |
|
|
@@ -154,7 +156,7 @@ committed `sig/` directory.
|
|
|
154
156
|
| 5 | [`references/06-agent-contract.md`](references/06-agent-contract.md) | **Phase 8a.** The one paragraph the project's `AGENTS.md` / `CLAUDE.md` keeps so every agent session sources types from Rigor rather than guessing them. Where to append it, when to create the file, and what never to overwrite. |
|
|
155
157
|
| — (optional) | [`references/05-jit-performance.md`](references/05-jit-performance.md) | **Operational, not a phase.** Run speed via a Ruby JIT: Rigor auto-enables YJIT for long runs (~5 s break-even), how to detect JIT support in your install, the override env vars, and why YJIT beats ZJIT for Rigor on Ruby 4.0. Read only when a large project's `rigor check` wall time matters. |
|
|
156
158
|
|
|
157
|
-
## Escalation paths (Phase
|
|
159
|
+
## Escalation paths (Phase 8 preview)
|
|
158
160
|
|
|
159
161
|
Some diagnostic clusters are neither a quick fix nor honest baseline
|
|
160
162
|
material. Two of them have a dedicated answer this skill hands off to:
|
|
@@ -183,7 +185,7 @@ material. Two of them have a dedicated answer this skill hands off to:
|
|
|
183
185
|
support, **open an issue on the Rigor project** asking for it:
|
|
184
186
|
<https://github.com/rigortype/rigor/issues>.
|
|
185
187
|
|
|
186
|
-
Neither is a Phase
|
|
188
|
+
Neither is a Phase 8 obligation — they are options to *offer* the
|
|
187
189
|
user when the triage report points at one of these causes. The
|
|
188
190
|
project-DSL handoff is detailed in
|
|
189
191
|
[`references/03-baseline-and-bugs.md`](references/03-baseline-and-bugs.md)
|
|
@@ -223,7 +225,7 @@ only in acknowledge mode). For each, give the commit recommendation:
|
|
|
223
225
|
|
|
224
226
|
| File | What it is | Commit? |
|
|
225
227
|
| --- | --- | --- |
|
|
226
|
-
| `.rigor.dist.yml` | The shared project config (Phase 4) — `target_ruby`, `paths:`, `plugins:`, `severity_profile:`, and the `baseline:` pointer. The single source of truth every contributor's `rigor check` reads. | **Yes** — it is the shared config; sharing it is the whole point. |
|
|
228
|
+
| `.rigor.dist.yml` | The shared project config (Phase 4) — `target_ruby`, `paths:`, `test_paths:`, `plugins:`, `severity_profile:`, and the `baseline:` pointer. The single source of truth every contributor's `rigor check` reads. | **Yes** — it is the shared config; sharing it is the whole point. |
|
|
227
229
|
| `.rigor-baseline.yml` | Acknowledge mode only (Phase 7) — the snapshot of today's known diagnostics. Doubles as a record of project state; without it each developer's baseline diverges and the regression guard means different things per machine. | **Yes** — commit it; it documents project state and pins the regression envelope. |
|
|
228
230
|
| `sig/` | RBS skeletons from `rigor sig-gen` (Phase 5), if that phase ran. A first-class project artefact — it sharpens inference for everyone. | **Yes** — commit it (see [`references/04-sig-uplift.md`](references/04-sig-uplift.md) § "Commit the sig/ directory"). |
|
|
229
231
|
| `.rigor/` (contains `cache/`) | The per-file analysis cache `rigor check` writes to speed up re-runs. Regenerable and machine-local. | **No** — add `.rigor/` to `.gitignore`. |
|
|
@@ -71,14 +71,13 @@ The directory should contain RBS gem subdirectories. Continue to
|
|
|
71
71
|
Phase 2 — the collection will be auto-detected by Rigor at analysis
|
|
72
72
|
time.
|
|
73
73
|
|
|
74
|
-
**Note: RBS collision after install.**
|
|
75
|
-
|
|
76
|
-
Ruby
|
|
77
|
-
|
|
78
|
-
`RBS::DuplicatedDeclarationError
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
deduplicate stdlib gems from the collection automatically.
|
|
74
|
+
**Note: RBS collision after install.** Rigor skips collection entries
|
|
75
|
+
for gems it already loads from its bundled RBS — including gems
|
|
76
|
+
extracted from Ruby's stdlib, such as `cgi` and `logger` — so the
|
|
77
|
+
collection does not double-declare them. If `rigor triage` still prints
|
|
78
|
+
an `RBS::DuplicatedDeclarationError`, note it and continue, and report
|
|
79
|
+
it at <https://github.com/rigortype/rigor/issues> with the gem names the
|
|
80
|
+
error mentions.
|
|
82
81
|
|
|
83
82
|
### Path scope
|
|
84
83
|
|
|
@@ -92,6 +91,11 @@ Note the conventional source roots so Phase 4 can set `paths:`:
|
|
|
92
91
|
are checked differently and inflate the diagnostic count. `vendor/`
|
|
93
92
|
and `tmp/` are always excluded.
|
|
94
93
|
|
|
94
|
+
Note the **test roots** too — every directory holding the project's
|
|
95
|
+
tests, not only the conventional one (`spec/`, `test/`, and any
|
|
96
|
+
extra suite such as `test/system` kept elsewhere or an
|
|
97
|
+
`integration/` tree). Phase 4 writes them to `test_paths:`.
|
|
98
|
+
|
|
95
99
|
## Phase 3 — Plugin selection
|
|
96
100
|
|
|
97
101
|
Propose a plugin set from the detected families. Present it to the
|
|
@@ -120,7 +124,7 @@ ActiveSupport monkey-patches the core classes (`3.days`,
|
|
|
120
124
|
`rigor-activesupport-core-ext` bundle, every such call reports
|
|
121
125
|
`call.undefined-method` — on a real Rails app this is the single
|
|
122
126
|
largest diagnostic cluster (a measured Mastodon run: ~365 of 489
|
|
123
|
-
diagnostics were exactly this). Phase
|
|
127
|
+
diagnostics were exactly this). Phase 6's `rigor triage` flags it as
|
|
124
128
|
hint `activesupport-core-ext`.
|
|
125
129
|
|
|
126
130
|
`rigor-activesupport-core-ext` is a **plugin** (an RBS-bundle plugin
|
|
@@ -91,6 +91,11 @@ paths:
|
|
|
91
91
|
- app
|
|
92
92
|
- lib
|
|
93
93
|
|
|
94
|
+
# Where the tests live. `rigor sig-gen --params=observed` reads their
|
|
95
|
+
# call sites to type parameters (Phase 5). Not analysed by `rigor check`.
|
|
96
|
+
test_paths:
|
|
97
|
+
- spec
|
|
98
|
+
|
|
94
99
|
exclude:
|
|
95
100
|
- vendor
|
|
96
101
|
- tmp
|
|
@@ -107,7 +112,7 @@ plugins:
|
|
|
107
112
|
|
|
108
113
|
severity_profile: lenient
|
|
109
114
|
|
|
110
|
-
# Phase
|
|
115
|
+
# Phase 7 (acknowledge mode) appends this line after generating the
|
|
111
116
|
# baseline. Strict mode leaves it out entirely.
|
|
112
117
|
# baseline: .rigor-baseline.yml
|
|
113
118
|
```
|
|
@@ -138,9 +143,28 @@ A strict-mode plain-Ruby gem is shorter:
|
|
|
138
143
|
```yaml
|
|
139
144
|
paths:
|
|
140
145
|
- lib
|
|
146
|
+
test_paths:
|
|
147
|
+
- test
|
|
141
148
|
severity_profile: strict
|
|
142
149
|
```
|
|
143
150
|
|
|
151
|
+
### Test roots — write `test_paths:` explicitly
|
|
152
|
+
|
|
153
|
+
Always write `test_paths:` with the test roots Phase 1 found, even
|
|
154
|
+
when they are the conventional `spec/` or `test/`. Left unset, Rigor
|
|
155
|
+
auto-detects whichever of `spec/` and `test/` exist; that covers the
|
|
156
|
+
common layouts, but the committed config is then silent about where
|
|
157
|
+
the tests are, and a suite anywhere else (a second tree, an
|
|
158
|
+
`integration/` directory) is never read. Declaring the key replaces
|
|
159
|
+
auto-detection, so list every root. A project with no tests yet
|
|
160
|
+
writes `test_paths: []`.
|
|
161
|
+
|
|
162
|
+
The key affects no diagnostic. Its reader today is `rigor sig-gen
|
|
163
|
+
--params=observed` (Phase 5), which types a parameter from the
|
|
164
|
+
arguments the tests pass. When there is no root to read, or a declared
|
|
165
|
+
root does not exist, sig-gen says so on stderr and the affected
|
|
166
|
+
parameters stay `untyped`.
|
|
167
|
+
|
|
144
168
|
### Key reference
|
|
145
169
|
|
|
146
170
|
Only the keys this skill needs. `rigor --help` and the project
|
|
@@ -150,19 +174,20 @@ handbook document the full surface.
|
|
|
150
174
|
| --- | --- |
|
|
151
175
|
| `paths:` | Directories Rigor analyses. Source roots only — not `spec/` / `test/`. |
|
|
152
176
|
| `exclude:` | Paths removed from the `paths:` walk. |
|
|
177
|
+
| `test_paths:` | The project's test roots (`spec`, `test`, or several). Write it explicitly; see § "Test roots". Relative entries resolve against the config file. `rigor check` ignores it; `sig-gen` names a declared root that does not exist. |
|
|
153
178
|
| `plugins:` | Plugin ids to activate (the Phase 3 set). |
|
|
154
179
|
| `signature_paths:` | Extra RBS source **directories** (paths, not gem names; resolved relative to the config file). Use it for the project's own local `sig/` if it has one. RBS-bundle *plugins* like `rigor-activesupport-core-ext` ship their own `sig/` and need no entry here — list them under `plugins:`. |
|
|
155
180
|
| `severity_profile:` | `lenient` / `balanced` / `strict`. See the table above. |
|
|
156
181
|
| `severity_overrides:` | Per-rule severity tweaks. Leave empty at init; the baseline-reduce workflow tunes it later. |
|
|
157
|
-
| `baseline:` | Path to the baseline file. **Only acknowledge mode sets it**, and only in Phase
|
|
158
|
-
| `pre_eval:` | Project files Rigor walks before per-file inference — used to register in-project monkey-patches. Leave empty at init; Phase
|
|
159
|
-
| `dependencies.source_inference:` | Opt-in inference for gems shipping no RBS. Leave empty at init; Phase
|
|
182
|
+
| `baseline:` | Path to the baseline file. **Only acknowledge mode sets it**, and only in Phase 7 *after* the file exists. Per Rigor's no-magic rule, a `.rigor-baseline.yml` on disk does nothing until this key names it. |
|
|
183
|
+
| `pre_eval:` | Project files Rigor walks before per-file inference — used to register in-project monkey-patches. Leave empty at init; Phase 6a may add it. |
|
|
184
|
+
| `dependencies.source_inference:` | Opt-in inference for gems shipping no RBS. Leave empty at init; Phase 8 may suggest it. |
|
|
160
185
|
|
|
161
186
|
## Do not write the baseline yet
|
|
162
187
|
|
|
163
188
|
Phase 4 writes the config with the `baseline:` line **commented out
|
|
164
|
-
or absent**. The baseline file does not exist until Phase
|
|
165
|
-
`baseline:` pointing at a missing file is an error. Phase
|
|
189
|
+
or absent**. The baseline file does not exist until Phase 7, and a
|
|
190
|
+
`baseline:` pointing at a missing file is an error. Phase 7 writes
|
|
166
191
|
the file and uncomments / appends the line in one step.
|
|
167
192
|
|
|
168
193
|
Strict mode never adds `baseline:` at all.
|
|
@@ -231,8 +256,8 @@ with the message text.
|
|
|
231
256
|
|
|
232
257
|
## Output of this module
|
|
233
258
|
|
|
234
|
-
A committed `.rigor.dist.yml` with `paths:`, `
|
|
235
|
-
`plugins:`, and `severity_profile:` set — and no active
|
|
259
|
+
A committed `.rigor.dist.yml` with `paths:`, `test_paths:`,
|
|
260
|
+
`exclude:`, `plugins:`, and `severity_profile:` set — and no active
|
|
236
261
|
`baseline:` line. `rigor plugins` reports every entry loaded,
|
|
237
262
|
zero load errors. No Gemfile changes; plugins are bundled inside
|
|
238
263
|
`rigortype`.
|
|
@@ -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)).
|
|
@@ -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
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rigor-type-oracle
|
|
3
|
-
description:
|
|
4
|
-
|
|
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.
|
|
5
7
|
license: MPL-2.0
|
|
6
8
|
metadata:
|
|
7
9
|
version: 0.1.0
|
|
@@ -59,10 +61,6 @@ scope the moment you are about to write or assert one:
|
|
|
59
61
|
- Being asked "what type is this?", "what does this method return?",
|
|
60
62
|
"add types to this class", "document this file".
|
|
61
63
|
|
|
62
|
-
It applies to **Rigor's own tree** as well: `lib/`, the bundled plugins,
|
|
63
|
-
and the examples are held to the same rule, and a gap found there is
|
|
64
|
-
engine signal worth more than the annotation you would have written.
|
|
65
|
-
|
|
66
64
|
## When NOT to use
|
|
67
65
|
|
|
68
66
|
- **Setting Rigor up on a project that has none** → `rigor-next-steps`
|
|
@@ -101,7 +101,7 @@ rigor sig-gen [paths]
|
|
|
101
101
|
| `--overwrite` | Allow a tighter return to replace user-authored RBS. |
|
|
102
102
|
| `--include-private` | Emit private / protected instance methods too (default: public only). |
|
|
103
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 `spec/`
|
|
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
105
|
| `--new-files` / `--new-methods` / `--tighter-returns` | Emit only that classification. |
|
|
106
106
|
| `--format=text\|json` | Text RBS, or the structured candidate report. |
|
|
107
107
|
| `--config=PATH` | Explicit `.rigor.yml`. |
|
|
@@ -133,8 +133,9 @@ skip is a finding. `--format=json` names each one:
|
|
|
133
133
|
"classification": "skipped", "skip_reason": "sig.skipped.untyped-return" }
|
|
134
134
|
```
|
|
135
135
|
|
|
136
|
-
Classifications
|
|
137
|
-
(nothing to tighten;
|
|
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
|
|
138
139
|
each one means for you: [`03-gap-protocol.md`](03-gap-protocol.md).
|
|
139
140
|
|
|
140
141
|
### Deriving a parameter type from call sites
|
|
@@ -215,10 +216,11 @@ a family prefix (`call`, `flow`, `assert`, `dump`, `def`) it prints the
|
|
|
215
216
|
rule's firing conditions, the severity per profile, the evidence tier,
|
|
216
217
|
and how to suppress it.
|
|
217
218
|
|
|
218
|
-
**`explain`
|
|
219
|
-
|
|
220
|
-
sig.skipped.untyped-return` answers
|
|
221
|
-
|
|
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.
|
|
222
224
|
|
|
223
225
|
## `rigor check` — the gate, not the oracle
|
|
224
226
|
|
|
@@ -255,7 +257,9 @@ Two shape differences from the CLI worth knowing:
|
|
|
255
257
|
- `rigor_sig_gen` returns the **JSON candidate report**, always — there
|
|
256
258
|
is no `--print` text mode and no `--diff`. Read `rbs` per candidate.
|
|
257
259
|
- `rigor_sig_gen` exposes `params` but **not** `observe`; observation
|
|
258
|
-
|
|
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`.
|
|
259
263
|
|
|
260
264
|
`rigor_triage` and `rigor_coverage` are also served, and belong to
|
|
261
265
|
`rigor-baseline-reduce` / `rigor-protection-uplift` rather than here.
|
|
@@ -123,6 +123,3 @@ more to the project than any annotation. File it at
|
|
|
123
123
|
Also say `rigor --version`, and note whether `sig/` and the relevant
|
|
124
124
|
plugins were in play — a gap that only appears without community RBS is a
|
|
125
125
|
different bug from one that survives it.
|
|
126
|
-
|
|
127
|
-
Inside Rigor's own tree the same report is the deliverable: the gap is
|
|
128
|
-
the reason not to hand-write the RBS there.
|
|
@@ -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
|
|
@@ -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
|
|