Was der Compiler
nicht sagt
judge liest den aktuellen Quellbaum, die Workspace-Struktur, die öffentlichen APIs und den Abhängigkeitsgraph. Es wiederholt nichts, was Compiler oder Clippy schon melden.
$ cargo judge [WARN] Judge summary Analysis context: boundary rules: 0 not checked (no judge.toml) Evidence: 102 Advisory: 58 Top issue rules: 84x duplicate-code 35x complexity-inflation 14x maintainability-index 9x swallowed-result 5x silent-default
Gemessen am Workspace lightweight-pdf mit 8 Crates und 765 analysierten Funktionen. Dazu 58 Heuristiken, die separat ausgewiesen werden.
cargo judge dupes im Modus mild: 84 Mitglieder in 41 Familien, jede mit Datei, Zeilenbereich und Funktionsnamen. Testcode zählt nur mit --include-tests mit.
Ein konfigurierbarer Trendindex, kein objektives Qualitätsurteil. Aussagekräftig ist die Differenz zu einer Baseline, nicht die absolute Zahl.
Strukturelle Befunde, die erst über den ganzen Workspace sichtbar werden.
judge ist als Cargo-Subcommand gebaut und läuft sowohl als cargo judge als auch als cargo-judge. Es analysiert den ausgecheckten Zustand – keine Commit-Historie, keine Autorenschaft, keine Telemetrie. Ergebnisse gelten für handgeschriebenen, generierten und von Agenten umgebauten Code gleichermaßen.
- 01Deterministisch — gleicher Quellbaum, gleiche Befunde; ohne Netzwerkzugriff, solange man ihn nicht anfordert
- 02Belegt statt geraten — jeder Befund trägt Evidenzklasse, Ort und Begründung
- 03Heuristik getrennt — Advisory-Befunde beeinflussen weder Verdict noch Score
- 04Kein Ersatz — kein Linter, kein Formatter, kein Security-Scanner
Fünf Richtungen, in die judge schaut.
Jede Kategorie ist ein eigenes Subcommand und zugleich Teil des kombinierten Laufs – außer denen, die ausdrücklich Opt-in sind.
- 01
Duplikate
dupesgruppiert wiederholte Token-Spannen zu Klon-Familien, in vier Modi vonstrictbissemantic. Absichtliche Duplikate lassen sich mit// judge-dupe-ignore: <Grund>vor der Funktion begründen – ohne Grund greift die Direktive nicht. - 02
Komplexität und Wartbarkeit
complexityundhealthliefern zyklomatische Komplexität je Funktion und einen Maintainability-Index je Datei. Produktions- und Testcode bleiben getrennt. - 03
Toter Code
dead-codegehört zum Deep Tier und meldetunused-pub-workspace:pub-Items ohne Referenz aus einer anderen Workspace-Crate und ohne Erreichbarkeit von einem erkannten Einstiegspunkt. Das heißt „keine Nutzung in der untersuchten Sicht“, nicht „bewiesen tot“. - 04
Dependency-Hygiene
depsprüft Abhängigkeitsarten, Feature-Flags und lokale Namenskollisionen. crates.io-Abfragen und der Abgleich mit einem bereits erzeugtencargo audit --jsonsind Opt-in – judge ruft cargo-audit nicht selbst auf. - 05
API-Fläche und Grenzen
apizeigtundocumented-public-itemundsemver-hazard.boundariesprüft Crate-Grenzen aus einerjudge.tomlund findet Zyklen; ohne Konfiguration tut es nichts.
Drei Ausgaben aus einem echten Lauf.
$ cargo judge dupes
mode: mild
min tokens: 20
clone families: 41
refactoring summary: 41 clone families, 84 members (repeated tokens, not an automatic merge recommendation)
#1 3 members × 22 tokens = 66 repeated tokens across 2 files collect_anchors_in_node, collect_headings_in_node, collect_anchor_pages_in_node
#2 3 members × 20 tokens = 60 repeated tokens across 1 files layout_rich_text, layout_rich_text, layout_text_fixed_overflow
#3 2 members × 66 tokens = 132 repeated tokens across 1 files layout_row_cells, render_cells_starting_at
#4 2 members × 63 tokens = 126 repeated tokens across 1 files hard_break_word, hard_break_styled_word
#5 2 members × 59 tokens = 118 repeated tokens across 1 files natural_row_heights, apply_rowspan_deficits$ cargo judge deps
dependency findings: 5
[unused-feature-flag] lightweight-pdf serde
[heavy-dependency] lightweight-pdf-cli lightweight-pdf
[workspace-dep-drift] ? png
[workspace-dep-drift] ? schemars
[workspace-dep-drift] ? serde
feature-only candidates (no code usage found; see unused-feature-flag findings above for detail): serde$ cargo judge health --score
functions analyzed: 765
slop signals: 14 (52 advisory)
swallowed-result: 9
suppression-debt: 2
complexity-inflation: 35
maintainability-index: 14
abstraction-inflation: 1
integer-cast-risk: 2
panic-in-lib: 3
health score: 97.8 (A) — 16026 authored LOC, 0 fail, 12 warn, 57 advisory (not scored)Installieren, laufen lassen, festschreiben.
- 1Installieren
Von crates.io
Braucht Rust 1.95 oder neuer (Edition 2024). Alternativ aus dem Repository bauen oder
cargo install --path ..cargo install cargo-judge - 2Laufen lassen
Kombinierter Bericht
Die Standardansicht gruppiert nach Regel und zeigt je Gruppe einen Beispielort.
--detailslistet jeden Befund,--format jsonschreibt das vollständige Artefakt.cargo judge - 3Festschreiben
Baseline setzen
Die Baseline ist eine Datei, kein Git-Stand. Danach zählt nur noch, was gegenüber diesem Stand neu dazukommt.
cargo judge --save-baseline
Warum zwei Läufe dasselbe ergeben.
Ohne die Opt-in-Flags von deps macht judge keine Netzwerkaufrufe. Damit hängt das Ergebnis nicht am Zeitpunkt des Laufs.
compare vergleicht den aktuellen Zustand mit einer gespeicherten Artefaktdatei und funktioniert auch ohne Git.
Jede JSON-Datei beginnt mit einem header aus Arbeitsverzeichnis, Ausgabepfad, Zeitstempel, Kommandobeschreibung und Einschätzung.
Ein Trend wird nur gezeigt, wenn die Baseline mit derselben Score-Formelversion und denselben Crate-Profilen entstanden ist. Sonst meldet judge „nicht vergleichbar“ statt einer falschen Differenz.
Ein Job, zwei Artefakte.
# .github/workflows/judge.yml
name: judge
on: [pull_request]
jobs:
judge:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- run: cargo install cargo-judge
# schlägt fehl, sobald gegenüber der Baseline etwas Neues auftaucht
- run: cargo judge --baseline .judge/baseline.json
# SARIF 2.1.0 geht auf stdout, z. B. für Code Scanning
- run: cargo judge --format sarif > judge.sarifWas judge bewusst nicht übernimmt.
| Kriterium | judge | Clippy | cargo-audit |
|---|---|---|---|
| Sichtweite | Workspace, dateiübergreifend | Datei und Ausdruck | Abhängigkeitsgraph |
| Duplikate über Crates hinweg | ja | nein | nein |
| Bekannte Sicherheitslücken | nur Abgleich mit vorhandenem Report | nein | ja, eigene Quelle |
| Baseline mit Verdict | ja | nein | nein |
| Braucht einen Build | nur im Deep Tier | ja | nein |
judge ersetzt keines der beiden Werkzeuge. Die Regel im Repository lautet: Was Compiler oder Clippy schon melden, wiederholt judge nicht.
Fast Tier und Deep Tier.
- Standard
Fast Tier
Analyse über
syn,cargo metadataund die Manifeste. Kein Build des Projekts nötig, daher schnell genug für jeden Pull Request. - Opt-in
Deep Tier
Lädt den Workspace in rust-analyzer, um mit echten Referenzdaten statt Syntax-Vermutungen zu arbeiten. Der Build der
ra_ap_*-Crates dauert spürbar länger. - Übergabe
Artefakte
Versioniertes JSON auf jedem Report-Kommando, SARIF 2.1.0 für Code Scanning, Markdown für Pull-Request-Beschreibungen. Ein separater MCP-Adapter reicht die JSON-Ausgabe an Assistenten weiter.
Das Verdict, auf das CI hört.
$ cargo judge --save-baseline
$ cargo judge compare .judge/baseline.json
verdict: pass
unchanged: 160
resolved: 0
introduced: 0
introduced advisory (heuristic — no verdict effect): 0
severity changed: 0Was die Analyse nicht leistet.
Die Befunde sind Belege, keine Urteile. Vier Einschränkungen, die judge selbst benennt.
Toter Code ist nicht bewiesen tot
unused-pub-workspace heißt „keine Nutzung in der untersuchten Sicht gefunden“. Der Workspace wird ohne Proc-Macro-Server und ohne build.rs-Ausführung geladen, generierter Code ist also unsichtbar.
Der Score ist ein Trendindex
Kein objektives Qualitätsranking. Ohne Basis zur Berechnung meldet judge den Score als nicht verfügbar und beendet sich mit Code 2 – statt eine perfekte Zahl zu erfinden.
Früh im Projekt
Der Fast Tier ist umgesetzt, vom Deep Tier ein erster Ausschnitt. Modulgrenzen und mehrere geplante Regeln für Wartbarkeit und Dependency-Hygiene fehlen noch.
Duplikate brauchen Urteilskraft
Eine Klon-Familie ist eine Beobachtung wiederholter Token, keine automatische Empfehlung zum Zusammenführen. refactor erzeugt deshalb nie einen Patch.
cargo-judge oder eine abgewandelte Fassung Dritten als gehosteten Dienst oder als Konkurrenzprodukt anzubieten. Jede Version wechselt vier Jahre nach ihrer Veröffentlichung zu Apache 2.0.Lizenztext im Repository →- Rust-Workspaces mit mehreren Crates
- Reviews nach großen Refactorings
- Pull-Request-Gates
- Übergaben zwischen Teams
- Coding-Agenten als Leser
Häufige Fragen.
Ersetzt judge Clippy?
Nein. Die Regel im Repository lautet: Was Compiler oder Clippy bereits melden, wiederholt judge nicht. Es deckt strukturelle und dateiübergreifende Fragen ab, die erst über einen ganzen Workspace sichtbar werden.
Welche Exit-Codes gibt es?
0 für einen sauberen Lauf, 1 wenn Befunde gemeldet werden, 2 bei einem Fehler oder einer unvollständigen Analyse. Im Lauf gegen lightweight-pdf am 16.09.2026 war der Exit-Code 0, obwohl 102 belegte Befunde ausgewiesen wurden: keiner davon hatte den Schweregrad fail.
Wie verhindere ich, dass CI an Altlasten scheitert?
Mit einer Baseline. cargo judge --save-baseline schreibt den aktuellen Stand nach .judge/baseline.json, danach bewertet cargo judge --baseline nur noch, was gegenüber diesem Stand neu ist. Die Baseline ist eine Datei und braucht kein Git.
Liest judge meine Commit-Historie?
Nein. Die Analyse betrachtet den ausgecheckten Quellbaum, die Workspace-Struktur, die öffentlichen APIs und den Abhängigkeitsgraph. Autorenschaft, Commit-Historie, Telemetrie und Code-Provenienz sind ausdrücklich nicht Teil davon, und compare vergleicht gegen eine Artefaktdatei statt gegen eine Revision.
Was ist der Unterschied zwischen Evidence und Advisory?
Evidence-Befunde sind an nachprüfbaren Belegen festgemacht und wirken auf Verdict und Score. Advisory-Befunde sind reproduzierbare Interpretationen, also Heuristik: sie werden separat ausgewiesen und beeinflussen weder Verdict noch Score.
Kann ein Coding-Agent die Ausgabe nutzen?
Ja, dafür ist sie mitgedacht. Jedes Report-Kommando kann versioniertes JSON schreiben, und im Verzeichnis judge-mcp liegt ein schlanker stdio-Adapter, der ein bereits gebautes cargo-judge-Binary aufruft und dessen JSON als MCP-Tool-Aufrufe zurückgibt. Er rechnet selbst nichts und ist keine Voraussetzung für judge.
Einmal laufen lassen, dann eine Baseline setzen.
Der erste Lauf braucht keinen Build des Projekts und keine Konfiguration.