Code health

Know which code will break next, and the fix for it.

Every file scored for defect risk, maintainability and performance. Then a ranked worklist: named refactoring plans with the tests to run, slow code traced across files, and dead code you can delete safely.

No LLM in the analysis · the same code always scores the same

Repowise Code Health for repowise-dev/repowise: a 7.6 out of 10 repository score, the bug-fix ranking check, maintainability, performance risk and hotspot health, above the health map of every file.

repowise-dev/repowise · Code Health, 4,535 files

Measured, not claimed

0.74
AUC predicting which files get a bug fix next
n = 2,826 · 21 repositories, 9 languages, 2,826 files · 2026-08
2.3x
more defects found under the same review budget
n = 2,770 · p = 0.003 · 2,770 files scored by both tools at the same leakage-free commit · 2026-08
3.3x
lift on a repo's own lowest-scoring files
16 of the 20 lowest-health files had a bug fix in the prior six months
7
named refactoring plan types
Beside 25 defect markers and 22 performance markers

Sound familiar?

Every tool says everything is wrong.

  • 01

    The linter flags five thousand things.

  • 02

    Big files always look worst, whether or not they break.

  • 03

    We know the file is bad. Nobody knows what to do first.

What makes it different

From a score to the next edit.

  1. Defect risk

    A 1 to 10 score checked against real bug fixes.

    Weights learned from a defect corpus, with hotspot health and the worst file kept beside the average.

  2. Fix first

    One ranked list of what to do this week.

    Each item is a first edit, its expected gain, its effort and the command that checks it.

  3. Refactoring plans

    Seven named plans, not a vague smell.

    Extract Method, Extract Class, Extract Helper, Move Method, Split File, Break Cycle and Performance Fix.

  4. Dataflow-checked

    Extract Method that keeps behaviour.

    A span is offered only when every value it returns is written on every path and no handler changes.

  5. Performance

    N+1 queries and blocking calls, traced across files.

    The loop and the I/O call can sit three calls apart. Kept separate from the defect score.

  6. Dead code

    Delete with confidence.

    Unused files, exports and packages in confidence tiers, with the ones that are safe to delete marked.

In depth

Not just a score. The next edit, ready to make.

Fix first

One ranked list of what to fix, across every signal.

Refactoring plans, performance fixes and the strongest findings compete in one queue, ranked by expected gain for effort. Each item carries its first edit and the command that checks it, so the top of the list is a task, not a topic.

Now, next, later
Ordered by gain, confidence and effort.
Verify built in
The tests that reach the code, as a command.
Noise left out
Tests, generated code and tiny wins are counted, not listed.
Hotspots first
The code you change most rises to the top.
repowise health
$ repowise healthFix first (3 of 41 eligible items) 1. Extract the retry branch from parse_config   now · effort M · +1.4    src/config/loader.py:212    CCN 47 and nesting 6 in a file changed 19 times this quarter.    verify: pytest tests/unit/test_loader.py 2. Batch the customer lookup in enrich_orders   now · effort S    services/orders.py:88 · N+1, runs per request 3. Split OrderService into 3 classes            next · effort L · +0.9    services/orders.py · LCOM4 3, 41 methods Code health 7.4/10 [Good] · Hotspot 6.1 · Worst 2.3 (src/config/loader.py)
Illustrative repository · repowise health

Refactoring plans

Seven named plans, and an Extract Method that keeps behaviour.

A plan names the change: the groups a god class splits into, the method that belongs in another class, the one import edge that breaks a cycle, the lines to lift into a helper with its parameters and return value. Extract Method is dataflow-checked, so a span is offered only when the extraction provably keeps behaviour.

Extract Method
The span, the helper's signature, the call that replaces it.
Extract Class
The cohesive groups a god class splits into.
Move Method, Extract Helper
Where a method belongs; one helper for every copy.
Split File, Break Cycle
Which symbols go where; the edges to invert.
plan · extract method · src/config/loader.py

