Module: Rigor::BleedingEdge
- Defined in:
- lib/rigor/bleeding_edge.rb
Overview
ADR-50 § WD2 — the bleeding-edge overlay.
A Rigor-maintained set of the *next major’s* queued changes —severity-map promotions and new-discipline rule enablements — that a user can adopt early, before they become default-on at a major (ADR-50 § WD7). It is orthogonal to ‘severity_profile:` (how loud *today’s* rules are) and is versioned with the gem, NOT a user-supplied file: the inspectable counterpart to PHPStan’s ‘bleedingEdge` include.
The overlay is **empty today** — no discipline has yet been queued for the next major. This module is the WD2 foundation (the v0.1.19 slice): the surface (‘bleeding_edge:` config, the `rigor show-bleedingedge` command, the severity-composition hook in Configuration::SeverityProfile.resolve) exists and is wired end-to-end, so the first real feature lands as a single FEATURES entry with no engine plumbing.
Each feature carries a **stable feature id** — part of the ADR-50 WD1 contract vocabulary: the config, the ‘show` command, and the eventual CHANGELOG migration note all name the same id, and a feature graduates to default-on at a major by being removed from FEATURES.
Defined Under Namespace
Classes: Feature
Constant Summary collapse
- FEATURES =
The overlay. Empty until the first next-major discipline is queued; add a Feature here (with a stable id) when one is.
[].freeze
Instance Attribute Summary collapse
-
#id ⇒ String
The stable feature id (contract vocabulary).
-
#severity_overrides ⇒ Hash{String => Symbol}
Canonical rule id → the severity this feature imposes.
-
#summary ⇒ String
A one-line description of what it changes.
Class Method Summary collapse
-
.active_features(selector) ⇒ Array<Feature>
Resolves a normalized ‘bleeding_edge:` selector (see Configuration#bleeding_edge) to the active Feature list.
- .feature(id) ⇒ Feature?
-
.feature_ids ⇒ Array<String>
Every feature id in the overlay.
-
.features ⇒ Array<Feature>
The whole overlay.
-
.severity_overrides_for(selector) ⇒ Hash{String => Symbol}
The merged severity-override map the active features impose for a selector.
-
.unknown_selected_ids(selector) ⇒ Array<String>
Feature ids named by a selector that are NOT in the overlay (typo / graduated / from a newer gem).
Instance Attribute Details
#id ⇒ String
Returns the stable feature id (contract vocabulary).
39 40 41 42 43 44 45 46 47 |
# File 'lib/rigor/bleeding_edge.rb', line 39 Feature = Data.define(:id, :summary, :severity_overrides) do def to_h { "id" => id, "summary" => summary, "severity_overrides" => severity_overrides.transform_values(&:to_s) } end end |
#severity_overrides ⇒ Hash{String => Symbol}
Returns canonical rule id → the severity this feature imposes. Composed below the user’s own ‘severity_overrides:` and above the active `severity_profile` (see Configuration::SeverityProfile.resolve).
39 40 41 42 43 44 45 46 47 |
# File 'lib/rigor/bleeding_edge.rb', line 39 Feature = Data.define(:id, :summary, :severity_overrides) do def to_h { "id" => id, "summary" => summary, "severity_overrides" => severity_overrides.transform_values(&:to_s) } end end |
#summary ⇒ String
Returns a one-line description of what it changes.
39 40 41 42 43 44 45 46 47 |
# File 'lib/rigor/bleeding_edge.rb', line 39 Feature = Data.define(:id, :summary, :severity_overrides) do def to_h { "id" => id, "summary" => summary, "severity_overrides" => severity_overrides.transform_values(&:to_s) } end end |
Class Method Details
.active_features(selector) ⇒ Array<Feature>
Resolves a normalized ‘bleeding_edge:` selector (see Configuration#bleeding_edge) to the active Feature list. Unknown ids in a `list` / `except` selector are simply absent from the overlay and contribute nothing — symmetric with how `severity_overrides:` keeps an unknown rule id inert until it lands (robust across gem versions).
82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/rigor/bleeding_edge.rb', line 82 def active_features(selector) case selector["mode"] when "all" except = selector["except"] || [] FEATURES.reject { |f| except.include?(f.id) } when "list" ids = selector["ids"] || [] FEATURES.select { |f| ids.include?(f.id) } else [] end end |
.feature(id) ⇒ Feature?
67 68 69 |
# File 'lib/rigor/bleeding_edge.rb', line 67 def feature(id) FEATURES.find { |f| f.id == id } end |
.feature_ids ⇒ Array<String>
Returns every feature id in the overlay.
61 62 63 |
# File 'lib/rigor/bleeding_edge.rb', line 61 def feature_ids FEATURES.map(&:id) end |
.features ⇒ Array<Feature>
Returns the whole overlay.
56 57 58 |
# File 'lib/rigor/bleeding_edge.rb', line 56 def features FEATURES end |
.severity_overrides_for(selector) ⇒ Hash{String => Symbol}
The merged severity-override map the active features impose for a selector. Frozen so the result is ‘Ractor.shareable?`.
100 101 102 103 104 |
# File 'lib/rigor/bleeding_edge.rb', line 100 def severity_overrides_for(selector) active_features(selector).each_with_object({}) do |feature, acc| acc.merge!(feature.severity_overrides) end.freeze end |
.unknown_selected_ids(selector) ⇒ Array<String>
Feature ids named by a selector that are NOT in the overlay (typo / graduated / from a newer gem). Surfaced by ‘rigor show-bleedingedge` as a hint; never an error.
112 113 114 115 116 117 118 119 120 121 |
# File 'lib/rigor/bleeding_edge.rb', line 112 def unknown_selected_ids(selector) named = case selector["mode"] when "list" then selector["ids"] || [] when "all" then selector["except"] || [] else [] end known = feature_ids named.reject { |id| known.include?(id) } end |