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-ci-setup
|
|
3
|
-
description:
|
|
4
|
-
|
|
3
|
+
description: >-
|
|
4
|
+
Set up Rigor in a project's CI and surface diagnostics on pull or merge requests. Use when adding or
|
|
5
|
+
changing GitHub Actions, GitLab CI, SARIF, or reviewdog wiring; not for first-time Rigor configuration
|
|
6
|
+
or baseline reduction.
|
|
5
7
|
license: MPL-2.0
|
|
6
8
|
metadata:
|
|
7
9
|
version: 0.1.0
|
|
@@ -31,7 +33,6 @@ Rigor is installed:
|
|
|
31
33
|
```sh
|
|
32
34
|
rigor skill --full rigor-ci-setup # this skill's current workflow, in one call
|
|
33
35
|
rigor docs ci # the manual's CI chapter — the actual templates
|
|
34
|
-
rigor docs --list manual | grep ci-templates # ready-to-copy template files
|
|
35
36
|
```
|
|
36
37
|
|
|
37
38
|
If you already loaded this skill *via* `rigor skill` you have the current
|
|
@@ -61,7 +62,7 @@ these markers from the project root and let them drive the platform choice:
|
|
|
61
62
|
| `bitbucket-pipelines.yml` / `azure-pipelines.yml` / `.drone.yml` | that platform (generic recipe) |
|
|
62
63
|
| none of the above | no CI yet — **ask** the user which platform they use |
|
|
63
64
|
|
|
64
|
-
Concretely
|
|
65
|
+
Concretely:
|
|
65
66
|
|
|
66
67
|
- List `.github/workflows/*.yml` and `.gitlab-ci.yml`. **If
|
|
67
68
|
`.github/workflows/rigor.yml` already exists, read it** — this is an
|
|
@@ -108,10 +109,8 @@ this is the *decision*:
|
|
|
108
109
|
## Phase 2 — Apply the matching template
|
|
109
110
|
|
|
110
111
|
Take the template for your (platform, surface) choice from `rigor docs ci`
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
in, adjust nothing but the trigger unless asked, and pin the version next
|
|
114
|
-
(Phase 3).
|
|
112
|
+
(GitHub annotations / SARIF / reviewdog, and GitLab). Copy it in, adjust
|
|
113
|
+
nothing but the trigger unless asked, and pin the version next (Phase 3).
|
|
115
114
|
|
|
116
115
|
**reviewdog is platform-specific.** It reads Rigor's `checkstyle`
|
|
117
116
|
(preferred — light, no code scanning) or `sarif`, but the `-reporter` must
|
|
@@ -142,14 +141,11 @@ The exact recipe (the `BUNDLE_GEMFILE` wiring, the Dependabot entry) is in
|
|
|
142
141
|
- **Determinism.** Add `--no-cache` in CI if you want each run independent
|
|
143
142
|
of any persisted `.rigor/cache`.
|
|
144
143
|
- **Cache persistence (opposite trade).** When the Rigor job's runtime
|
|
145
|
-
matters, persist `.rigor/cache` with the CI's cache facility.
|
|
146
|
-
|
|
147
|
-
automatically (`cache.validation: auto`)
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
watch-glob cache slots read as stale on every run. A self-hosted
|
|
151
|
-
runner that reuses its workspace opts back into the faster stat check
|
|
152
|
-
with `cache.validation: stat`. Snippets: `rigor docs ci`
|
|
144
|
+
matters, persist `.rigor/cache` with the CI's cache facility. Rigor
|
|
145
|
+
detects CI and validates the restored cache by content hash
|
|
146
|
+
automatically (`cache.validation: auto`). A self-hosted runner that
|
|
147
|
+
reuses its workspace opts back into the faster stat check with
|
|
148
|
+
`cache.validation: stat`. Snippets: `rigor docs ci`
|
|
153
149
|
§ "Persisting the analysis cache across runs".
|
|
154
150
|
|
|
155
151
|
## Verify
|
|
@@ -165,12 +161,12 @@ The exact recipe (the `BUNDLE_GEMFILE` wiring, the Dependabot entry) is in
|
|
|
165
161
|
|
|
166
162
|
- Manual: `rigor`'s CI chapter — the authoritative templates, severity
|
|
167
163
|
mapping, and pinning recipe, **offline and version-matched** with
|
|
168
|
-
`rigor docs ci
|
|
169
|
-
ci
|
|
170
|
-
|
|
171
|
-
- [ADR-51](
|
|
164
|
+
`rigor docs ci`. Web fallback, before Rigor is installed:
|
|
165
|
+
<https://github.com/rigortype/rigor/blob/master/docs/manual/11-ci.md>
|
|
166
|
+
(ready-to-copy files in `docs/manual/ci-templates/` beside it).
|
|
167
|
+
- [ADR-51](https://github.com/rigortype/rigor/blob/master/docs/adr/51-ci-diagnostic-output-formats.md)
|
|
172
168
|
— the output-format surface (the severity / identifier contract).
|
|
173
|
-
- [ADR-27](
|
|
169
|
+
- [ADR-27](https://github.com/rigortype/rigor/blob/master/docs/adr/27-tool-distribution-model.md)
|
|
174
170
|
— why Rigor installs standalone and runs in its own job.
|
|
175
171
|
- [reviewdog](https://github.com/reviewdog/reviewdog) /
|
|
176
172
|
[action-setup](https://github.com/reviewdog/action-setup).
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rigor-doctor
|
|
3
|
-
description:
|
|
4
|
-
Validate that a project's Rigor
|
|
3
|
+
description: >-
|
|
4
|
+
Validate that a project's Rigor configuration, plugins, paths, and baseline are actually healthy. Use
|
|
5
|
+
when diagnostics are suspicious or setup behavior is wrong; not for first-time onboarding or reducing
|
|
6
|
+
ordinary diagnostics.
|
|
5
7
|
license: MPL-2.0
|
|
6
8
|
metadata:
|
|
7
9
|
version: 0.1.0
|
|
@@ -11,12 +13,13 @@ metadata:
|
|
|
11
13
|
# Rigor Doctor
|
|
12
14
|
|
|
13
15
|
`rigor skill describe` reports what *exists* (presence checks). This skill
|
|
14
|
-
goes a level deeper:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
goes a level deeper: `rigor doctor` *runs* Rigor's own setup validators
|
|
17
|
+
(config audit, RBS environment, plugin loading, baseline drift, plugin
|
|
18
|
+
gaps, install layout) and this skill interprets the result — the
|
|
19
|
+
difference between "a `.rigor.yml` is present" and "it parses, loads its
|
|
20
|
+
plugins, and analyses the right files." Reach for it when the diagnostics
|
|
21
|
+
look wrong (suspiciously zero, or suspiciously many) or after editing the
|
|
22
|
+
config.
|
|
20
23
|
|
|
21
24
|
## First: load the version-current copy
|
|
22
25
|
|
|
@@ -44,25 +47,24 @@ header names). If `rigor` is not on `PATH`, this task needs it: run
|
|
|
44
47
|
|
|
45
48
|
## What it validates
|
|
46
49
|
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
`rigor doctor` runs the setup checks in one pass (`--format json` gives
|
|
51
|
+
each finding's `checks[].id` and `status`) and exits non-zero when any
|
|
52
|
+
check fails. It does not check whether the analysis sees the right
|
|
53
|
+
files; that is a separate look at `stats.target_files` in
|
|
54
|
+
`rigor check --format json`. What each check id means and how to act on
|
|
55
|
+
it live in the version-current
|
|
49
56
|
[`references/01-checks.md`](references/01-checks.md) (loaded per the
|
|
50
|
-
directive above)
|
|
51
|
-
|
|
52
|
-
1. **Config resolves with nothing silently inert** — no `config_warnings`.
|
|
53
|
-
2. **Every configured plugin loads** — `rigor plugins --strict` is clean.
|
|
54
|
-
3. **The baseline is not stale** (if one exists) — no large drift.
|
|
55
|
-
4. **The analysis is actually seeing your code** — the source-file count
|
|
56
|
-
matches the project.
|
|
57
|
+
directive above).
|
|
57
58
|
|
|
58
59
|
## Interpreting the result
|
|
59
60
|
|
|
60
|
-
- **All clean**
|
|
61
|
-
|
|
61
|
+
- **All clean** (no `fail` or `warn` finding, and the file count matches
|
|
62
|
+
the project) → the setup is healthy; any diagnostics are about the code,
|
|
63
|
+
not the configuration. Move on to `rigor-baseline-reduce` or
|
|
62
64
|
`rigor-protection-uplift`.
|
|
63
|
-
- **A `
|
|
64
|
-
fixing it usually clears a whole cluster of confusing
|
|
65
|
-
diagnostics at once.
|
|
65
|
+
- **A `config_audit`, `rbs_environment`, or `plugins` failure** → that is
|
|
66
|
+
the real problem; fixing it usually clears a whole cluster of confusing
|
|
67
|
+
downstream diagnostics at once.
|
|
66
68
|
|
|
67
69
|
For deeper symptoms (hover shows `untyped` everywhere, completion empty,
|
|
68
70
|
LSP silent) read the manual's troubleshooting chapter — offline and
|
|
@@ -1,52 +1,116 @@
|
|
|
1
|
-
# 01 — The
|
|
1
|
+
# 01 — The checks
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
output. Run them in order; the first failure is usually the root cause of
|
|
5
|
-
a cluster of confusing downstream diagnostics.
|
|
6
|
-
|
|
7
|
-
## 1. Config resolves with nothing silently inert
|
|
3
|
+
## Run `rigor doctor`
|
|
8
4
|
|
|
9
5
|
```sh
|
|
10
|
-
rigor
|
|
6
|
+
rigor doctor # human-readable: [FAIL] / [WARN] / [PASS] lines
|
|
7
|
+
rigor doctor --format json # machine-readable
|
|
11
8
|
```
|
|
12
9
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
(which would turn every covered call into a false `call.undefined-method`
|
|
17
|
-
at `evidence_tier: high`), a `libraries:` name RBS does not recognise, a
|
|
18
|
-
`disable:` / `severity_overrides:` id naming no real rule, or a missing
|
|
19
|
-
`bundler` / `rbs_collection` path. **Each warning here is a real
|
|
20
|
-
misconfiguration — fix it.** None appearing is the healthy state.
|
|
21
|
-
|
|
22
|
-
## 2. Every configured plugin loads
|
|
10
|
+
It runs one scoped analysis, audits the config, loads the plugins, and
|
|
11
|
+
checks baseline drift in a single pass, then prints a finding per
|
|
12
|
+
problem with a hint. The JSON shape:
|
|
23
13
|
|
|
24
|
-
```
|
|
25
|
-
|
|
14
|
+
```json
|
|
15
|
+
{ "status": "issues_found",
|
|
16
|
+
"checks": [ { "id": "plugins", "status": "fail",
|
|
17
|
+
"message": "Plugin load errors: 1",
|
|
18
|
+
"hint": "Run `rigor plugins --strict` for the full per-plugin report." } ] }
|
|
26
19
|
```
|
|
27
20
|
|
|
28
|
-
|
|
29
|
-
|
|
21
|
+
- Top-level `status` is `issues_found` when any check has `status: "fail"`,
|
|
22
|
+
otherwise `clean` — a run with only `warn` findings still reads `clean`,
|
|
23
|
+
so read the `checks` array too.
|
|
24
|
+
- `checks[].status` is `fail`, `warn`, or `pass`. A check with nothing to
|
|
25
|
+
report is usually **absent**, not `pass`; only `rbs_environment` reports
|
|
26
|
+
a `pass` line.
|
|
27
|
+
- The command exits non-zero when any check fails.
|
|
28
|
+
|
|
29
|
+
Fix `fail` findings first, in the order below: an early failure is usually
|
|
30
|
+
the root cause of a cluster of confusing downstream diagnostics.
|
|
31
|
+
|
|
32
|
+
## The check ids
|
|
33
|
+
|
|
34
|
+
### `config_audit` — config resolves with nothing silently inert
|
|
35
|
+
|
|
36
|
+
`fail` with a count of configuration warnings. Doctor gives only the
|
|
37
|
+
count; the individual warnings are in `rigor check --format json` under
|
|
38
|
+
`config_warnings`. They cover the typo class whose only symptom is a
|
|
39
|
+
confusing downstream error: a `signature_paths:` that is missing / not a
|
|
40
|
+
directory / holds no `.rbs` (which would turn every covered call into a
|
|
41
|
+
false `call.undefined-method` at `evidence_tier: high`), a `libraries:`
|
|
42
|
+
name RBS does not recognise, a `disable:` / `severity_overrides:` id
|
|
43
|
+
naming no real rule, or a missing `bundler` / `rbs_collection` path.
|
|
44
|
+
**Each warning is a real misconfiguration — fix it.**
|
|
45
|
+
|
|
46
|
+
### `rbs_environment` — the type universe loaded
|
|
47
|
+
|
|
48
|
+
- `fail` — the RBS environment is empty (zero classes). It failed to build
|
|
49
|
+
or loaded no signatures: look for duplicate declarations across
|
|
50
|
+
`signature_paths:`, or run `rbs collection install` for gem signatures.
|
|
51
|
+
- `warn` — degraded: one or more `signature_paths:` files did not parse
|
|
52
|
+
and were skipped. The run is quieter, not cleaner — the types those
|
|
53
|
+
files declare are gone. Run `rbs validate` on the `sig/` set and fix
|
|
54
|
+
the parse error.
|
|
55
|
+
- `pass` — healthy, with the class count.
|
|
56
|
+
|
|
57
|
+
### `plugins` — every configured plugin loads
|
|
58
|
+
|
|
59
|
+
`fail` with a count of plugin load errors. Run `rigor plugins --strict`
|
|
60
|
+
for the per-plugin report. A failure is usually a misspelled id or a
|
|
30
61
|
plugin whose `signature_paths:` did not resolve. Fix it, or the plugin's
|
|
31
62
|
type knowledge is silently absent.
|
|
32
63
|
|
|
33
|
-
|
|
64
|
+
### `plugin_skew` — a bundled plugin came from another installation
|
|
34
65
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
66
|
+
`warn` when a bundled plugin was loaded from a different `rigortype`
|
|
67
|
+
installation than the engine. The engine and its bundled plugins are
|
|
68
|
+
versioned together, so a mismatched copy can produce wrong diagnostics.
|
|
69
|
+
Make sure a single `rigortype` is on the load path.
|
|
70
|
+
|
|
71
|
+
### `baseline` — the baseline is not stale (if one exists)
|
|
72
|
+
|
|
73
|
+
- `fail` — drift: some baseline buckets are over their recorded count,
|
|
74
|
+
cleared, or reducible. The hint is `rigor baseline regenerate`; before
|
|
75
|
+
regenerating, run `rigor baseline drift` to see which buckets moved, so
|
|
76
|
+
a regeneration does not bury a new catch (often after an upgrade — see
|
|
77
|
+
`rigor-upgrade`).
|
|
78
|
+
- `warn` — the baseline file failed to load. Check the `baseline:` path
|
|
79
|
+
in the config.
|
|
80
|
+
|
|
81
|
+
### `plugin_gap` — the stack has a plugin that is not enabled
|
|
82
|
+
|
|
83
|
+
Read from the `DEPENDENCIES` section of `Gemfile.lock`.
|
|
84
|
+
|
|
85
|
+
- `fail` — the project depends on gems that bundled plugins model, and
|
|
86
|
+
**none** of those plugins is enabled: framework calls will not resolve.
|
|
87
|
+
Add the plugins for the stack to `plugins:` (the `rigor-plugin-tune`
|
|
88
|
+
skill does this).
|
|
89
|
+
- `warn` — one per plugin that models a direct dependency but is not
|
|
90
|
+
enabled. Enable it, or leave it out deliberately; declining a plugin is
|
|
91
|
+
a legitimate choice.
|
|
92
|
+
|
|
93
|
+
### `gemfile_install` — Rigor is a project dependency
|
|
94
|
+
|
|
95
|
+
`fail` when `rigortype` is resolved from a gem source in the project's
|
|
96
|
+
`Gemfile.lock`. Rigor is a tool, not a library: remove it from the
|
|
97
|
+
`Gemfile` and install it standalone (`rigor docs manual/01-installation`).
|
|
98
|
+
|
|
99
|
+
### `bundle_layout` — gem-shipped signatures are not discovered
|
|
38
100
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
101
|
+
`warn` when a `Gemfile.lock` exists but Rigor cannot locate the installed
|
|
102
|
+
bundle (the gems live in the active Ruby's default gem home). Gems that
|
|
103
|
+
ship their own `sig/` are then not loaded. Point Rigor at the install
|
|
104
|
+
root with `bundler.bundle_path:`, install into `vendor/bundle`, or supply
|
|
105
|
+
signatures with `rbs collection install` instead.
|
|
43
106
|
|
|
44
|
-
##
|
|
107
|
+
## Not covered by `rigor doctor`: is the analysis seeing your code?
|
|
45
108
|
|
|
46
109
|
```sh
|
|
47
|
-
rigor check --format json
|
|
110
|
+
rigor check --no-cache --format json | jq '.stats.target_files'
|
|
48
111
|
```
|
|
49
112
|
|
|
50
|
-
|
|
51
|
-
`
|
|
113
|
+
`--no-cache` matters: a result served from the run cache carries no
|
|
114
|
+
`stats`. If the file count is `0` or far below your project size, `paths:`
|
|
115
|
+
/ `exclude:` are mis-scoped, or the command is running from the wrong
|
|
52
116
|
directory. The analysis is only as good as the files it reads.
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rigor-editor-setup
|
|
3
|
-
description:
|
|
4
|
-
|
|
3
|
+
description: >-
|
|
4
|
+
Set up Rigor's bundled language server for live diagnostics, hover, outline, and completion in a
|
|
5
|
+
developer's editor. Use when wiring `rigor lsp` into VS Code, Neovim, Helix, Emacs, or another LSP
|
|
6
|
+
client; not for CI or first-time project setup.
|
|
5
7
|
license: MPL-2.0
|
|
6
8
|
metadata:
|
|
7
9
|
version: 0.1.0
|
|
@@ -24,7 +26,7 @@ rigor docs editor-integration
|
|
|
24
26
|
```
|
|
25
27
|
|
|
26
28
|
(Web fallback, only before Rigor is installed:
|
|
27
|
-
**[Rigor LSP — Editor Integration](
|
|
29
|
+
**[Rigor LSP — Editor Integration](https://github.com/rigortype/rigor/blob/master/docs/manual/09-editor-integration.md)**.)
|
|
28
30
|
This skill is the *workflow* around it (identify the editor → apply the
|
|
29
31
|
manual's snippet → verify), so it does not duplicate (and cannot
|
|
30
32
|
stale-out) the config details.
|
|
@@ -62,7 +64,7 @@ Every editor snippet simply launches **`rigor lsp`** (stdio) and needs
|
|
|
62
64
|
**`rigor` on the editor's `PATH`** — the same executable `rigor check`
|
|
63
65
|
uses. For GUI editors that do not inherit your shell, the `mise` shim
|
|
64
66
|
path is the most reliable channel (see `rigor docs install`, or
|
|
65
|
-
[Installing Rigor](
|
|
67
|
+
[Installing Rigor](https://github.com/rigortype/rigor/blob/master/docs/install.md)
|
|
66
68
|
on the web). Do **not** add `rigortype` to the project's `Gemfile` — it
|
|
67
69
|
is a tool, not a library.
|
|
68
70
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rigor-mcp-setup
|
|
3
|
-
description:
|
|
4
|
-
|
|
3
|
+
description: >-
|
|
4
|
+
Set up Rigor's bundled MCP server for an AI coding agent and verify the connection. Use when wiring
|
|
5
|
+
`rigor mcp` into Claude Code, Cursor, Cline, or another MCP client; not for editor LSP or CI setup.
|
|
5
6
|
license: MPL-2.0
|
|
6
7
|
metadata:
|
|
7
8
|
version: 0.1.0
|
|
@@ -26,7 +27,7 @@ rigor docs mcp-server
|
|
|
26
27
|
```
|
|
27
28
|
|
|
28
29
|
(Web fallback, only before Rigor is installed:
|
|
29
|
-
**[Rigor MCP Server — AI Agent Integration](
|
|
30
|
+
**[Rigor MCP Server — AI Agent Integration](https://github.com/rigortype/rigor/blob/master/docs/manual/10-mcp-server.md)**.)
|
|
30
31
|
This skill is the *workflow* around it (identify the client → apply the
|
|
31
32
|
manual's snippet → verify the handshake), so it does not duplicate (and
|
|
32
33
|
cannot stale-out) the config details.
|
|
@@ -70,7 +71,7 @@ Every client config simply launches **`rigor mcp`** (stdio) and needs
|
|
|
70
71
|
**`rigor` on the agent's `PATH`** — the same executable `rigor check`
|
|
71
72
|
uses. For agents that do not inherit your shell, the `mise` shim path is
|
|
72
73
|
the most reliable channel (see `rigor docs install`, or
|
|
73
|
-
[Installing Rigor](
|
|
74
|
+
[Installing Rigor](https://github.com/rigortype/rigor/blob/master/docs/install.md)
|
|
74
75
|
on the web). Do **not** add `rigortype` to the project's `Gemfile` — it
|
|
75
76
|
is a tool, not a library.
|
|
76
77
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rigor-monkeypatch-resolve
|
|
3
|
-
description:
|
|
4
|
-
Resolve
|
|
3
|
+
description: >-
|
|
4
|
+
Resolve Rigor diagnostics caused by literal `def` methods in a project's own monkey-patches by wiring
|
|
5
|
+
their files into `pre_eval:`. Use when project core extensions cause undefined-method findings; not for
|
|
6
|
+
dynamic method generation or an external gem without RBS.
|
|
5
7
|
license: MPL-2.0
|
|
6
8
|
metadata:
|
|
7
9
|
version: 0.1.0
|
|
@@ -14,7 +16,7 @@ When a project adds methods to existing classes in its own files — the
|
|
|
14
16
|
classic `lib/core_ext/*.rb` `class String; def squish; …; end` pattern —
|
|
15
17
|
Rigor does not see them unless told to, so every call to the added method
|
|
16
18
|
fires `call.undefined-method` (or `call.unresolved-toplevel` for a
|
|
17
|
-
top-level helper). `pre_eval:` ([ADR-17](
|
|
19
|
+
top-level helper). `pre_eval:` ([ADR-17](https://github.com/rigortype/rigor/blob/master/docs/adr/17-monkey-patch-pre-evaluation.md))
|
|
18
20
|
fixes this: it pre-evaluates the listed project files and registers every
|
|
19
21
|
method they define with a **literal** `def` / `def self.`.
|
|
20
22
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rigor-next-steps
|
|
3
|
-
description:
|
|
4
|
-
Route a project to its next Rigor step
|
|
3
|
+
description: >-
|
|
4
|
+
Route a project to its next Rigor step, installing or onboarding Rigor when needed and then delegating
|
|
5
|
+
to `rigor skill describe`. Use when the user asks where to start or what to do next with Rigor; not
|
|
6
|
+
instead of a task-specific skill the route selects.
|
|
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-plugin-author
|
|
3
|
-
description:
|
|
4
|
-
Author a Rigor plugin in
|
|
3
|
+
description: >-
|
|
4
|
+
Author a Rigor plugin in an adopting project or standalone `rigor-*` gem for a DSL, framework, or
|
|
5
|
+
metaprogramming pattern. Use when Rigor needs project-specific extension support; not for onboarding a
|
|
6
|
+
project, reducing a baseline, or editing Rigor's bundled plugins.
|
|
5
7
|
license: MPL-2.0
|
|
6
8
|
metadata:
|
|
7
9
|
version: 0.1.0
|
|
@@ -43,21 +45,20 @@ If you already loaded this skill *via* `rigor skill` you have the current
|
|
|
43
45
|
copy — just proceed. If the `rigor` command is not available, run
|
|
44
46
|
**`rigor-next-steps`** to install Rigor first, then come back.
|
|
45
47
|
|
|
46
|
-
##
|
|
48
|
+
## The plugin contract is pre-1.0
|
|
47
49
|
|
|
48
|
-
Rigor's plugin contract (ADR-2)
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
Rigor's plugin contract (ADR-2) freezes at `rigortype` v1.0.0. Until
|
|
51
|
+
then, treat each `rigortype` minor release as potentially
|
|
52
|
+
contract-changing:
|
|
51
53
|
|
|
52
|
-
- **Pin `rigortype`
|
|
53
|
-
or Gemfile
|
|
54
|
-
- Expect to **revisit your plugin** when you
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
- After v0.2.0 the contract is stable and ordinary semver applies.
|
|
54
|
+
- **Pin `rigortype` to the minor you built against** — `"~> X.Y.0"`
|
|
55
|
+
in your gemspec or Gemfile, where `X.Y` comes from `rigor --version`.
|
|
56
|
+
- Expect to **revisit your plugin** when you move to the next minor.
|
|
57
|
+
The node-rule block signature, the `Diagnostic` shape, and the type
|
|
58
|
+
carriers may shift.
|
|
58
59
|
|
|
59
|
-
Tell the user this up front
|
|
60
|
-
|
|
60
|
+
Tell the user this up front: a plugin written today is valuable but
|
|
61
|
+
not yet on a frozen foundation.
|
|
61
62
|
|
|
62
63
|
## Read a real plugin — `rigor plugin`
|
|
63
64
|
|
|
@@ -114,14 +115,9 @@ AST walk per file — hands every matching node to the block along with a
|
|
|
114
115
|
`Rigor::Analysis::Diagnostic` (built via the `diagnostic` helper).
|
|
115
116
|
Optionally the plugin also declares `dynamic_return(receivers:)` /
|
|
116
117
|
`narrowing_facts(methods:)` to *supply* a return type or narrowing facts
|
|
117
|
-
for call sites the core analyzer types as `Dynamic`.
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
`#diagnostics_for_file`
|
|
121
|
-
is the file-rule surface for whole-file diagnostics a per-node walk can't
|
|
122
|
-
express. (`flow_contribution_for` was removed pre-1.0 in ADR-52 WD3 —
|
|
123
|
-
defining it now raises `ArgumentError`; use `dynamic_return` /
|
|
124
|
-
`narrowing_facts`. See Phase 2.)
|
|
118
|
+
for call sites the core analyzer types as `Dynamic`.
|
|
119
|
+
`#diagnostics_for_file` is the file-rule surface for whole-file
|
|
120
|
+
diagnostics a per-node walk can't express. See Phase 2.
|
|
125
121
|
|
|
126
122
|
## Phase outline
|
|
127
123
|
|
|
@@ -136,5 +132,5 @@ defining it now raises `ArgumentError`; use `dynamic_return` /
|
|
|
136
132
|
| Module | Read | Covers |
|
|
137
133
|
| --- | --- | --- |
|
|
138
134
|
| 1 | [`references/01-plan-and-scaffold.md`](references/01-plan-and-scaffold.md) | **Phase 1.** The gem vs project-private packaging split, directory trees for both, gemspec template, project-private path-gem / `RUBYLIB` activation, the `Rigor::Plugin::Base` skeleton, `.rigor.yml` `plugins:` wiring. |
|
|
139
|
-
| 2 | [`references/02-walker-and-types.md`](references/02-walker-and-types.md) | **Phase 2.** The `node_rule` engine-owned AST walk over Prism nodes, the `Base#diagnostic` helper, asking the analyzer for inferred types via `scope.type_of`, two-pass / lexical context (`node_file_context` / `NodeContext`), the optional `dynamic_return` / `narrowing_facts` return-type hooks
|
|
135
|
+
| 2 | [`references/02-walker-and-types.md`](references/02-walker-and-types.md) | **Phase 2.** The `node_rule` engine-owned AST walk over Prism nodes, the `Base#diagnostic` helper, asking the analyzer for inferred types via `scope.type_of`, two-pass / lexical context (`node_file_context` / `NodeContext`), the optional `dynamic_return` / `narrowing_facts` return-type hooks, calling the target library's pure methods directly rather than reimplementing them (ADR-39: `Plugin::Inflector` over the real `ActiveSupport::Inflector`; `Base.suggest` for did-you-mean), and shipping `sig/*.rbs` so the DSL's types are visible. |
|
|
140
136
|
| 3 | [`references/03-test-and-ship.md`](references/03-test-and-ship.md) | **Phase 3.** Testing a plugin from outside the monorepo — fixture projects driven through `rigor check --format json`, plus pure unit tests of dispatch tables — with RSpec or Minitest. Version pinning against the pre-1.0 contract. README. Publishing to RubyGems or keeping the plugin private. |
|
|
@@ -52,8 +52,9 @@ Gem::Specification.new do |spec|
|
|
|
52
52
|
spec.require_paths = ["lib"]
|
|
53
53
|
|
|
54
54
|
spec.add_dependency "prism", ">= 1.0", "< 2.0"
|
|
55
|
-
# Pin
|
|
56
|
-
|
|
55
|
+
# Pin to the minor you built against — the contract is pre-1.0
|
|
56
|
+
# (see SKILL.md). X.Y comes from `rigor --version`.
|
|
57
|
+
spec.add_dependency "rigortype", "~> X.Y.0"
|
|
57
58
|
end
|
|
58
59
|
```
|
|
59
60
|
|
|
@@ -131,7 +132,7 @@ your-app/
|
|
|
131
132
|
|
|
132
133
|
```ruby
|
|
133
134
|
# your-app/Gemfile
|
|
134
|
-
gem "rigortype", "~>
|
|
135
|
+
gem "rigortype", "~> X.Y.0" # the minor you built against
|
|
135
136
|
gem "rigor-myapp", path: "rigor-plugin"
|
|
136
137
|
```
|
|
137
138
|
|
|
@@ -172,16 +173,16 @@ module Rigor
|
|
|
172
173
|
# Optional: declare config keys the user may set under
|
|
173
174
|
# `.rigor.yml` plugins: [{ gem:, config: { … } }].
|
|
174
175
|
config_schema: {
|
|
175
|
-
|
|
176
|
-
# "rules"
|
|
176
|
+
"module_name" => { kind: :string, default: "Default" }
|
|
177
|
+
# "rules" => :array,
|
|
177
178
|
}
|
|
178
179
|
)
|
|
179
180
|
|
|
180
181
|
# Called once at load time with the service container.
|
|
181
|
-
#
|
|
182
|
-
#
|
|
182
|
+
# `config` is the validated user config Hash, with declared
|
|
183
|
+
# defaults merged beneath it.
|
|
183
184
|
def init(_services)
|
|
184
|
-
@module_name = config
|
|
185
|
+
@module_name = config["module_name"]
|
|
185
186
|
end
|
|
186
187
|
|
|
187
188
|
# The engine owns the AST walk and hands every matching node to
|
|
@@ -165,20 +165,14 @@ Rigor::Plugin::Base.suggest(typo, known_names) # nearest match, or nil
|
|
|
165
165
|
|
|
166
166
|
## Optional — contribute a return type with `dynamic_return` / `narrowing_facts`
|
|
167
167
|
|
|
168
|
-
> **
|
|
169
|
-
>
|
|
170
|
-
>
|
|
171
|
-
>
|
|
172
|
-
>
|
|
173
|
-
>
|
|
174
|
-
>
|
|
175
|
-
>
|
|
176
|
-
> cluster on a DSL-generated method (the common reason
|
|
177
|
-
> `rigor-project-init` hands off to this skill), the fix is to make the
|
|
178
|
-
> method *exist* in Rigor's view — ship RBS declaring it (see "Shipping
|
|
179
|
-
> RBS for the DSL" below), not a return-type contribution.** Reach for
|
|
180
|
-
> these only when the call already resolves and you want a *better
|
|
181
|
-
> return type*.
|
|
168
|
+
> **Prefer RBS to make a DSL method exist.** A `dynamic_return` answer
|
|
169
|
+
> suppresses `call.undefined-method` only at the call sites where the
|
|
170
|
+
> rule fires (its gated receiver kind and methods); RBS makes the method
|
|
171
|
+
> defined for all of core inference — arity, argument types, every call
|
|
172
|
+
> site. To clear a `call.undefined-method` cluster on DSL-generated
|
|
173
|
+
> methods (the common reason `rigor-project-init` hands off to this
|
|
174
|
+
> skill), ship RBS (see "Shipping RBS for the DSL" below). Reach for
|
|
175
|
+
> these hooks when you want a better *return type* for a call.
|
|
182
176
|
|
|
183
177
|
A plugin can do more than emit diagnostics: it can *supply* the
|
|
184
178
|
inferred return type (or narrowing facts) for a call site the core
|
|
@@ -213,10 +207,6 @@ narrowing_facts methods: [:assert_kind_of] do |call_node, scope|
|
|
|
213
207
|
end
|
|
214
208
|
```
|
|
215
209
|
|
|
216
|
-
> **`narrowing_facts` was renamed from `type_specifier` in ADR-80.**
|
|
217
|
-
> The old verb was removed in 0.3.0 — `narrowing_facts` is the only
|
|
218
|
-
> spelling a plugin can declare.
|
|
219
|
-
|
|
220
210
|
Build return types with `Rigor::Type::Combinator`:
|
|
221
211
|
|
|
222
212
|
```ruby
|
|
@@ -233,12 +223,9 @@ plugin is confident; a wrong contribution propagates downstream.
|
|
|
233
223
|
`rigor plugins --capabilities` catalogue enumerates — run it to see
|
|
234
224
|
exactly what each loaded plugin contributes.
|
|
235
225
|
|
|
236
|
-
> **
|
|
237
|
-
>
|
|
238
|
-
>
|
|
239
|
-
> expressed by `dynamic_return`'s callable gates: a **method-gated return
|
|
240
|
-
> type** (an RSpec `let(:x) { … }` binding, a Sorbet `sig`-driven return —
|
|
241
|
-
> keyed on the method, not a fixed receiver class) uses
|
|
226
|
+
> **Callable gates.** A **method-gated return type** (an RSpec
|
|
227
|
+
> `let(:x) { … }` binding, a Sorbet `sig`-driven return — keyed on the
|
|
228
|
+
> method, not a fixed receiver class) uses
|
|
242
229
|
> `dynamic_return methods: -> { [...] }` or `file_methods: ->(path) { [...] }`;
|
|
243
230
|
> a **dynamic per-project receiver set** (ActiveStorage's `Attached::One`
|
|
244
231
|
> on discovered model classes) uses `dynamic_return receivers: -> { [...] }`,
|
|
@@ -247,7 +234,7 @@ exactly what each loaded plugin contributes.
|
|
|
247
234
|
> if the plugin genuinely needs to sharpen call-site types; a
|
|
248
235
|
> diagnostics-only plugin skips them entirely.
|
|
249
236
|
|
|
250
|
-
## Shipping RBS for the DSL —
|
|
237
|
+
## Shipping RBS for the DSL — making DSL methods exist
|
|
251
238
|
|
|
252
239
|
If the DSL introduces methods or classes that Rigor cannot see (a
|
|
253
240
|
`Money` class defined by metaprogramming, `Setting.<name>` accessors a
|
|
@@ -106,11 +106,12 @@ CLI tests for the end-to-end wiring.
|
|
|
106
106
|
|
|
107
107
|
## Version pinning — the pre-1.0 contract
|
|
108
108
|
|
|
109
|
-
The plugin contract is **not frozen until `rigortype`
|
|
109
|
+
The plugin contract is **not frozen until `rigortype` v1.0.0** (see
|
|
110
110
|
SKILL.md). Concretely:
|
|
111
111
|
|
|
112
|
-
- Gemspec / Gemfile: `rigortype`
|
|
113
|
-
|
|
112
|
+
- Gemspec / Gemfile: `rigortype` `~> X.Y.0` for the minor you tested
|
|
113
|
+
(`rigor --version`). Never an open `>=` range — that floats across
|
|
114
|
+
contract-changing minors.
|
|
114
115
|
- Your plugin's own version is normal semver, independent of
|
|
115
116
|
`rigortype`'s.
|
|
116
117
|
- When you bump the `rigortype` pin to a new minor, **re-run the
|
|
@@ -120,9 +121,6 @@ SKILL.md). Concretely:
|
|
|
120
121
|
- State the supported `rigortype` range in the README so users do
|
|
121
122
|
not pair the plugin with an incompatible Rigor.
|
|
122
123
|
|
|
123
|
-
When v0.2.0 lands, re-pin to the stable range and ordinary
|
|
124
|
-
compatibility rules apply.
|
|
125
|
-
|
|
126
124
|
## README
|
|
127
125
|
|
|
128
126
|
A plugin README should carry:
|
|
@@ -151,13 +149,13 @@ wired and the fixture tests run.
|
|
|
151
149
|
Either way, if the plugin uncovered a gap that *should* be core
|
|
152
150
|
Rigor behaviour — or if you hit a plugin-contract rough edge — report
|
|
153
151
|
it: <https://github.com/rigortype/rigor/issues>. External plugin
|
|
154
|
-
authors are the main source of
|
|
152
|
+
authors are the main source of contract feedback before v1.0.
|
|
155
153
|
|
|
156
154
|
## Output of this module — plugin shipped
|
|
157
155
|
|
|
158
156
|
- A test suite: fast unit tests + fixture-driven `rigor check`
|
|
159
157
|
tests, in RSpec or Minitest.
|
|
160
|
-
- A `rigortype` pin tight to
|
|
158
|
+
- A `rigortype` pin tight to the tested minor.
|
|
161
159
|
- A README stating the compatibility range.
|
|
162
160
|
- The plugin published as a gem, or committed project-private with
|
|
163
161
|
CI wired.
|