A deterministic scanner to go with the agentic one
rvl 1.0 adds a new local scanner mode. It does not replace the agentic scan. The two work together, and the agentic scan is still the default.
The new scanner provides a deterministic pass which reads your code the way a compiler does, through the real language toolchain. Where it can resolve a call site to a reliability risk, it resolves it, and does so the same way every time. The agentic scan then adjudicates what is genuinely hard to decide, working from a smaller surface because the deterministic pass has already settled everything it could. Against the agentic scan alone that is about 40% less scan time and about 65% fewer tokens spent on the agentic portion.
It also runs on its own. When you want a fast, cheap, repeatable answer, most obviously in a pre-commit or pre-push hook, it won’t catch everything the agentic scan will, but what it does catch, it catches in seconds, while the change is still in the working tree and a development agent can fix it on the spot.
The speed is nice, but it isn’t what matters. It’s that a deterministic gate gives the same answer every time. This matters most when an agent is working in a commit loop, fixing one finding and then hitting another. The agent can only commit when the gate says “clean”, and it can only do that if the gate gives the same answer every time it is asked.
Getting the new scanner
brew upgrade is the supported path. Then run rvl doctor. The scanner needs the
toolchain for your stack installed, and doctor will tell you what is missing and how to fix it.
rvl doctor now probes what each retriever actually needs, the Go tool, libclang through
cindex --engine-check, rust-analyzer, etc. If the toolchain for one of your languages is missing, you find out from doctor.
If you’d like to suppress any particular finding, use the rvl:allow pragma.
Try it out, and give us feedback with rvl feedback if you run into any problems.
Team ownership, and scope flags for evidence and controls
Scans now carry the team ownership declared in your .revelara.yaml file, with a --team flag override for command line use. Near spellings will get a did-you-mean prompt.
rvl evidence takes --team and --service scope flags, and rvl control show reports scope
status per team. A control’s status can now be read for the team that actually owns it, rather
than flattened into a single org-wide status.
On the platform side, ownership is now a first-class axis. There is a team registry, a scan coverage view, and evidence scoping that resolves worst-of across a team’s services, with inheritance and a queue for anything whose ownership is not yet known. The risk matrix takes a team axis alongside services.
Per-team risk trajectory tracks new versus resolved week over week, with a rollup ranked by direction rather than count. A team or service that is degrading slowly shows up next to a team or service that is bad but improving, which is a trendline that doesn’t get captured when you rank by open count.
Fixes
goindexexits non-zero when the Go toolchain is missing. Five silent exit-0 paths are closed, so the lane degrades honestly instead of reporting a successful scan of nothing.pyindexandcsindexjoin the same guard through an unconditionalretrieval_statsrecord, closing three silent paths each.- A failed lane’s files are no longer written to the packet index as scanned-and-empty, which used to make the false green permanent.
- In a polyglot stream,
repo_configrecords now merge. An empty record from one language no longer erases another language’s construction facts under last-wins. rvl doctorprobes what each native retriever actually needs (the Go tool, libclang viacindex --engine-check, rust-analyzer) instead of claiming no runtime prerequisites.- A cached scan replay reproduces the original status, so a retry cannot clear a blocking gate.
- Team bindings are re-ingested when a scan replays from cache, and the replay is marked on the wire.
- The org switcher follows the selected theme. It had been permanently dark since the header tokenization in v1.9.0.
- Risk category slugs are normalized at every write path, with a backfill.
Improvements
- Evidence scoping resolves worst-of across a team’s services, with inheritance and a queue for unknown ownership.
- The risk register gains a multi-select service filter with chips, and a category filter driven by what is actually present rather than a fixed list.
- Control detail evidence rows are real accordion toggles.
- Scan output routes practice controls to the
/rvl:assess-*skills. - Feedback from
rvl feedbacklands in an operator triage loop with a notifier job. - The new rvl-cli README is reorganized into
docs/.
Breaking
rvl scanexit codes are now a four-value contract:0clean,1the scan could not complete,2usage error,3blocking findings remain. v0 exited1on blocking findings. Git hooks are unaffected (any non-zero blocks), but CI that branches on the specific number should update.- For Homebrew users, nothing renames: the binary is still
rvland configuration is stillRVL_*. Hooks installed by v0 keep working across the upgrade, andrvl hook doctorwill offer to modernize them. Only the internal beta scanner is retired: thervlscanbinary name andRVLSCAN_*environment variables are gone without a transitional alias, so any script that invoked them must move torvlandRVL_*. - The v0 CLI codebase is archived at rvl-cli-v0.