judgev0.7.1

CASOON Open Source

Know what a refactoring left behind.

The refactoring compiles and Clippy is quiet, yet something is off. judge reads your Rust workspace, reports what the change left behind with the evidence for every finding, and tells CI whether it made things worse.

cargo install cargo-judge
BUSL-1.1v0.7.1Rust 1.95+offline by default
Terminal, excerpts of two real judge 0.7.0 runs on its own source tree. cargo judge prints the start of the Judge summary: 671 evidence and 333 advisory findings, top rules duplicate-code (635), complexity-inflation (243), integer-cast-risk (39), maintainability-index (39) and panic-in-lib (22). cargo judge compare .judge/baseline.json then prints the count lines: verdict fail, unchanged 934, resolved 45, introduced 56, introduced advisory (no verdict effect) 14, severity changed 0. The full output of both runs is in the showcase.

Who it is for

rules, each with a declared evidence class
78
of them can fail a verdict; 29 are advisory only
49
output formats: terminal, JSON, SARIF and Markdown
4
network calls by default; crates.io checks are opt-in
0

How the CI verdict works

Run judge once on a tree you accept and save its findings as a baseline. On every later tree, cargo judge compare sorts the findings into unchanged, resolved and introduced.

Only introduced findings that are backed by evidence and carry warning or failure severity fail the verdict and the exit code. Heuristic findings are listed, but never block a merge.

From baseline to CI verdictcargo judge --save-baseline writes the findings of an accepted tree to .judge/baseline.json. cargo judge compare checks a later tree against it and sorts the findings into unchanged, resolved and introduced. If an introduced finding is gating and has warning or failure severity, the verdict fails and judge exits with 1; otherwise the verdict passes and judge exits with 0. Introduced advisory findings are listed but never change the verdict.From baseline to CI verdictAccepted tree → baseline.json: writesbaseline.json → cargo judge compare: readsLater tree → cargo judge compare: analysescargo judge compare → New gating findings?New gating findings? → verdict: fail: yesNew gating findings? → verdict: pass: nowritesreadsanalysesyesnoAccepted tree – cargo judge --save-baselineAccepted treecargo judge --save-baselinebaseline.json – in .judge/baseline.jsonin .judge/Later tree – after the refactoringLater treeafter the refactoringcargo judge compare – unchanged, resolved, newcargo judge compareunchanged, resolved, newNew gating findings? – warning or failure severityNew gating findings?warning or failure severityverdict: fail – exit 1verdict: failexit 1verdict: pass – exit 0verdict: passexit 0
From baseline to CI verdictcargo judge --save-baseline writes the findings of an accepted tree to .judge/baseline.json. cargo judge compare checks a later tree against it and sorts the findings into unchanged, resolved and introduced. If an introduced finding is gating and has warning or failure severity, the verdict fails and judge exits with 1; otherwise the verdict passes and judge exits with 0. Introduced advisory findings are listed but never change the verdict.From baseline to CI verdictAccepted tree → baseline.json: writesbaseline.json → cargo judge compare: readsLater tree → cargo judge compare: analysescargo judge compare → New gating findings?New gating findings? → verdict: fail: yesNew gating findings? → verdict: pass: nowritesreadsanalysesyesnoAccepted tree – cargo judge --save-baselineAccepted treecargo judge --save-baselinebaseline.json – in .judge/baseline.jsonin .judge/Later tree – after the refactoringLater treeafter the refactoringcargo judge compare – unchanged, resolved, newcargo judge compareunchanged, resolved, newNew gating findings? – warning or failure severityNew gating findings?warning or failure severityverdict: fail – exit 1verdict: failexit 1verdict: pass – exit 0verdict: passexit 0
From baseline to CI verdictcargo judge --save-baseline writes the findings of an accepted tree to .judge/baseline.json. cargo judge compare checks a later tree against it and sorts the findings into unchanged, resolved and introduced. If an introduced finding is gating and has warning or failure severity, the verdict fails and judge exits with 1; otherwise the verdict passes and judge exits with 0. Introduced advisory findings are listed but never change the verdict.From baseline to CI verdictAccepted tree → baseline.json: writesbaseline.json → cargo judge compare: readsLater tree → cargo judge compare: analysescargo judge compare → New gating findings?New gating findings? → verdict: fail: yesNew gating findings? → verdict: pass: nowritesreadsanalysesyesnoAccepted tree – cargo judge --save-baselineAccepted treecargo judge--save-baselinebaseline.json – in .judge/baseline.jsonin .judge/Later tree – after the refactoringLater treeafter therefactoringcargo judge compare – unchanged, resolved, newcargo judgecompareunchanged,resolved, newNew gating findings? – warning or failure severityNew gatingfindings?warning orfailure severityverdict: fail – exit 1verdict: failexit 1verdict: pass – exit 0verdict: passexit 0
From baseline to CI verdictcargo judge --save-baseline writes the findings of an accepted tree to .judge/baseline.json. cargo judge compare checks a later tree against it and sorts the findings into unchanged, resolved and introduced. If an introduced finding is gating and has warning or failure severity, the verdict fails and judge exits with 1; otherwise the verdict passes and judge exits with 0. Introduced advisory findings are listed but never change the verdict.From baseline to CI verdictAccepted tree → baseline.json: writesbaseline.json → cargo judge compare: readsLater tree → cargo judge compare: analysescargo judge compare → New gating findings?New gating findings? → verdict: fail: yesNew gating findings? → verdict: pass: nowritesreadsanalysesyesnoAccepted tree – cargo judge --save-baselineAccepted treecargo judge--save-baselinebaseline.json – in .judge/baseline.jsonin .judge/Later tree – after the refactoringLater treeafter therefactoringcargo judge compare – unchanged, resolved, newcargo judgecompareunchanged,resolved, newNew gating findings? – warning or failure severityNew gatingfindings?warning orfailure severityverdict: fail – exit 1verdict: failexit 1verdict: pass – exit 0verdict: passexit 0

