Module: Rigor::Configuration::SeverityProfile

Defined in:
lib/rigor/configuration/severity_profile.rb

Overview

ADR-8 § “Severity profile” — three named profiles tune the severity of every built-in ‘Analysis::CheckRules` rule for the run. Profiles are applied as a **final filter** on `Diagnostic#severity`: rules emit with their authored severity, then `Analysis::Runner` re-stamps the severity from the active profile before adding the diagnostic to the result.

Three profiles:

  • ‘lenient`: Only proven (`:no`) diagnostics are errors; uncertain (`:maybe`) drop to `:warning`. Useful for incremental adoption on legacy code.

  • ‘balanced` (default): Current Rigor stance — most rules `:error`; `dump.type` `:info`; uncertain rules `:warning`.

  • ‘strict`: Every rule is `:error`. CI-friendly.

The profile resolution order:

  1. Profile-specific entry for the canonical rule id.

  2. The diagnostic’s own authored severity (the rule’s default).

  3. ‘:error` (catch-all so an unrecognised rule still emits visibly — the public-API drift spec catches the bookkeeping gap separately).

Constant Summary collapse

VALID_PROFILES =
%i[lenient balanced strict].freeze
VALID_SEVERITIES =
%i[error warning info off].freeze
DEFAULT_PROFILE =
:balanced
PROFILES =

Per-profile severity tables. Missing keys fall back to the diagnostic’s authored severity (typically ‘:error`).

{
  lenient: {
    "call.undefined-method" => :error,
    "call.wrong-arity" => :error,
    "call.argument-type-mismatch" => :warning,
    "call.possible-nil-receiver" => :warning,
    "flow.always-raises" => :warning,
    "assert.type-mismatch" => :error,
    "dump.type" => :info,
    "def.return-type-mismatch" => :warning
  }.freeze,
  balanced: {
    "call.undefined-method" => :error,
    "call.wrong-arity" => :error,
    "call.argument-type-mismatch" => :error,
    "call.possible-nil-receiver" => :error,
    "flow.always-raises" => :error,
    "assert.type-mismatch" => :error,
    "dump.type" => :info,
    "def.return-type-mismatch" => :warning
  }.freeze,
  strict: {
    "call.undefined-method" => :error,
    "call.wrong-arity" => :error,
    "call.argument-type-mismatch" => :error,
    "call.possible-nil-receiver" => :error,
    "flow.always-raises" => :error,
    "assert.type-mismatch" => :error,
    "dump.type" => :error,
    "def.return-type-mismatch" => :error
  }.freeze
}.freeze

Class Method Summary collapse

Class Method Details

.resolve(rule:, authored_severity:, profile: DEFAULT_PROFILE, overrides: {}) ⇒ Symbol

Resolves the configured severity for a diagnostic given the active profile and any per-rule overrides.

Parameters:

  • rule (String, nil)

    canonical rule id (‘call.undefined-method`).

  • authored_severity (Symbol)

    severity the rule emitted the diagnostic with (‘:error`, `:warning`, `:info`).

  • profile (Symbol) (defaults to: DEFAULT_PROFILE)

    one of VALID_PROFILES; falls back to DEFAULT_PROFILE for unknown values.

  • overrides (Hash{String => Symbol}) (defaults to: {})

    per-rule severity overrides from ‘.rigor.yml`’s ‘severity_overrides:` map. Keys are canonical rule ids; values are VALID_SEVERITIES symbols. Family-wildcard keys (`call`) match every rule under that prefix.

Returns:

  • (Symbol)

    the resolved severity. Returns ‘:off` to mean “drop the diagnostic entirely”.



89
90
91
92
93
94
95
96
97
# File 'lib/rigor/configuration/severity_profile.rb', line 89

def resolve(rule:, authored_severity:, profile: DEFAULT_PROFILE, overrides: {})
  return authored_severity if rule.nil?

  override = overrides[rule] || family_override(rule, overrides)
  return override.to_sym if override

  profile_table = PROFILES[profile] || PROFILES.fetch(DEFAULT_PROFILE)
  profile_table.fetch(rule, authored_severity)
end