RailVerdict

Deterministic, offline, fail-closed merge verification for Ruby on Rails.

Gem Version License: MIT Ruby

RailVerdict is a deterministic verification framework for Ruby on Rails applications. It collects evidence from existing quality tools, normalizes it into stable findings, applies project policy and historical baselines, and produces a machine-readable PASS / WARN / FAIL decision that humans, CI systems, and AI coding agents can trust.

Evidence discovers.
Verification decides.
Intelligence explains.
Agents act.

One command. One gate. No SaaS, no accounts, no telemetry, no hosted service. Core verification is 100% local and offline.


Why RailVerdict Exists

In modern Rails development, source code is written and modified across multiple surfaces:

  • Software engineers crafting features, migrations, and bug fixes;
  • Automated refactoring tools updating syntax and framework deprecations;
  • AI coding agents generating code, tests, and pull requests;
  • CI automation running checks and test suites.

Running test suites alone is not enough to answer a fundamental question:

"Is this change safe to accept?"

Existing tools produce fragmented formats and disparate semantics:

  • RuboCop reports style and lint offenses;
  • RSpec and Minitest report test outcomes and failures;
  • SimpleCov reports line coverage metrics;
  • bundler-audit reports gem dependency advisories;
  • Git tracks what actually changed.

When AI coding agents enter this workflow, a new challenge appears: an AI model can explain findings and propose code changes, but an AI model should not be the authority deciding whether code is safe to merge.

RailVerdict solves this by establishing a deterministic verification layer between raw tooling and human engineers or coding agents. Given identical repository state, configuration, analyzer state, and baseline, RailVerdict produces the exact same evidence-backed PASS, WARN, or FAIL gate result — regardless of whether AI is enabled.


Born from a Real Rails Application

RailVerdict was not created as an isolated demo or synthetic experiment. It originated from real-world engineering needs encountered while maintaining IntegrarPlus.

IntegrarPlus is a private Ruby on Rails platform developed for the operational needs of a multidisciplinary healthcare organization. It has grown continuously over time and contains multiple interconnected business modules and workflows. Development involves both traditional engineering and AI-assisted coding.

As the application grew, maintaining confidence across tests, authorization, security, regressions, code quality, and automated changes became increasingly important. RailVerdict emerged from the need for a reusable verification layer capable of giving both humans and coding agents a deterministic answer about the state of a change.

Information Firewall: No IntegrarPlus private source code, database schemas, business rules, clinical workflows, or private data are included in RailVerdict. All public examples, tests, and validation fixtures are strictly synthetic. RailVerdict is a completely standalone, open-source verification framework reusable by any Rails application.


Tested Beyond Unit Tests: RailVerdict Lab

Validation repository: pedro-dalben/railverdict-lab

To ensure RailVerdict works reliably in real-world conditions, it is continuously tested against RailVerdict Lab — an independent, public Rails application designed to exercise RailVerdict as an external consumer rather than testing only internal classes.

Validation Scope

The Lab exercises RailVerdict across realistic operational scenarios:

  • Installing and running RailVerdict as an external gem dependency in a real Rails codebase;
  • Introducing controlled regressions to verify expected PASS, FAIL, and INCOMPLETE gate behavior;
  • Validating Git-aware changed-scope verification (--changed --base);
  • Testing analyzer availability, timeout, and failure modes;
  • Validating CLI commands, structured JSON, and SARIF output;
  • Validating Model Context Protocol (MCP) tool execution;
  • Validating repair packet generation and repair verification;
  • Exercising fail-closed behavior on missing or malformed analyzer output;
  • Testing release artifact installation from clean environments.

External Validation Campaign

The Lab independently validates the published gem as an external consumer. 1.0 closeout validated 21 / 21 scenarios; 1.2.0 certification validates 81 scenarios (14 categories, see Lab README) including Verification Receipts and PR Intelligence. See railverdict-lab for the canonical campaign and results.

These controlled validation scenarios represent rigorous external regression verification rather than a claim of mathematically bug-free software. During development, the Lab uncovered real defects — such as test failure scoping edge cases and the 1.2 dogfooding hardening — which were fixed before release.