Fast tier or deep tier

One more build step, real reference data

The default Fast Tier needs no build step and reads the tree as written. Compiling in rust-analyzer itself, behind the deep Cargo feature, lets dead-code and explain --why-live work from real reference data instead of syntax-level guesses.

  • Dead code, with evidence. dead-code reports unused-pub-workspace — no reference from another workspace crate and no reachability from a recognised entry point, not proof.
  • Why something is still live. explain --why-live prints the shortest evidenced route from fn main, a test or an FFI boundary to the item, each edge classified as static, dynamic, macro, generated or unknown.
  • The build cost is upfront, not per run. Compiling the ra_ap_* crates takes noticeably longer once; cargo judge inspect confirms deep: available afterward.
Deep Tier
cargo install cargo-judge --features deep
cargo judge inspect                      # "deep: available"

cargo judge dead-code
cargo judge explain my_crate::parser::parse --why-live

Quickstart

Install it, run it in the workspace root, and turn the result into a baseline for CI. Crate boundaries in judge.toml, the output formats and the rust-analyzer deep tier are covered in the documentation.

  1. Install cargo-judge from crates.io with the line above.
  2. Run cargo judge in the workspace root for the grouped triage report.
  3. Save a baseline and let CI run cargo judge compare against it.
Three commands
cargo judge                    # triage report
cargo judge --save-baseline    # accept this state
cargo judge compare .judge/baseline.json

New in v0.7.1

Changelog →

Frequently asked questions

What does judge check that Clippy and the compiler don't?

Structural and cross-file concerns that only become visible across a workspace — duplicated code, complexity concentration, public API surface and dependency hygiene. Anything the compiler or Clippy already tells you, judge does not repeat.

Does judge look at Git history or who wrote the code?

No. It analyzes only the current source tree, workspace structure and dependency graph, never commit history, authorship or telemetry, so human-written and agent-refactored code get the same findings.

How does the CI verdict work?

Save a baseline from a tree you accept with --save-baseline, then run cargo judge compare against it in CI. Only new findings backed by evidence and warning or failure severity fail the verdict; heuristic findings are listed but never block a merge.

What is the Deep Tier, and do I need it?

The default Fast Tier needs no build step. The Deep Tier, behind the deep Cargo feature, loads the workspace into rust-analyzer for dead-code and why-live analysis, at the cost of a noticeably longer build.

Does judge make network calls?

Not by default. Dependency checks against crates.io, such as phantom or yanked dependencies, are opt-in via --check-crates-io, and judge never runs cargo-audit itself.

Your first report in a few minutes.

Read the quickstart