Module: RailVerdict::PRIntelligence
- Defined in:
- lib/rail_verdict/pr_intelligence.rb
Constant Summary collapse
- SCHEMA_VERSION =
"1.0"- MAX_SIGNAL_EVIDENCE =
20- SIGNALS =
{ "database_change" => lambda { |path| path == "db/schema.rb" || path == "db/structure.sql" || path.start_with?("db/migrate/") }, "routes_change" => lambda { |path| path == "config/routes.rb" || path.start_with?("config/routes/") }, "dependency_change" => lambda { |path| %w[Gemfile Gemfile.lock].include?(path) }, "configuration_change" => lambda { |path| path == "config" || path.start_with?("config/") }, "authorization_change" => lambda { |path| path.start_with?("app/policies/") }, "tests_change" => lambda { |path| path.start_with?("spec/") || path.start_with?("test/") } }.freeze
- STATUS_KEYS =
%w[added modified deleted renamed].freeze
- TEST_KEYS =
%w[tests_total assertions failures errors skips duration_seconds seed runner].freeze
- GATE_RESULT_KEYS =
%w[ schema_version completion_status gate policy_status findings operational_failures decision_reasons ].freeze
Class Method Summary collapse
- .deep_copy(value) ⇒ Object
- .document(outcome) ⇒ Object
- .render_json(outcome) ⇒ Object
-
.stable_projection(document) ⇒ Object
Deterministic projection used for receipt binding: identical meaningful verification inputs must produce an identical digest, so volatile test runtime fields (duration_seconds, seed) are excluded.
Class Method Details
.deep_copy(value) ⇒ Object
69 70 71 72 73 74 75 |
# File 'lib/rail_verdict/pr_intelligence.rb', line 69 def deep_copy(value) case value when Hash then value.to_h { |k, v| [k, deep_copy(v)] } when Array then value.map { |item| deep_copy(item) } else value end end |
.document(outcome) ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/rail_verdict/pr_intelligence.rb', line 26 def document(outcome) result = outcome.result git_context = outcome.context&.git_context git = result.git || {} document = { "schema_version" => SCHEMA_VERSION, "provenance" => provenance(outcome, git_context, git), "gate_result" => gate_result(result), "change" => change(git_context), "signals" => signals(git_context), "quality_delta" => quality_delta(result), "analyzer_evidence" => analyzer_evidence(result), "test_intelligence" => test_intelligence(result), "coverage" => coverage(result) } errors = SchemaValidator.validate_pr_intelligence(document) raise RailVerdict::Error, "pr-intelligence-v1 validation failed: #{errors.join('; ')}" unless errors.empty? document end |
.render_json(outcome) ⇒ Object
48 49 50 |
# File 'lib/rail_verdict/pr_intelligence.rb', line 48 def render_json(outcome) JSON.generate(document(outcome)) + "\n" end |
.stable_projection(document) ⇒ Object
Deterministic projection used for receipt binding: identical meaningful verification inputs must produce an identical digest, so volatile test runtime fields (duration_seconds, seed) are excluded.
55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/rail_verdict/pr_intelligence.rb', line 55 def stable_projection(document) projected = deep_copy(document) analyzers = projected.dig("test_intelligence", "analyzers") if analyzers.is_a?(Hash) analyzers.each_value do |values| next unless values.is_a?(Hash) values.delete("duration_seconds") values.delete("seed") end end projected end |