The Verification Pipeline

+-------------------------------------------------------------+
|                      Rails Project                          |
+-------------------------------------------------------------+
                              |
                              v
+-------------------------------------------------------------+
|               1. Evidence Layer (Analyzers)                 |
|  RuboCop · Minitest · RSpec · SimpleCov · bundler-audit     |
+-------------------------------------------------------------+
                              |
                              v
+-------------------------------------------------------------+
|                  Normalized Findings (v1)                   |
|       Analyzer-independent · Fingerprinted · Stable         |
+-------------------------------------------------------------+
                              |
                              v
+-------------------------------------------------------------+
|               2. Verification Core (Policy)                 |
|     Baseline (no-new-debt) · Waivers · Policy Evaluation    |
+-------------------------------------------------------------+
                              |
                              v
+-------------------------------------------------------------+
|           Deterministic Gate: PASS / WARN / FAIL            |
|                  (or INCOMPLETE / exit 2)                   |
+-------------------------------------------------------------+
        |                     |                     |
        v                     v                     v
+---------------+     +---------------+     +---------------+
|   Outputs     |     | 3. Advisory AI|     | 4. Agent Loop |
| Console, JSON,|     | Explain &     |     | RepairPackets,|
| SARIF, CI exit|     | Investigate   |     | MCP server,   |
|   (0, 1, 2)   |     |  (opt-in only)|     | coding agents |
+---------------+     +---------------+     +---------------+
  • Analyzers provide evidence.
  • Policy owns the decision.
  • AI never controls the deterministic GateResult.

Installation

Install the gem directly:

gem install rail_verdict

Or add it to your application's Gemfile:

group :development, :test do
  gem "rail_verdict", require: false
end

Then install dependencies:

bundle install

Quick Start

You can verify your Rails repository with RailVerdict in under five minutes:

# 1. Initialize default configuration (.railverdict.yml)
railverdict init

# 2. Check configuration and analyzer readiness
railverdict doctor

# 3. Create an initial baseline for existing technical debt
railverdict baseline create

# 4. Run verification
railverdict check

# 5. Inspect normalized findings
railverdict findings

# 6. Summarize one pull-request change from a single verification run
railverdict pr --base origin/main

Example: A Passing Gate

When all required analyzers succeed and no new debt is introduced:

RailVerdict Verification: PASS
Policy: no_new_debt (complete)
Analyzers: 5 run (5 complete)
Findings: 0 introduced, 14 existing (baseline), 0 blocking
Exit: 0

Example: A Policy Failure

When a change introduces a new offense or test failure:

RailVerdict Verification: FAIL
Policy: no_new_debt (failed)
Analyzers: 5 run (5 complete)
Findings: 1 introduced (blocking), 14 existing (baseline)
  - [rubocop] Lint/UselessAssignment in app/models/user.rb:42 (introduced)
Exit: 1

Analyzer timeouts

Analyzer processes have a 30-second timeout by default. For a legitimately long-running analyzer, use configuration schema version: 1.5 and set the timeout on that analyzer only:

version: 1.5
mode: strict
analyzers:
  rubocop:
    enabled: true
    required: true
  rspec:
    enabled: true
    required: true
    timeout_seconds: 600

timeout_seconds must be an integer from 1 through 3600. An analyzer without an explicit value, including every analyzer in older configuration versions, continues to use 30 seconds. A timeout is incomplete evidence, never a normal finding: a required timeout produces INCOMPLETE and exit code 2.

There is no CLI timeout override; the versioned configuration (version: 1.5) is the supported public surface. SimpleCov accepts the same setting for a uniform configuration contract, but reads a local coverage artifact rather than starting an analyzer process.

30-Second Demonstration (real output)

$ railverdict check

RailVerdict Verification: PASS
Policy: no_new_debt (complete)
Analyzers: 5 run (5 complete)
Findings: 0 introduced, 0 existing, 0 blocking
Exit: 0

Introduce a controlled defect:

# app/models/user.rb:42
unused = "oops" # Lint/UselessAssignment
$ railverdict check

