ripr
ripr is a static RIPR mutation-exposure analyzer for Rust workspaces.
It answers a draft-time testing question:
For the behavior changed in this diff, do the current tests appear to contain
a discriminator that would notice if that behavior were wrong?
ripr is alpha software. The current release is a syntax-first scanner that is
useful for early feedback, not a proof system.
This is the product repository for ripr. The 0.3.x line keeps the analyzer
scope narrow while strengthening syntax-backed evidence and the editor loop.
Mission
ripr helps Rust developers and coding agents write tests that actually notice
changed behavior.
It performs static RIPR exposure analysis over changed Rust code, creates mutation-shaped probes, and reports whether existing tests appear to contain the discriminators needed to expose those changes.
It is a fast draft-mode companion to real mutation testing: static guidance while the pull request is moving, real mutation confirmation when the change is ready.
Vision
The vision for ripr is to become the live test-adequacy layer between coverage
and mutation testing for Rust/Cargo workspaces.
Coverage tells developers what executed. Mutation testing tells developers what
survived. ripr tells developers, reviewers, and agents what changed behavior
appears to lack a meaningful oracle before the expensive mutation run begins.
The end state is an LSP-native sidecar that watches changed code, identifies missing discriminators, explains the evidence path, emits agent-ready test intent, and calibrates itself against real mutation outcomes.
Category
ripr defines its category as:
Static Mutation Exposure Analysis
More specifically:
Static oracle-gap analysis for diff-derived mutation probes.
The tool is not trying to be a coverage dashboard, a full mutation engine, a proof system, a second rust-analyzer, or a generic LLM test generator. Its job is to shorten the path from "this behavior changed" to "this is the exact test oracle that should notice."
What ripr Does
ripr reads changed Rust code, creates mutation-shaped probes, and estimates
whether related tests appear to reach, infect, propagate, observe, and
discriminate the changed behavior.
It looks for missing or weak test oracles such as:
- boundary changes without boundary-value assertions
- error-path changes checked only with
is_err() - return-value changes checked only with smoke assertions
- field construction changes without field, object, or snapshot assertions
- side effects without mock, event, state, persistence, or metric oracles
What ripr Does Not Do
ripr does not run mutants.
It does not report killed or survived, prove test adequacy, replace coverage,
or replace real mutation testing. Use a real mutation runner, such as
cargo-mutants, when the change is ready for confirmation.
Where It Fits
coverage:
did this code execute?
ripr:
does changed behavior appear exposed to a meaningful oracle?
mutation testing:
did tests fail when a concrete mutant was run?
The goal is fast, honest oracle-gap feedback while code is still changing.
Ecosystem Positioning
| Existing layer | What it answers | Gap |
|---|---|---|
cargo-llvm-cov |
Did code execute? | Not oracle-aware |
| selective retest tools | Which tests are impacted? | Not assertion-aware |
cargo-mutants |
Did real mutants survive? | Too expensive for live draft feedback |
rust-analyzer |
What does Rust code mean in the editor? | Does not rank mutation exposure |
ripr |
Does changed behavior appear exposed to a meaningful oracle? | New middle layer |
Install
Install from crates.io:
Links:
- crates.io: https://crates.io/crates/ripr
- docs.rs: https://docs.rs/ripr
For local development from this repository:
ripr targets Rust 2024 and requires Rust 1.93 or newer.
Quick Start
# Check local tooling and workspace shape
# Analyze the current Git diff against origin/main
# Analyze an explicit unified diff
# Emit stable JSON for tools and agents
# Emit GitHub Actions annotations
# Explain one finding
# Emit an agent-ready context packet
# Start the experimental LSP sidecar
Example Finding
WARNING src/pricing.rs:88
Static exposure: weakly_exposed (predicate, control)
Changed behavior:
after: if amount >= discount_threshold {
RIPR:
Reach: yes
Infect: weak
Propagate: yes
Observe: yes
Discriminate: weak
Gap:
- No detected boundary input for the changed predicate
- No strong discriminator was detected
Recommended next step:
Add below, equal, and above threshold tests with exact assertions.
Output Formats
Human output is optimized for local use.
JSON output is versioned and intended for editor integrations, CI, and coding agents:
GitHub output emits workflow annotations.
Classifications
| Classification | Meaning |
|---|---|
exposed |
Static evidence suggests a complete RIPR path to a strong oracle. |
weakly_exposed |
A path exists, but infection or discrimination appears weak. |
reachable_unrevealed |
Related tests appear reachable, but no meaningful oracle was found. |
no_static_path |
No static test path was found for the changed owner. |
infection_unknown |
Reachability exists, but input or fixture evidence is opaque. |
propagation_unknown |
The changed behavior crosses an opaque propagation boundary. |
static_unknown |
Syntax-first analysis cannot make a credible judgment. |
Current Scope
The current alpha line is intentionally narrow:
- one published package:
ripr - one CLI binary:
ripr - one shared analysis engine
- syntax-first unified diff analysis
- basic Rust function, test, and assertion indexing
- human, JSON, and GitHub outputs
- experimental LSP sidecar
The package is not split into ripr-core, ripr-cli, or ripr-lsp. Public
crate boundaries can be added later if external consumers need them.
Current Capability Snapshot
ripr is currently strongest as a fast, syntax-first draft signal. The next
planned work is to make findings more grounded through fixtures, file facts,
parser-backed syntax, stable probe ownership, richer oracle facts, local flow,
and activation/value modeling.
| Capability | Current state | Next checkpoint |
|---|---|---|
| Distribution | Crate and extension packaging paths exist. | Verify one-click editor install from a fresh profile. |
| Diff analysis | Syntax-first changed-line probes. | Parser-backed changed-node facts. |
| Test discovery | Basic Rust test/assertion indexing. | AST-backed test and oracle extraction. |
| Output | Human, JSON, GitHub annotation formats. | Golden fixture lab and stable DTOs. |
| LSP | Experimental tower-lsp-server sidecar with evidence-aware diagnostic metadata, related test links, targeted context actions, and diagnostic hovers. |
Server-owned context packets, config propagation, and open-related-test actions. |
| Agent context | Compact context packet. | Test-writing brief with missing values and assertion shape. |
| Calibration | Not yet connected to real mutation outcomes. | cargo-mutants import after static facts improve. |
Development
Useful sample commands: