TD Agent
A Python LLM-based technical-debt analyser, scored in the same unit as SonarQube so the two are directly comparable — the empirical core of an MSc dissertation, benchmarked across ten repositories.
10
repositories benchmarked
10
debt categories scored
~73%
above SQALE on the same codebase
// stack
// architecture
Python analysis pipeline · Git history sampling at configurable intervals · per-file churn and hotspot analysis · token-budget-aware prioritisation within an 80-file / 400k-character budget · Gemini analysis behind a free-tier rate limiter · FastAPI background jobs with live progress polling · Pandas over the results for longitudinal analysis · Next.js dashboard · CSV export and standalone HTML reports
// overview
TD Agent analyses a repository’s commit history rather than a single snapshot, sending prioritised source snapshots to Gemini and asking it to identify technical debt. The whole analysis pipeline is Python — git history sampling, per-file churn and hotspot analysis, token-budget-aware file prioritisation, the Gemini client behind a free-tier rate limiter, and FastAPI background jobs orchestrating a run — with a Next.js dashboard on top for live progress and results. Every issue gets a category, severity, confidence, a concrete "why is this debt" consequence, and a realistic remediation estimate in minutes, which are summed into an AI Technical Debt Score. Scoring in minutes is the methodological point: it is SonarQube’s own SQALE unit, so the two tools produce directly comparable numbers instead of two incommensurable scales. Benchmarked across ten open-source microservice repositories, the AI score ran substantially higher than the SQALE index on the same codebase, and the delta was architectural and cross-cutting debt that pattern-matching rules cannot express as a rule.
// what was built
- ·Analyses a repository’s full commit history at configurable intervals, not just a single snapshot, so debt has a trajectory rather than a value — checkouts are driven from Python and each sampled point is scored independently.
- ·Scores technical debt in remediation minutes, deliberately unit-matched to SonarQube’s SQALE index, which is what makes the comparison meaningful rather than rhetorical.
- ·Designed the evaluation methodology benchmarking LLM analysis against static analysis across ten open-source microservice repositories, with SonarQube run over the identical commits so nothing about the comparison depends on the tools seeing different code.
- ·Detects ten debt categories — code smells, architecture, complexity, security, performance, duplication, maintainability, documentation, testing and dependencies — each with severity, confidence and a remediation estimate.
- ·Every issue carries a "why is this debt?" explanation naming the concrete consequence of leaving it, which is the part a static analyser cannot produce.
- ·Git churn analysis in Python surfaces per-file change frequency, author counts and hotspots — the files that change often and carry the most risk — and that signal feeds directly into what gets analysed.
- ·Token-budget-aware file prioritisation keeps large repositories inside an 80-file, 400k-character budget, combining churn, debt-prone path heuristics, recency and entry-point detection; which files get spent is the substance of the design, not the prompt.
- ·Structured LLM output is parsed and validated on the way back, so a malformed or partial response fails as a handled error rather than corrupting a run’s score.
- ·Runs analysis as FastAPI background jobs with live progress polling, behind a Next.js dashboard showing a timeline chart, a churn hotspot table and a filterable issue list, plus CSV export and standalone HTML reports.
- ·Built-in rate limiter holds the tool inside Gemini’s free-tier quota, so the whole study is reproducible at zero cost by anyone marking or replicating it.
- ·The finding: the AI score ran roughly 73% above the SQALE index on the same codebases, and the gap was consistently architectural and cross-cutting debt — the kind that cannot be expressed as a pattern-matching rule.
System design
Drawn from the actual source: services, data ownership, message flow and failure paths. Drag to pan, scroll to zoom, or open any diagram fullscreen.
From a git history to a debt score
The design constraint is that an LLM context is finite and a repository is not. Churn analysis and prioritisation decide which files get spent within an 80-file, 400k-character budget — that selection is the substance, not the prompt.
// engineering notes
The decisions worth talking through
The parts of this project where the interesting work was choosing between options, not writing the code.
Unit-matching is the contribution
It would have been easy to produce an LLM debt score on its own invented scale, and impossible to say anything rigorous with it. Choosing remediation minutes — SQALE’s unit — means the two tools can be put on the same axis, and the gap between them becomes a measurable finding rather than a claim.
The context budget is the architecture
A repository is unbounded and an LLM context is not. Churn analysis, debt-prone path heuristics, recency and entry-point detection all exist to answer one question: given a fixed budget of files, which ones will tell you the most about this codebase? That selection logic does more for result quality than any amount of prompt tuning, and it is the part of the system that is genuinely engineered rather than configured.
History, not snapshots
Static analysers score the code in front of them. Sampling the commit history at intervals and scoring each point turns a number into a trajectory, which is the only way to distinguish a codebase that is accumulating debt from one that happens to carry some. It also makes churn a first-class input rather than a curiosity: the files that change constantly are where debt actually costs you.
Reproducible at zero cost, on purpose
An empirical dissertation result that only replicates if the reader pays for API credit is a weaker result. The rate limiter that holds every run inside Gemini’s free tier is not a convenience feature — it is what lets the entire ten-repository benchmark be re-run by a marker, on their own machine, for nothing.