RailVerdict Verification: FAIL
Policy: no_new_debt (failed)
Findings: 1 introduced (blocking), 0 existing
  - [rubocop] Lint/UselessAssignment in app/models/user.rb:42 (introduced)
Exit: 1

Fix it, rerun → PASS. See docs/release/1.2-clean-room-rehearsal.md for automated reproduction.

Why not just CI?

CI answers “did these jobs execute successfully?” across fragmented outputs. RailVerdict answers “given required evidence, repository state, baseline and policy, what is the deterministic verification decision for this change?” — normalized findings, baseline-aware policy (no_new_debt), changed-scope (--changed --base), fail-closed INCOMPLETE on missing evidence, and machine contracts (JSON/SARIF/exits) plus Repository State Identity and Verification Receipts. It complements CI; the example in GitHub Actions Integration runs RailVerdict inside CI.

Why not just RSpec + RuboCop?

Those are the evidence. RailVerdict is the verifier:

RSpec says:       42 tests passed.
RuboCop says:     3 offenses.
SimpleCov says:   91.3% coverage.
Git says:         these 7 lines changed.
RailVerdict says: FAIL — this change introduced a blocking finding.

They produce facts; policy owns the gate. rubocop + rspec + minitest + simplecov + bundler-audit + Git are inputs; PASS/WARN/FAIL/INCOMPLETE is the GateResult (see docs/contracts.md).

Why this matters for AI agents

An AI agent can write code, run tests, and declare itself finished — but it should not be the authority deciding whether its own work is acceptable.

