Measure — and catch at creation — code your team no longer understands.
Project description
____ ____ _____ ____ _____
/ ___| _ \| ____| __ )_ _|
| | | | | | _| | _ \ | |
| |___| |_| | |___| |_) || |
\____|____/|_____|____/ |_|
know which code nobody on your team understands — before it pages you at 2 a.m.
what is this
AI writes code 5–7× faster than anyone can actually read it. Tests pass, velocity looks great, everyone's happy — until something breaks and you realize nobody can explain the file it broke in. That gap has a name now (Google's Addy Osmani called it comprehension debt in March 2026), and cdebt is a tool that measures it, blocks it at the door, and helps you pay it off in ~3 minutes per file.
It's not another linter. It doesn't care if your code is "clean." It cares whether a named human can prove they understand it.
One formula, no magic:
debt(file) = difficulty × exposure × (1 − verified understanding)
Every score comes with the evidence that produced it. If the data doesn't exist, the component stays silent — honest by default.
get it running (60 seconds)
git clone https://github.com/RonaldSit/comprehension-debt && cd comprehension-debt
pip install .
cd /path/to/any/git/repo
cdebt scan . # 0–100 risk per file, with the WHY
cdebt scan . --html report.html # same thing, but pretty
Python ≥ 3.9. Two deps (lizard, numpy). No server, no account, no network — everything runs locally on your git history. Works on a local folder or straight off a URL: cdebt scan https://github.com/org/repo.
how you'd actually use it
You're a dev. The gate runs in CI (action.yml is included). Clean PRs pass silently. When it blocks you, that means you shipped something complex that nobody has demonstrably understood — so:
cdebt repay . # drafts an ADR + 3 questions about YOUR file
cdebt confirm . thefile.py -i # answer in your own words; answers get graded against the code
Generic AI-pasted answers score 0 (they never name the file's actual identifiers — that's their tell). "I don't know" also scores 0, and that's fine: the honest signal is the point. Learn the file first (ask Claude to walk you through it!), then confirm what you verified.
You're the lead. Once a week:
cdebt scan . --save-baseline # remember today
cdebt trend # is the dark stuff growing?
cdebt repay . --path scary.py # schedule the worst file into the sprint
Repo full of AI code with no commit trailers? Declare it honestly: echo '{"assume_ai": true}' > cdebt.json && cdebt scan . --config cdebt.json. Files someone already verified are exempt — we never punish the people who did the right thing.
Something's on fire. Wire Sentry/PagerDuty into cdebt serve, or cdebt ingest . --payload incident.json. The moment an incident lands, the terminal tells you who actually understood the blamed file and shows their explanation, in their words. Then cdebt calibrate . scores the score itself against your incident history — including a Miss Ledger of every bug it under-rated, with its likely blind spot. We keep our own receipts.
receipts (run them yourself, please)
- 54 self-checks, one command, no network, ~1 min:
python tests/test_suite.py— covers every command, the anti-faking grader, corrupt stores, concurrency, unicode filenames, the works. - Real-bug benchmark, zero lookahead: on 84 real historical bugs from the peer-reviewed BugsInPy dataset (tqdm, thefuck, fastapi, youtube-dl), the buggy file ranked in our top quartile 93% of the time — 3.7× random. fastapi and youtube-dl: 16/16 and 43/43. Reproduce it:
git clone --depth 1 https://github.com/soarsmu/BugsInPy /tmp/BugsInPy
python benchmarks/bugsinpy_bench.py --bugsinpy /tmp/BugsInPy --project fastapi
- Scale: 100,000-file monorepo → cold scan 22 s, warm 6 s, ~540 MB RAM, deterministic.
- Multi-user: concurrent confirms are lock-protected; 4 parallel writers, zero lost updates (it's check #54).
what it costs
$0. Local git + AST + numpy. The only optional paid bit is --llm (Claude drafts the ADR and grades answers against the code) — that reads your own ANTHROPIC_API_KEY, ≈ $0.02–0.03 per confirmation, and everything works without it.
what it deliberately does NOT do
It doesn't find bugs (SAST does that). It doesn't judge style (linters do that). It doesn't replace review bots (it consumes their output as a signal). And it can't catch "simple but wrong" — a trivial file with a wrong constant scores low, and when one of those causes an incident, the Miss Ledger says so out loud. See VALIDITY.md for exactly what the score claims and what it doesn't.
the 15 commands
scan · gate · report · audit · trend · repay · confirm · reverify · calibrate · ingest · serve · recalibrate · reviews · explain · prsignals — each has --help. Longer walkthrough in USAGE.md.
Apache-2.0. Built solo, bug ledger currently at 27 (every one has a regression test now). If it breaks, open an issue — I answer.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file comprehension_debt-0.13.2.tar.gz.
File metadata
- Download URL: comprehension_debt-0.13.2.tar.gz
- Upload date:
- Size: 69.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
11e6c464aa544913bb90527cb58ea52ed172baa6020ba671d819463d44420381
|
|
| MD5 |
c63b4da8345f62c3fce93b554d8047e7
|
|
| BLAKE2b-256 |
d83fe132898081b777132f95469e64f300fa036d3a0c8a7c2059aea85baff380
|
File details
Details for the file comprehension_debt-0.13.2-py3-none-any.whl.
File metadata
- Download URL: comprehension_debt-0.13.2-py3-none-any.whl
- Upload date:
- Size: 69.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
17e4a52036b892eccbc0f5b4b03d3a720557ca63369a02a88dfa84293d249d1c
|
|
| MD5 |
e939cf348ddc82f413bbe0a9d5076a6c
|
|
| BLAKE2b-256 |
6eb1755c158648c79154071a9b292485005bbca8d38c9509245da042cff90e6c
|