CHANGE RISK GUIDE

Change Risk & PR Review: Catch the PRs That Break Things Before You Merge

How repowise scores change risk and blast radius deterministically from the real dependency graph and git history, then turns it into will_break, missing_cochanges, and missing_tests directives you act on before merge.

depth 3
Reverse-dependency BFS over the real graph finds every importer of your change
0
LLM calls in scoring — the same diff scores the same every time, no drift
3
PR directives (will_break, missing_cochanges, missing_tests) turn a score into a checklist
<30s
Incremental re-score on a new push, against the already-indexed graph
By Raghav ChamadiyaUpdated June 2026 · 11 min
TL;DR

repowise scores any commit or base..head diff from 0 to 10 deterministically, with no LLM, so the same diff always scores the same. Blast radius traces every dependent of your change through the real dependency graph with a reverse-dependency BFS to depth 3, and in PR mode the score ships with directives — will_break, missing_cochanges, missing_tests — so review is a checklist, not a guess. The Repowise PR Bot is silent by default: a green PR gets no comment.

DEFINITION

Change risk is a deterministic 0-10 defect-risk score for any commit or diff range, computed from the shape of the change and the history of the files it touches. Blast radius is every file downstream of that change, traced through the real dependency graph rather than guessed, so you see what might break, not just the lines you edited.

Repowise PR Bot comment showing a 0-10 change-risk score, the blast-radius file list, and a missing_tests directive on a pull request
One deterministic comment, only when there's something worth saying — no LLM in the path.

Why does change risk matter?

Most breakage hides in files the diff never touched. A reviewer reading the diff sees the lines that changed; they do not see the importers, the co-change partners, or the test that quietly went missing.

A diff cannot tell you what it might break, what usually changes alongside it, or whether the tests went missing. repowise reads the change and the graph and turns that into one score plus a checklist of exactly what to look at.

  • The risky PRs look like the safe ones, until something fails in production.
  • Import-based blast radius is invisible in a diff: your change can break a file you never opened.
  • Co-change coupling has no import link at all, so no static tool will warn you.

How does change risk work?

repowise fuses two signals static analysis cannot blend on its own: graph topology (who imports what) and git history (what moves together over time). The result is one score plus a directive block.

The engine runs the same way every time, with no model in the loop.

StageWhat happensSource signal
Read the diffTake any commit or base..head range; nothing is sent anywhereDiff shape
ScoreKamei-style just-in-time metrics fold size, entropy, scatter, and file history into one 0-10 bandGit history + diff
Blast radiusReverse-dependency BFS over the graph to depth 3 finds every importer of the changed filesDependency graph
Co-changeHistorical partners that move together without an import link are surfacedGit history
DirectEmit the directives plus suggested reviewersGraph + history + ownership

In PR mode the score ships with a directive block — read it first. Each directive points at a verifiable thing.

DirectiveWhat it flagsSource signal
will_breakDependents downstream of your change — the importers you did not open, centrality-rankedDependency graph (reverse-dependency BFS, depth 3)
missing_cochangesA changed file's historical co-change partners that are not in the diffGit history (co-change partners)
missing_testsChanged risky files with no accompanying test changeDiff + test-file matching (coverage optional)

Three things to know about the engine:

  • Deterministic, zero-LLM. The score is computed from the diff and the graph; no model in the loop, no drift, no token bill, no prompt-injection surface.
  • Reverse-dependency BFS. Blast radius walks the graph edges from the changed set outward to depth 3, collecting every file that imports your change.
  • Co-change from git. Partners come from the co-change history mined from your repo, so the hidden coupling no AST sees is still caught.

How does change risk help you?

Three outcomes: safer merges, faster review triage, and catching the co-changes and tests a diff silently dropped. Each maps to a directive.

will_break: dependents the change is likely to affect

will_break lists the files downstream of your change in the dependency graph — the importers you did not open. It answers "what else touches this?" from real edges, not a guess.

  • Computed by reverse-dependency BFS over the import graph to depth 3.
  • Each dependent is ranked by centrality, so the high-PageRank consumers surface first.
  • Doubles as reviewer routing: the top owners of affected files become suggested reviewers.
repowise blast radius graph showing direct and transitive dependents of a changed file out to depth 3
Blast radius — every dependent, traced from the real dependency graph, not heuristics.

missing_cochanges: files that usually move together but didn't

missing_cochanges flags a changed file's historical co-change partners that are not in your PR. This is hidden coupling — the kind with no import link, the kind AST analysis cannot see.

  • Partners come from git history: files that change in the same commit, repeatedly, without importing each other.
  • Often the most expensive coupling, because no static tool warns you about it.
  • Each warning carries the co-change count, so you can judge how load-bearing the pairing is.
repowise change coupling view showing two files that change together without an import link
Change coupling — the partner that should have changed alongside this one, but didn't.

missing_tests: risky code with no accompanying test

missing_tests flags affected files that lack a corresponding test in the change set. Test files themselves are never reported as having a gap.

