Unused imports
A module loaded that nothing calls. Every one is read, parsed and loaded on every run.
import io # nothing uses it
Does the AI assistant actually pay off?
Justify reads a whole repository and asks every import, function, class and dependency one question: why are you here? What cannot answer is dead weight. Justify finds it, shows how much came from AI-assisted commits, and removes it only with proof.
Auditing
For private code, or a repository this large, run Justify on your own machine — see install locally.
Audit statement
Justified Line Ratio
%
Authorship could not be traced for this repository.
Nothing matches.
REMOVE means no use was found anywhere in the repository. The hosted audit never runs code, so nothing here is proved yet — Justify proves removals with your own tests when you run it locally.
What it finds
Dead weight never breaks anything — that is why it survives. An assistant writes for the prompt in front of it, not for the codebase it cannot see, so it leaves these behind:
A module loaded that nothing calls. Every one is read, parsed and loaded on every run.
import io # nothing uses it
A helper with no callers anywhere in the repository — kept alive only because nobody checked.
def clock_time(): # 0 callers
The same job written twice, because the assistant could not see the first one.
def fmt_date(d) ≡ def format_date(d)
A package installed that no file imports — one more thing to download, patch and audit.
leftpad==1.0 # no file imports it
How it works
A code graph proposes, a model is asked why, a second call tries to prove it wrong, the tests decide, and a person approves. Doubt always means keep.
This site stages 1–3, authorship and the score — public repositories, read-only.
Your machine stages 4–6 — your model, your tests, your private code.
What we measured
We ran Justify on five public repositories with AI-assisted commits — 3,247 files, 989,614 lines — and split every finding by who wrote it.
Static stages and authorship, no proof. AI-assisted = commits with an assistant trailer, a lower bound. Rework is counted from the first AI-assisted commit.
Model Context Protocol
The assistant that writes the code can call Justify before it hands the code over. One URL — no account, no key.
The hosted audit reads public repositories and never runs anything. To audit private code, and to prove each removal by running your own tests on a temporary copy, run Justify on your machine:
pip install "justify-code[mcp] @ git+https://github.com/BPSKartik/justify"
justify scan . --prove "python -m pytest -q"
Questions
No. It proposes. On your machine it removes code only in a temporary copy, runs your tests there, and writes a report. A person approves every change. The model can veto a removal; it can never force one.
It clones the public repository, reads it, traces each line to an AI-assisted or human commit, and deletes the clone. It never runs the repository's code or tests and never sends it to a model. Results are cached by commit.
From commit trailers the assistants write themselves, like Co-Authored-By: Claude or Co-authored-by: Copilot. An assistant used without a trailer counts as human, so the AI share is always a lower bound.
The share of lines that are not dead weight: lines left after removing everything with no use anywhere, divided by all lines. A team can track it per repository, per quarter, and split by authorship.
A linter looks at one file and asks whether a name is used. Justify looks at the whole repository, asks whether the code is worth keeping, explains why with a file and line, proves removals with your tests, and splits the result by who wrote it.
Python today. The parsing layer is built to take tree-sitter for more languages next.