Lift lines 214 to 241 out of parse_config

high confidenceeffort S
def _build_retry_policy(raw: dict, attempts: int) -> RetryPolicy:    ...  # 28 lines, 6 decision points policy = _build_retry_policy(raw, attempts)

Dataflow checked

  • Every returned value is written on every path
  • No state carried across loop iterations
  • No local a closure shares across the span's edge
  • The try stays with its handlers
Reach
local · no caller changes
Gain
+1.4 health · CCN 47 to 29
Verify
tests/unit/test_loader.py::test_retry_defaults

Hand to your agent

Copy the plan as a recipe. The edit, the checks, and what it must not change.

Illustrative plan · get_health(plan_id=...)

Performance

Slow code traced across files, not just inside one function.

A database call inside a loop is easy to spot when both sit in one function. Repowise follows the resolved call graph up to three hops, so it finds the loop in the service that calls the query in the repository, says whether the loop grows with the data, and groups findings that share one fix.

N+1 and I/O in loops
Database, network, file system and subprocess.
Blocking calls in async
Blocking I/O and serial awaits on the hot path.
Per request first
Loops that run per request outrank cold paths.
One fix, many sites
A shared plan when every site reaches one sink.
performance · n+1 · traced across files
  1. list_orders routes/orders.py:31

    GET /orders · per request

  2. enrich_orders services/orders.py:88

    for order in rows (grows with the data)

  3. get_customer db/customers.py:14

    SELECT ... WHERE id = ? (database)

State
plan ready · one shared fix for 2 call sites
First step
Add get_customers(ids) and call it once before the loop

enrich_orders · services/orders.py:88

One query per order, on every request. Kept apart from the defect score.

Illustrative finding · traced through the call graph

Dead code

Delete what nothing uses, starting with what is safe.

Files nothing imports, exports nothing uses and packages nothing depends on, each with a confidence and the evidence behind it. The deletion-ready ones are marked, and entry points, framework routes and registered handlers are never reported.

Confidence tiers
High, medium and a review tier you opt into.
Safe to delete
High confidence, no runtime-load path.
Evidence attached
Why each finding is in, and what capped it.
Graph plus history
No LLM, computed during every index.
repowise dead-code
FindingConfidenceReady
formatLegacyDateunused_export100%✓ safe
toCsvRowunused_export100%✓ safe
src/legacy/parser.tsunreachable_file100%review
config/feature_flags.pyunreachable_file40%review

Safe to delete

2 unused exports, 24 lines. High confidence, no runtime-load path.

Illustrative repository · repowise dead-code

On a real repository

Every plan on one board, ranked.

The refactoring board plots every structural plan by how big the file is and how much code imports it, then lists them in the order to do them, each with its effort and confidence. Open one and its drawer shows the steps, the tests that reach the code and a prompt to hand to your agent.

Repowise refactoring board for repowise-dev/repowise: a scatter of Split File, Break Cycle, Extract Class and Move Method plans by file size and importers, above a ranked list of plans with effort and confidence.
repowise-dev/repowise · the refactoring board

In plain words

One number, 1 to 10, for how likely a file is to produce the next bug.

Every file starts at 10 and loses points for findings in its structure, its history and its ownership. The weights were learned from real bug fixes, so a low score has predicted defects before, and file size is controlled for, so a big file is not marked down for being big.

How to read it

What's a good score?

8.5 and up · Excellent
Easy to change safely. Leave it alone.
7 to 8.5 · Good
Healthy. A seven is not a warning.
5.5 to 7 · Fair
Watch the trend. Refactor it if it is also a hotspot.
4 to 5.5 · Needs work
Changes here are the ones that come back as bug fixes. Plan the refactor.
Under 4 · At risk
Where the repository's bug fixes concentrate. Start here, with the named fix.

How it works

Measure, calibrate, act.