Guardrail: coverage here is an input that sharpens risk, not a dashboard.

  • Feed a coverage report and the test-gap weighting tightens around genuinely untested lines.
  • Accepts LCOV, Cobertura, Clover, or normalized JSON.
  • No coverage report is required: risk still scores without it; coverage just makes the signal more precise.

Silent by default

The Repowise PR Bot posts one comment per pull request, and only when there is something worth saying.

  • A green PR gets no comment at all, so the signal stays trusted.
  • Zero LLM calls, so the same PR twice produces the exact same comment.
  • That is the opposite of LLM review bots, which comment on every PR regardless of signal.

Walkthrough: from a diff to a risk verdict

Step 1 — Point at a diff. Run get_risk in PR mode (or let the Repowise PR Bot do it) on any commit or base..head range. Nothing is sent anywhere; scoring is local and deterministic.

repowise risk view ranking files by hotspot score, owner, and risk type
Risk view — churn percentile fused with complexity, ranked.

Step 2 — Read the score. A 0-10 band is computed from the shape of the diff with Kamei-style just-in-time metrics: size, entropy, scatter, and the history of the files it touches.

Step 3 — Trace the blast radius. A reverse-dependency BFS over the graph to depth 3 lists every dependent of your change, ranked by centrality so the high-PageRank consumers surface first.

repowise blast radius fanning out from a changed file to its direct and transitive dependents
Enter your changed files and watch the graph fan out to every dependent.

Step 4 — Read the directives. PR mode returns will_break, missing_cochanges, and missing_tests. Each points at a verifiable thing, so review is a checklist instead of a guess.

Step 5 — Merge or fix. A green PR gets no comment. Otherwise, work the directive checklist — add the missing co-change partner or test — before you merge.

Repowise PR Bot comment listing the risk band, the will_break dependents, and a missing_cochanges callout
The PR comment — a checklist of exactly what to verify before merge.

Proof: a deterministic verdict, not a guess

Every signal below is computed from the diff and the graph, with no model in the loop, so it reproduces on your own repo.

ResultValue
Blast radiusReverse-dependency BFS over the real graph to depth 3, centrality-ranked
Scoring0 LLM calls — the same diff scores the same every time
PR directives3will_break, missing_cochanges, missing_tests
Co-changeHidden coupling mined from git history, no import link required
Coverage inputLCOV, Cobertura, Clover, JSON — an input that sharpens risk, not a dashboard
Incremental re-scoreunder 30s on a new push, against the already-indexed graph
PR commentsOne per PR, only when warranted; a green PR stays silent

Try it on your repo

Score a commit, a branch, or a PR before you merge — every signal is deterministic and runs locally.

pip install repowise
repowise init                          # builds graph, git, and health layers
repowise risk HEAD                     # score a single commit
repowise risk main..my-feature         # score a base..head range

Or install the Repowise PR Bot on a public repo and let it score every PR — silently, until there is something worth saying.

FOR YOUR ROLE

How each role uses this feature

FREQUENTLY ASKED

Questions, answered

What is a directive?

A directive is a single, concrete instruction in the PR-mode risk block telling the reviewer exactly what to check before merge. repowise emits three: will_break (dependents the change is likely to affect), missing_cochanges (files that usually move together but were left out of the diff), and missing_tests (risky code with no accompanying test changes). Each points at a verifiable thing, so review is a checklist instead of a guess.

Does the PR bot use an LLM?

No. Scoring is fully deterministic, computed from the diff and the dependency graph with Kamei-style just-in-time metrics and no model in the path. The same diff produces the same score every time, so there is no drift, no token bill, and no prompt-injection surface. The same PR run twice yields the exact same comment.

What is blast radius and how deep does it go?

Blast radius is the full set of dependents of a change — every file that could be affected by what you touched, derived from the real dependency graph rather than guessed. repowise computes it with a reverse-dependency BFS over the import graph to depth 3, ranks dependents by centrality, and reuses the same file list to suggest the right reviewers.

How does it know what co-changes?

From git history. repowise mines the co-change partners of your changed files — files that repeatedly change in the same commit without an import link between them. That hidden coupling cannot be seen by AST or static analysis. On a PR, if a changed file's historical partner is missing from the diff, it surfaces as a missing_cochanges warning with the co-change count, so you can judge how load-bearing the pairing is.

How does test coverage fit in?

Coverage is an input that sharpens risk, not a dashboard. Feed a standard LCOV, Cobertura, Clover, or JSON report and the missing_tests directive tightens around genuinely untested lines instead of just basename-matched test files. No coverage report is required — risk still scores without it; coverage just makes the test-gap signal more precise.

Can I run it on a commit, not just a PR?

Yes. Change risk scores any commit or any base..head range, not only pull requests. Run it locally over MCP with get_risk in PR mode, or from the CLI — on a single commit, on a feature branch before you open a PR, or on a range to triage everything that changed since a release.

Last reviewed: June 2026

See what your next PR would break