Agent --modifies--> Repository --verify--> RailVerdict
                                           |--> deterministic evidence
                                           |--> GateResult
                                           `--> Verification Receipt

The agent proposes; the verification system decides. Receipts let agents (and humans) prove fresh vs stale after any edit — see below. AI inside RailVerdict (explain/investigate) is advisory only and never changes GateResult.


The Default Policy Model: No New Debt

RailVerdict supports three policy modes: no_new_debt (default), strict, and advisory.

Why "No New Debt" Matters

Large, mature Rails applications often contain existing technical debt: legacy style offenses, pending test skips, or partial test coverage. Requiring teams to fix all historical issues before adopting verification creates an impossible barrier.

RailVerdict's no_new_debt mode solves this by separating historical debt from new changes:

"Existing debt is known and recorded. New debt is blocked."

How Baselines Work

  1. Atomic Creation: railverdict baseline create runs a complete verification and atomically records SHA-256 fingerprints of current findings into .railverdict-baseline.json.
  2. Comparison: Subsequent runs classify findings into introduced, existing, resolved, changed, or moved.
  3. Selective Enforcement: Only introduced (new) findings block the merge gate in no_new_debt mode.
  4. Read-Only Verification: railverdict check is strictly read-only and never mutates baselines.
  5. Waivers: Time-bounded, exact-fingerprint exemptions can be documented with owners and UTC expiration dates without silencing evidence.

Changed-Scope Verification

For pull requests, CI builds, and coding agents, RailVerdict supports incremental, Git-aware verification:

# Verify only changes against the main branch
railverdict check --changed --base origin/main

# Verify against a local Git revision
railverdict check --changed --base HEAD~1

# Output versioned JSON for machine consumers
railverdict check --changed --base origin/main --format json

PR Intelligence

railverdict pr --base origin/main produces a deterministic, versioned summary of the change, quality delta, objective Rails path signals, analyzer evidence, test metrics, and coverage available from that same verification run. Use --format json for machine consumers. Signals are deterministic attention indicators, not risk probabilities; GateResult and policy remain the only verification authority.

Example console output:

RailVerdict PR Intelligence

Gate: PASS
Completion: complete
Revision: 3f4a2c1d9e00 (base 8a7b6c5d4e33)

Change
  4 files
  +38 / -7
  added 1  modified 2  deleted 0  renamed 1

Quality Delta
  introduced 0  resolved 2  existing 8

Signals
  Database       YES
  Authorization  YES
  Routes         NO
  Dependencies   NO
  Configuration  NO
  Tests          YES

Evidence
  rubocop: succeeded
  rspec: succeeded

The JSON contract is pr-intelligence-v1.schema.json. It includes head, base, merge_base, and configuration-digest provenance, plus a stable projection of the canonical gate_result without checkout-local paths. Without a compatible baseline, quality_delta.available is false with reason: "baseline_not_available"; it does not emit fake zeroes. Invalid Git bases and incomplete required evidence remain INCOMPLETE with exit code 2.

Key Capabilities

  • Merge-Base Resolution: Computes the exact merge-base between HEAD and the target branch;
  • NUL-Safe Diff Parsing: Accurately handles renames, deletions, and binary files;
  • Changed-Line Coverage: Evaluates whether newly added or modified executable lines are covered by tests;
  • Fail-Closed Git Boundary: If the base revision is missing or repository history is shallow, RailVerdict returns INCOMPLETE (exit code 2) rather than guessing or silently passing.

Verification Receipts (1.2)

Verification is only meaningful for the exact state that was verified. RailVerdict 1.2 binds every guarded verification to a deterministic Repository State Identity (HEAD + Git index snapshot + worktree delta with content hashes + configuration/baseline/waiver digests) and issues a machine-readable Verification Receipt:

$ railverdict check
# => RailVerdict Verification: PASS (exit 0)
$ railverdict receipt create > receipt.json
# receipt_id = sha256:<64 hex>  (no created_at, no timestamps)

$ railverdict receipt verify receipt.json --format json
{"schema_version":"1.0","status":"fresh","reasons":[],"gate":"PASS"}

Edit anything afterwards and the same receipt reports stale:

$ echo "# changed after verification" >> app/models/user.rb
$ railverdict receipt verify receipt.json --format json
{"schema_version":"1.0","status":"stale","reasons":["worktree_changed"],"gate":"PASS"}
# exit 2 — current state is not what was verified

# Same for staged, config, baseline, waiver edits:
# head_changed | index_changed | worktree_changed | configuration_changed | baseline_changed | waivers_changed

If the repository mutates while analyzers run, receipt issuance fails closed with repository_changed_during_verification. Receipts exist for PASS, FAIL, and INCOMPLETE; they are deterministic integrity records — not signed attestations — a trusted CI remains the trust anchor when forgery is in scope. Full protocol in docs/agent-verification.md.

Deterministic Verification  PR Intelligence  Verification Receipt  Agent Verification Protocol

Supported Analyzers

All analyzers in RailVerdict are external and owned by the target project. RailVerdict invokes existing executables via argument arrays (argv) without shell interpolation and never silently installs or vendors third-party packages.

Analyzer Purpose Supported Versions How RailVerdict Consumes It
RuboCop (+ rubocop-rails) Style, linting, Rails conventions RuboCop >= 1.72, < 2<br>rubocop-rails >= 2, < 3 Runs bundle exec rubocop --format json; captures plugin versions and configuration digest.
Minitest Unit and integration tests >= 5, < 7 Consumes test results via RailVerdict's owned JSON reporter (minitest-reporter-v1).
RSpec Unit and integration specs >= 3.13, < 4 Consumes test results via standard --format json.
SimpleCov Code and changed-line coverage >= 1, < 2 Ingests versioned public coverage/coverage.json v1 (never parses internal .resultset.json).
bundler-audit Gem dependency vulnerabilities >= 0.9.3, < 1 Runs bundle exec bundler-audit check --format json (never runs automatic updates). Robustly extracts JSON when advisory-DB download notices precede the payload.

Brakeman Status: Brakeman support is not included in 1.2.0 (on HOLD pending legal and licensing review). Third-party analyzers retain their respective upstream licenses.


Outputs, CI, and Exit Codes

RailVerdict produces structured output for both human developers and automated systems.

Output Formats

  • Console (--format console): Human-readable terminal output (default);
  • JSON (--format json): Single-document, canonical JSON complying with result-v1.schema.json on stdout, diagnostics on stderr;
  • SARIF (--format sarif): Standard SARIF 2.1.0 projection for GitHub Code Scanning and IDEs.

Exit Code Contract

Exit Code Meaning Gate Status
0 Verification succeeded without blocking issues. PASS or non-blocking WARN
1 Policy violation detected (new offenses, failing tests, etc.). FAIL
2 Incomplete evidence, tool failure, missing base, or configuration error. INCOMPLETE
130 Execution interrupted by user (SIGINT). INTERRUPTED

Why Exit Code 2 is Vital

If a required analyzer is missing, times out, crashes, or produces malformed output, that run must never be interpreted as "zero offenses" or a PASS. RailVerdict fails closed: incomplete required evidence produces INCOMPLETE and exits with code 2, preventing broken pipelines from silently passing.

GitHub Actions Integration

name: Verification
on:
  pull_request:
    types: [opened, synchronize, reopened]

permissions:
  contents: read

jobs:
  railverdict:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: ruby/setup-ruby@v1
        with:
          bundler-cache: true

      - name: Run RailVerdict
        run: bundle exec railverdict check --changed --base ${{ github.event.pull_request.base.sha }}

See docs/github-actions.md for full CI configuration examples.


Optional AI Intelligence (Advisory Only)

RailVerdict includes an optional intelligence layer designed to assist with finding explanations and triage:

# Explain a specific finding
railverdict explain <finding-id|fingerprint>

# Preview context that would be sent (no network)
railverdict explain <finding-id> --preview-context

# Investigate top blocking findings
railverdict investigate --limit 3

Strict Advisory Boundaries

  • Opt-in Only: AI is disabled by default. Enabling remote AI requires explicit configuration (ai.enabled: true and ai.remote.enabled: true).
  • Zero Gate Authority: AI never controls GateResult. It cannot change a FAIL to a PASS, override project policy, or bypass checks.
  • Privacy & Redaction: Sensitive tokens, credentials, and private patterns are automatically scrubbed (trust: redacted by default).
  • Offline Core: All deterministic verification functions work 100% offline without network access or AI configuration.

See docs/ai.md and docs/privacy.md for details.


Coding Agents & The Repair Loop

Agent Completion Protocol (copyable for AGENTS.md / CLAUDE.md / Codex)

Before declaring any code-changing task complete:

  1. Run the required project tests.
  2. Run bundle exec railverdict check (or check --changed --base <main> in PRs).
  3. If FAIL: remediate findings and rerun until PASS or explicitly report the blocker.
  4. If INCOMPLETE (exit 2): do not claim verification succeeded — fix the evidence gap (missing analyzer, bad base, shallow history).
  5. After final PASS, create bundle exec railverdict receipt create > receipt.json.
  6. Do not modify repository state after receipt creation without reverifying — receipt verify must stay fresh.

FAIL means remediation required. INCOMPLETE must never be represented as PASS. See docs/agent-verification.md for the formal contract.

AGENTS.md snippet (paste into your repo)
## Verification

Before completing any code-changing task:

bundle exec railverdict check

A task may only be reported as verified when RailVerdict returns PASS (exit 0).

FAIL (exit 1) means remediation is required.

INCOMPLETE (exit 2) means required evidence could not be obtained and must never be represented as PASS.

After the final PASS, create a verification receipt: bundle exec railverdict receipt create > receipt.json

Do not modify repository state after receipt creation without reverifying (receipt verify must be fresh).

Validated against 1.2.0: init, doctor, check, pr, baseline create, findings, repair, receipt create|verify, mcp serve.

RailVerdict also provides a structured verification loop for AI coding agents (such as Claude, Codex, or custom agents):

Agent modifies code
        │
        ▼
railverdict check (returns FAIL / exit 1)
        │
        ▼
railverdict repair <finding-ref>
        │
        ▼
RepairPacket (bounded, structured context)
        │
        ▼
Agent applies fix
        │
        ▼
railverdict check (Verifier classifies outcome)

RepairPacket v1

When an agent needs to fix a finding, railverdict repair <finding-ref> generates a deterministic RepairPacket v1:

  • Bounded Context: Capped at 256 KiB with strict snippet and diff limits;
  • Trust Boundary: Delimits TRUSTED_RAILVERDICT_INSTRUCTIONS from untrusted repository text;
  • Secret Redacted: Scans and removes sensitive values before emission;
  • Outcome Classification: RailVerdict::Repair::Verifier classifies repair outcomes as fixed, still_present, changed, moved, regressed, or incomplete.

RailVerdict never directly mutates application code; it provides the verifiable contract that allows external agents to repair code safely. See docs/repair-workflow.md.


Model Context Protocol (MCP)

RailVerdict includes a native Model Context Protocol (MCP) stdio server, allowing coding agents to interact with verification as structured tools:

railverdict mcp serve

Implemented MCP Tools

Tool Purpose
verify Executes verification (full or changed) and returns canonical GateResult.
list_findings Lists, filters, and paginates normalized findings.
get_finding Retrieves detailed finding data, evidence references, and context.
build_repair_packet Builds a bounded RepairPacket v1 for a specific finding.
verify_repair Reruns verification and classifies whether a repair succeeded or regressed.
explain Generates an advisory AI explanation for a finding.
investigate Investigates top blocking findings across the codebase.
get_verification_receipt Returns the Verification Receipt for the last verify without rerunning analyzers (refuses stale cache).
get_pr_intelligence Returns PR Intelligence derived from the last verify's GateResult (no rerun).

MCP Security Properties

  • Stdio Transport: Operates over standard I/O with no open ports or background daemons;
  • Repository Containment: Paths are verified and strictly contained within the repository root;
  • Read-Only Tools: All tools are marked readOnlyHint: true; RailVerdict verifies while external agents edit;
  • Mutex Serialization: Verification runs are serialized to prevent concurrent execution conflicts.

See docs/mcp.md for configuration examples.


Rails-Aware Context (Without Booting Rails)

When verifying changes (--changed), RailVerdict enriches results with bounded Rails-aware context without booting the Rails application, loading ActiveRecord, or executing routes.rb and schema.rb:

  • Related Tests: Identifies candidate test and spec files for modified models and controllers;
  • Policies: Locates corresponding Pundit/ActionPolicy authorization policies;
  • Views: Identifies associated view templates;
  • Routes & Schema: Extracts literal route definitions and schema table fragments.

Each context element includes an explicit confidence rating (exact, conventional, inferred, unresolved) and provenance. Context extraction failures degrade gracefully without causing gate failures. See docs/rails-context.md.


Security & Fail-Closed Architecture

RailVerdict is engineered around a comprehensive threat model documented in SECURITY.md:

  • Fail-Closed Gate: Incomplete, missing, or malformed evidence cannot produce a PASS;
  • Safe Subprocess Execution: Invokes executables exclusively via argument arrays (argv), eliminating shell-injection vulnerabilities;
  • Resource Bounds: Monotonic timeouts, output limits, and process-group signal termination (SIGTERM/SIGKILL) prevent resource exhaustion;
  • Path Containment: Normalizes paths and rejects directory traversal or symlink escapes;
  • Information Firewall: Strict public provenance controls prevent internal data or private patterns from entering artifacts;
  • Subprocess Limitation: Subprocess containment provides argument and resource isolation; it is not an operating system kernel sandbox.

Architecture Overview

RailVerdict is structured into four distinct conceptual layers:

  1. Evidence Layer: Executes external quality tools safely and captures facts;
  2. Verification Core: Normalizes findings, manages fingerprints and baselines, and evaluates policy to produce an immutable GateResult;
  3. Intelligence Layer: Provides optional, advisory explanations without gate authority;
  4. Agent Layer: Exposes deterministic interfaces (CLI, JSON, SARIF, RepairPackets, MCP) for human engineers and coding agents.
Evidence discovers.
Verification decides.
Intelligence explains.
Agents act.

For detailed architectural principles and component designs, see ARCHITECTURE.md, PROJECT.md, and PHILOSOPHY.md.


What RailVerdict Is NOT

To maintain clear technical boundaries, RailVerdict is explicitly NOT:

  • NOT a replacement for test frameworks or linters: It does not replace RSpec, Minitest, or RuboCop; it normalizes and verifies their evidence.
  • NOT an AI code reviewer that decides safety: AI cannot override or determine the gate decision.
  • NOT a hosted SaaS or cloud dashboard: There are no user accounts, billing, hosted control planes, or telemetry.
  • NOT an auto-fixing bot: It does not autonomously commit or rewrite application source code.
  • NOT a full semantic code graph: Rails relationships are bounded, heuristic, and labeled with confidence rather than deep AST graphs.

Project Status

  • Release Version: 1.2.0
  • License: MIT (see NOTICE)
  • Trademarks: TRADEMARKS.md
  • Foundation & Legal: docs/foundation.md — preliminary screen found no obvious software/tool conflict; NOT LEGAL CLEARANCE; qualified trademark review NOT PERFORMED — NON-BLOCKING BY MAINTAINER DECISION 2026-08-19 (Pedro Dalben).
  • Ruby Compatibility: >= 3.3 (tested on Ruby 3.3, 3.4, and 4.0)
  • Target Rails Context: >= 8.0
  • Supply Chain: Released via RubyGems Trusted Publishing and GitHub OIDC.

Documentation Index

Topic Primary Documents
Product & Philosophy PROJECT.md · PHILOSOPHY.md · ARCHITECTURE.md · ROADMAP.md
Contracts & Schemas docs/contracts.md · schemas/finding-v1.schema.json · schemas/configuration-v1.schema.json · schemas/result-v1.schema.json
Examples examples/finding-v1.json · examples/configuration-v1.yml · examples/configuration-v1.5.yml · examples/result-v1.json
Analyzers & Baselines docs/analyzers.md · docs/baselines.md
CI, SARIF & Git Scope docs/github-actions.md
Rails-Aware Context docs/rails-context.md
Agent Protocols & Repair docs/mcp.md · docs/repair-workflow.md
AI & Privacy docs/ai.md · docs/privacy.md
Security & Firewall SECURITY.md · docs/foundation.md
Architecture Decisions ADRs
Legal & Trademarks LICENSE · NOTICE · TRADEMARKS.md
Changelog CHANGELOG.md
Public Validation Lab pedro-dalben/railverdict-lab

Try RailVerdict Challenge (5 minutes)

  1. bundle add rail_verdict --group development,test --require false && bundle install
  2. bundle exec railverdict init && bundle exec railverdict doctor
  3. bundle exec railverdict baseline create (or skip for greenfield) → bundle exec railverdict check → first gate
  4. Introduce a controlled RuboCop offense, rerun → FAIL, fix → PASS, then railverdict receipt create && railverdict receipt verify

Tell us where it confused (see docs/troubleshooting.md and docs/launch/try-challenge.md).

FAQ

Is RailVerdict a test framework? Does it replace RSpec/RuboCop/CI? No — it consumes them; they are evidence, it is the verifier. Run it inside CI.

Does it upload source? Require AI? Does AI decide PASS? No/no/no — offline by default, AI advisory only off by default (trust: redacted).

Legacy apps? Yes — no_new_debt baseline.

INCOMPLETE vs FAIL? FAIL = complete verification rejected new debt; INCOMPLETE = required evidence missing → no gate (exit 2), never PASS.

Baseline / waiver / receipt? Baseline snapshots current debt; waiver is exact-fingerprint, UTC-expired exemption; receipt is an integrity record (receipt_id = sha256:) — not signed, forgeable via whole-file rewrite — trusted CI is the trust anchor. Mutating after PASS makes receipt stale.

Brakeman / Ruby / Rails? Brakeman not in 1.2.0 (HOLD); Ruby >=3.3, Rails >=8.0 bounded.

Contributing & Issues

Contributions and issue reports are welcome. See CONTRIBUTING.md for “how to run tests / add regression”. Issue templates: Bug, Feature request, Compatibility report. Please open an issue on GitHub for:

  • Analyzer compatibility and version range feedback;
  • False positives or false negatives in evidence normalization;
  • Rails version or convention compatibility;
  • CLI and MCP ergonomics and developer experience.

GitHub Repository: https://github.com/pedro-dalben/RailVerdict Issues: https://github.com/pedro-dalben/RailVerdict/issues