Static mutation-exposure analysis — which changed behavior your tests run but don't actually check.
ripr shows your agents where tests are needed and which tests are too weak to trust — without running mutation testing.
- Rust ≥ 1.95 (2024 edition). Check with
rustc --version; update withrustup update stable. - Git on your
PATH. - Run inside a Git repository. By default, ripr looks for
origin/main,origin/master,main, ormasteras the diff base; pass--base <ref>when you need a different base.
The agent loop is a simple three-step flow:
gap → fix → verify
ripr names a gap (changed behavior lacks a focused assertion or discriminator)
the agent adds one focused test
ripr records whether the gap improved, closed, or still needs attention
You work in five key terms. Everything else in this README and the reference docs expands on them:
| Term | One-line meaning |
|---|---|
| gap | a place the code needs a test (or an existing test is too weak) |
| card | the per-gap unit an agent acts on — what to assert, where, and why the current proof is weak |
| packet | the bundle of evidence and guidance for one change (a bounded, test-only work order) |
| verify | re-check that a fix actually closed the gap |
| receipt | the durable before/after proof of what was checked |
cargo install ripr
ripr check --base origin/mainripr check is the ordinary first-value command: it analyzes the current
change and returns one bounded Start here: route — a named state, one selected
gap or safe next action, the omitted-finding count, and explicit pointers to
--format human-full for exhaustive evidence and --format json for machine
data. ripr.toml is optional; the zero-config run is the intended first
interface.
When the selected gap is repair-ready, use the dedicated two-phase transaction:
ripr agent repair --root . --seam-id <id> --phase before
# edit one focused test outside ripr
ripr agent repair --root . --seam-id <id> --phase afterRIPR owns the before/after evidence plumbing. The human or external coding agent
owns the focused test edit. ripr pilot --root . remains the guided
repository-adoption workflow. ripr first-pr --root . --base origin/main --head HEAD composes existing artifacts into PR-facing evidence; it is not the
analyzer or repair driver.
See the public command hierarchy for the stable task boundaries.
Internal vocabulary and capability detail live here and below. The first screen above is all a new user or agent needs to start.
ripr reads a PR diff and tells your reviewers and coding agents which changed
behavior the current tests reach but don't actually check — the question
mutation testing answers, asked at draft time without running a single mutant.
Where a test would not catch the change breaking, it routes one focused,
test-only repair: what to assert, where, the command that verifies it, and a
before/after receipt.
coverage: did this line run?
ripr: would any test notice this changed behavior breaking?
mutation testing: did a test fail when a real mutant ran?
ripr is static and advisory. It does not run mutants, report killed or
survived, replace coverage, or claim correctness or test adequacy. It names
the changed behavior that lacks a discriminator and the next test to add; a real
mutation runner like cargo-mutants confirms it under execution when the change
is ready. Coverage stays the execution-surface signal; ripr is the cheaper
draft-time question between them.
| Term | What it is |
|---|---|
| gap | a changed behavior whose tests are too weak to notice it breaking, with a stable canonical ID |
| card | the repair — what to assert, where, and why the current proof is weak |
| packet | a bounded, test-only work order for a human or agent: allowed files, forbidden files, stop conditions |
| verify | the focused command that checks the repair (cargo test …, pytest …) |
| receipt | the before/after record of whether the gap actually closed |
Illustrative bounded ripr check --format human output (paths shortened):
Start here:
State: top_gap
Safe next action: inspect or repair the selected non-exposed gap; this is static advisory evidence only.
File: src/lib.rs:2
Static exposure: weakly_exposed (warning, confidence 0.92)
Why weakly_exposed: the evidence path is partially complete — see full form for details
Changed behavior: if amount >= discount_threshold {
Missing discriminator: amount == discount_threshold
Related test: tests/pricing.rs:4 below_threshold_has_no_discount
Next step: Add boundary tests for below, equal, and above the changed threshold with exact assertions.
Evidence:
- reach yes: Related tests appear to reach discounted_total: below_threshold_has_no_discount, far_above_threshold_discounts
- infection weak: Related tests contain input values, but the equality-boundary discriminator is missing
- 12 more evidence line(s) hidden
Next: drill into the top finding:
ripr explain --root . --diff diff.patch --mode fast probe:src_lib.rs:predicate:c80557eb
ripr context --root . --diff diff.patch --mode fast --at probe:src_lib.rs:predicate:c80557eb
More:
Full evidence: rerun with --format human-full
Machine data: rerun with --format json
When lower-priority findings were omitted, that last block instead reads:
Hidden:
12 lower-priority finding(s) omitted from default human output.
Full evidence: rerun with --format human-full
Machine data: rerun with --format json
The wording is intentionally conservative: static analysis identifies evidence and gaps; it does not claim runtime mutation outcomes.
| You are a… | First action | Doc |
|---|---|---|
| VS Code user | Install EffortlessMetrics.ripr, open a Rust workspace, use the status bar, Problems, and hover evidence. |
Quickstart |
| CI owner | ripr init --ci github for an advisory PR summary and artifact packet. |
Quickstart |
| CLI user | ripr check --base origin/main, then repair the selected named gap. |
Quickstart |
| Agent operator | ripr agent repair --seam-id <id> --phase before, then finish after the focused test edit. |
LLM operator guide |
The mature loop is Rust/Cargo. Python repair-routing is usable alpha for
selected pytest/unittest workflows (repair cards, verify commands, bounded
agent packets, before/after receipts); TypeScript is an opt-in preview. ripr
is advisory static analysis — not a merge gate and not a mutation runner. This
Perl repair routing is still planned/advisory; its next checkpoint is
dogfood/perl-real-repo-evals-v1 before any usable-alpha claim. This README is
a front door, not the metric source of truth: see
Support tiers for what is usable, preview, or
advisory, and the Capability matrix and
Metrics for detailed state. ripr-swarm is the development trunk; source
EffortlessMetrics/ripr is the
release and distribution authority.
| Need | Doc |
|---|---|
| Choose the first-hour path by surface | Quickstart |
| Understand the public command roles | Command hierarchy |
| Map plain language to the internal model | Terminology |
| Understand the model (discrimination vs coverage) | Static exposure model |
| Know what is usable / preview / advisory | Support tiers |
| Understand JSON / context output | Output schema |
| Turn a gap into a test | Targeted test workflow |
| Prove one real PR's adoption | First successful PR workflow |
| Install and use the editor extension | Editor extension |
| See behavior contracts and architecture | Specs · Architecture · ADRs |
| Follow direction and active work | Roadmap · Plan · Campaigns · Codex Goals |
| Contribute a scoped PR | Contributing · Scoped PR contract · PR automation |
| Everything else | Documentation index · Documentation system |
Use the repo automation rather than remembering the gate order:
cargo xtask shape # safe local normalization
cargo xtask check-pr # the review-ready gateA good ripr PR is scoped by production risk, not line count: one production
delta plus its complete evidence package, preserving the
spec -> test -> code -> output contract -> metric chain. Large fixture,
golden, spec, or docs diffs are welcome when they make one production behavior
reviewable.
See Contributing, Scoped PR contract, and Agent instructions.
EffortlessMetrics/ripr-swarmis the public same-repo development landing zone for trusted agent and maintainer PRs. Package publishing, marketplace publishing, GitHub Releases, and public distribution authority remain inEffortlessMetrics/ripr. See Swarm development.
ripr is licensed under MIT OR Apache-2.0, at your option.
It targets Rust 2024 and requires Rust 1.95 or newer.