We shipped the free tier of rvl this week along with its v1 release, and I’m really excited about this one. It’s a deterministic reliability scanner: it finds missing timeouts and deadlines, unbounded calls, secrets in the tree, and risky CI and infrastructure configuration, across Go, Python, TypeScript, Rust, Java, C#, and C/C++. The scanner is open source (Apache-2.0), the free ruleset needs no account, and nothing about your code leaves your machine.

brew install --cask revelara-ai/tap/rvl
rvl sync    # pulls the free ruleset, no API key
rvl scan

Why I built this

Reliability failures repeat. The unbounded call that took down one company’s checkout takes down another company’s billing job a year later, and the incident reviews for both are public. We’ve been building a corpus of those incidents at Revelara, and one of the patterns that kept jumping out at us was: a number of production incidents trace to a small set of well-understood problems that were cheap to catch at the commit and expensive to catch at 3am.

Security already went through this. Known vulnerabilities were collected into databases, scanners grew around the databases, and the scanners ended up in commit gates. Nobody hand-audits their dependency tree anymore.

Reliability never got that treatment, at least not in any unified way. Linters check style, SAST checks security, and the knowledge of what makes code fall over in production stays locked in followup tasks and senior engineers’ heads. rvl puts it into the code commit loop instead.

I also have to credit where a lot of the inspiration came from. Thomas Stromberg has been driving atomdrift, open-source supply-chain attack detection built on local, deterministic analysis. My ideas for how to left shift reliability tooling in the AI age, plus our conversations about his work on Atomdrift shaped this tool more than anything else. If you care about supply-chain security, you should go check out his work. (Plus, and I mean this sincerely, Thomas is one of the kindest people I’ve ever met in the industry, and an amazing engineer.)

Why deterministic

A scan makes zero model calls. Retrievers report facts about your code, rulesets carry the judgment about APIs, and propagation combines them mechanically. Given the same input, you get the same output every time. When the scanner was purely LLM driven, I couldn’t recommend using it as a precommit gate because the results would swing from run to run.

The rulesets themselves are built with model involvement: candidate rules are authored from real-world API usage and have to survive a gauntlet of adversarial refutation before they ship. All of that happens before signing. What you download is a signed artifact, verified at fetch and at load.

What it looks like

A first scan of a small Python service:

■ BLOCKING

  app.py:4 — requests.get has no timeout or deadline — it can hang indefinitely
    severity: high
    control RC-019 · explain: rvl explain bfyx

■ COVERAGE

  47/91 API surfaces resolved (51%)
  12 abstain — 8 no spec · 2 unresolved bounds · 1 need per-site judge · 1 other
  3 sites block by design — uvicorn.run (server main loop)

✗ blocked — fix or suppress 1 blocking finding to commit

From here, rvl explain bfyx shows every site, the reliability control behind the finding, and the fix. If the finding is real, you add the timeout. If it’s wrong for your context, rvl suppress bfyx --reason "..." --expires 2027-01-01 writes a waiver into a committed config file, so the decision gets reviewed in a pull request like any other change instead of living silently on a laptop or in someone’s head.

If the scanner abstained because your database client is bounded by a server-side statement_timeout it can’t see, you declare that bound in the same file and the abstain closes.

Then you wire the gate: rvl hook install puts the scan on pre-commit, scanning only your staged changes against a warm index. The loop above is something you do a few times the first week and rarely after.

What it does that other tools don’t

Its rules come from production history derived from public incident disclosures. We author them against that corpus, so a rule exists because the failure mode has taken down real systems, not because a style guide disapproves. Every finding is also mapped to a reliability control, the same vocabulary the rest of the Revelara platform uses for risk and evidence tracking.

The report also tells you what it could NOT decide. Exit code 0 means “nothing found”, which is different than “nothing checked”, and abstains in the coverage section name what would close them. A language lane that read nothing is reported as a failure rather than counted clean, and the exit codes keep “your code has a problem” (3) distinct from “the scanner is broken” (1).

When running the commercial version of the scanner, the only thing it can send is the shape of unknown API surfaces, four fields per surface (client type, method name, language, site count). No source, no file paths, no line numbers. Tests assert that planted source isn’t transmitted in the payload. rvl report --json shows exactly what gets reported, and RVL_OFFLINE=1 disables network fetches.

What free means here

The free ruleset carries what we call the vocabulary lanes: server entry patterns, emission patterns (logging, tracing, error handling), and configuration knowledge for Kubernetes, Terraform, GitHub Actions, GitLab CI, Prometheus, Argo and Flux, and dependency manifests. It’s licensed CDLA-Permissive-2.0, embedded in the artifact itself. Results computed from the data are explicitly unencumbered, so your scan output carries no obligations, and redistribution only requires keeping the license text.

The commercial tier adds the judgment rulesets, which include per-API verdicts about blocking behavior and severity. This lets API findings gate a commit, plus you get the risk register and the rest of the Revelara platform. Upgrading is a config change: add a key, run rvl sync again, and the commercial rulesets layer over the free tier.

Coding agents

If you use a coding agent and are on the commercial platform, rvl init installs skills for it (Claude Code, Codex, Cursor, Copilot, Gemini, Windsurf, and others). The loop is scan, ask, fix. The deterministic engine settles everything it has rulesets for, and the agent works only on what the engine left undecided. Nothing gets scanned twice, and agent time goes where determinism can’t reach. In our own A/B on a real codebase, that ran 40% faster and used 65% fewer output tokens than a pure agent approach, and it surfaced more net-new issues.

Where this goes

I’m excited about this as a tool for finding early stage reliability issues before they become production problems, and it’s built as a pipeline that evolves the more we learn about how systems and components create or are impacted by reliability issues. Every “no spec” abstain is a ruleset we haven’t created yet, and shape reports (if you choose to send them) are how new rulesets get prioritized. Coverage grows toward the stacks people actually use and scan. We also watch upstream releases: when a client library ships a major version, the rules that judged its old API get re-examined instead of going stale.

Two things I want going forward:

First, deeper judgment: more of the “depends on the call site” cases should get resolved automatically instead of abstained.

Second, publishing more of what the incident corpus teaches in the open, the same way the free ruleset tier is open. Reliability knowledge can prevent incidents when it reaches developers before the code ships, and it tends to mostly sit in documents and in people’s heads rather than providing actionable insights and guardrails at the point of creation.

Where things are

If you try it and something is wrong or confusing, rvl bugreport sends us feedback, and GitHub issues work too.