Find the riskiest file before a release
Rank a directory by risk density, read the signals behind the ranking, and understand what the numbers do and do not claim.
Before a release you want to know where to spend your reading time. A scan answers that in a second, locally, with no model call.
Use Predictive Debugger to find the riskiest files in src/.
A real ranking
This is an actual scan of the Predictive Debugger source tree, trimmed to the top four:
{
"scanned": 28,
"excludedTests": 13,
"orderedBy": "riskDensity",
"files": [
{
"file": "core/analysis/dependencies.ts",
"riskDensity": 0.53,
"riskScore": 0.77,
"lines": 282
},
{
"file": "core/analysis/modulePaths.ts",
"riskDensity": 0.51,
"riskScore": 0.47,
"lines": 83
},
{
"file": "core/prediction/predictFile.ts",
"riskDensity": 0.45,
"riskScore": 0.39,
"lines": 125
},
{
"file": "core/analysis/callees.ts",
"riskDensity": 0.36,
"riskScore": 0.8,
"lines": 522
}
]
}
Density and score are different questions
Look at the first and last rows. callees.ts has the highest risk score
(0.80) but nearly the lowest density (0.36). dependencies.ts is the
reverse.
riskDensity- how concentrated the risk is, per line. This is what the ranking sorts by, because it answers “where is reading time best spent?”riskScore- the total amount of structural risk in the file. A 522-line file accumulates a lot of it simply by being long.
callees.ts is big, so it scores high overall. dependencies.ts packs more
risk into half the lines, so it ranks first. Sorting by score alone would just
rank your longest files.
Read the signals, not the number
Ask for the detail behind a row:
What are the risk signals in src/core/analysis/dependencies.ts?
{
"metrics": {
"functions": 23,
"longFunctions": 1,
"branches": 53,
"asyncCalls": 15,
"nestedLoops": 3,
"mutations": 19,
"tryCatch": 3,
"cyclomatic": 64,
"lines": 282
},
"riskScore": 0.767,
"riskDensity": 0.53
}
The combination that matters here is 15 async boundaries and 19 mutations of
existing state in one file. That is the shape a race condition takes: state
read before an await and written after it. Three nested loops and a cyclomatic
complexity of 64 mean many paths through that state.
None of that proves a bug exists. It tells you what kind of bug this file is built to hide, which is what to look for when you read it.
Tests are excluded on purpose
Note excludedTests: 13 - nearly a third of the tree was skipped. Test files
rank high for a structural reason rather than a real one: mocked awaits read as
async complexity.
If you actually want to audit the complexity of the suite itself:
Scan src/ with Predictive Debugger and include test files.
Narrowing a large tree
scan_project returns 50 files by default and up to 500. On a big repository,
scan the directory you are about to touch rather than the root - a ranking of
the whole monorepo is rarely the question you have.
What the ranking does not mean
Risk density is a reading priority, not a probability that a file contains a defect. A file at 0.53 is not “53% likely to be broken”. A low-density file can still be wrong, and a high-density file can be perfectly correct and simply hard to change safely.