Three signals stay separate until the evidence earns a conclusion, then the score points at a file and a fix.
  1. 01 / Measure

    Extract deterministic markers

    Complexity, nesting, cohesion, clones, churn, ownership, prior defects and coverage.
  2. 02 / Calibrate

    Weigh them against real defects

    Offline learning against bug-fix history. Only the constants ship.
  3. 03 / Act

    Go from score to worklist

    Fix first, refactoring plans, performance causes and dead code, each with the tests to run.

Questions

What people ask before they try it.

What does the code-health score actually measure?

Every file gets a single 1 to 10 score computed from 25 deterministic markers: McCabe complexity, deep nesting, brain methods, class cohesion (LCOM4), god classes, Rabin-Karp clone detection, change entropy, co-change scatter, ownership dispersion, prior-defect history, test-quality smells, and more. Lower scores mean the file is more likely to harbor defects.

How do you know the score actually predicts bugs?

It is defect-validated. On the same 2,770 files across 9 languages with real defect labels, ranking by repowise health surfaces 2.3x the defects of a leading commercial tool under the same review budget (recall 0.173 vs 0.074, effort-aware Popt 0.607 vs 0.462, ROC AUC 0.731 vs 0.705). Across 21 open-source repos the mean cross-project ROC AUC is 0.74 with a 95% confidence interval of 0.68 to 0.79, ranging from 0.55 to 0.86 across individual repos.

Does it use an LLM?

No. Scoring is fully deterministic: 25 markers with weights calibrated offline against a defect corpus. Only the learned constants ship, so the same code always produces the same score, in under 30 seconds on a 3,000-file repo. No cloud, no API calls, no drift.

How is this different from CodeScene?

Both score code health, but repowise is open source so every heuristic is inspectable and reproducible on your own repo, and the score ships inside a broader platform: named refactoring plans your agent can apply, an architecture-aware wiki, git intelligence, architectural decisions, agent provenance, and ten MCP tools for AI agents.

Will it just flag big files?

No. The discrimination survives controlling for file size (partial Spearman rho of -0.16) and significantly out-discriminates both recent churn (+0.10 AUC) and prior-defect history (+0.12 AUC), with DeLong p below 1e-9.

Can it use my test coverage?

Yes. repowise ingests LCOV and Cobertura coverage to compute untested-hotspot risk (the intersection of low coverage and high hotspot score), alerts when a file's health starts declining, and ranks refactoring targets by impact for effort.

Can I prove these numbers on my own codebase?

Yes, that is the point. Every heuristic is open source under AGPL-3.0, and the validation runs on your own repo. On a typical project, 16 of the 20 lowest-health files had a bug fix in the last 6 months, 3.3x the 24% baseline.

Does repowise check performance?

Yes, as a static health pillar, not as an APM or profiler. repowise statically detects performance-risk shapes such as N+1 access and IO-in-loop patterns and scores them as a co-equal third pillar alongside defect risk and maintainability. It is high precision and low recall by design: it raises few findings, but the ones it raises are real. There is no runtime, no agent, and no tracing; it reads your source, like every other signal.

Does repowise refactor my code for me?

It names the refactor and hands it over. Each of the seven plan types is structured data: what moves where, the helper's signature, what else has to change and the tests to run. Your agent applies it as a recipe, or you ask for the code and get a diff to review. Nothing is ever applied to your repository on its own.

What are the seven refactoring plans?

Extract Method, Extract Class, Extract Helper, Move Method, Split File, Break Cycle and Performance Fix. Each detector reports nothing when a signal it needs is missing, so a gap means no suggestion, never a guessed one, and the same commit always gives the same plans.

How does dead code know what is safe to delete?

Every finding carries a confidence from 0 to 1 and the evidence behind it. A finding is marked safe to delete only at high confidence and with no runtime-load risk on its path, such as config, bootstrap or served assets. Entry points, framework routes and registered handlers are never reported.

Last reviewed: October 2026

Get started

See what your codebase should fix first.

Start free on a repository you know and check the lowest-scoring files against the ones that broke last quarter. For a team rollout, book a demo.