Maintenance debt in AI-assisted code: how to measure it in your own repository and what to do with the result
Maintenance debt in AI-assisted code is the extra cost of every later change to code that was produced quickly with an assistant and merged without anyone taking ownership of it. It shows up as duplicated logic, lost change intent, tests that assert the implementation, dependencies nobody chose and modules nobody owns. All five leave traces in git, so all five can be measured before anyone argues about them.
dfzoo AI Engineering audits maintenance debt in AI-assisted codebases for engineering teams whose delivery got faster and whose changes got slower. The audit computes six metrics from git history and static analysis: relative churn per file, time to first fix after merge, ownership concentration, duplicated and inconsistently changed blocks, critical-path code without effective tests, and survival of issues introduced by assistants. Each metric has published evidence behind it, and the page states where that evidence is mixed. The output is a debt report ranked by cost of change, a remediation plan the team executes itself, and a procedure for handing ownership of unowned modules to named people. Rewriting the code is not part of the audit.
Who this guide is written for.
- CTOs and VPs of Engineering who adopted coding assistants across the team and now see lead time for changes going up
- Engineering managers inheriting a codebase where a large share of the code has no human author who remembers why it looks that way
- Tech leads asked to put a number on the debt before the next planning cycle, with nothing but a feeling to show
- Teams hiring for or budgeting AI code remediation as a category of work and needing a scope for it
Where the cost comes from
The evidence on AI-assisted code is mixed. In a controlled experiment with 151 participants, 95% of them professional developers, Borg and colleagues (Echoes of AI, 2025) observed no consistent warning signs of degraded code-level maintainability when other developers evolved AI-assisted code. In the wild the picture is different: Liu and colleagues (Debt Behind the AI Boom, 2026) tracked 302.6k verified AI-authored commits across 6,299 repositories and found that more than 15% of commits from every assistant introduced at least one static-analysis issue, and that 22.7% of those issues still survive in the latest revision. The 2025 DORA report, drawn from nearly 5,000 respondents, reports a positive relationship between AI adoption and throughput and a persistently negative one with delivery stability. Read together: the variable is the process around the tool, and the only way to know which side your repository is on is to measure it.
Five mechanisms account for most of the cost, and each is a property of the tool used without a process. An assistant sees the files in its context window, so it adds a helper or a branch next to existing structure instead of reusing what lives two directories away. A pull request description generated from the diff records what changed but not why, so the intent of the change is gone the day it merges. Tests generated from the implementation assert the current behaviour, bug included, and report high coverage while catching nothing. A dependency appears because the model has seen it often, not because anyone on the team decided to carry it. And a file touched by five people and their assistants has no owner, which Bird and colleagues (2011) showed correlates with both pre-release and post-release failures on Windows Vista and Windows 7. A multivocal review of 104 sources by Ehsani and colleagues (2026) gives this last one a name: provenance debt, the point where responsibility for generated logic cannot be traced to anyone.
Sawada and colleagues (2026) analysed about 1,000 AI-generated files across 100 popular repositories and found that they receive less frequent maintenance than human-authored code, that the changes they do receive are mostly feature extensions rather than fixes, and that humans perform almost all of that maintenance. A file that keeps growing and is never corrected is not necessarily healthy. It may simply be a file nobody dares to touch.
Six metrics you can compute from git and static analysis
None of the metrics below needs a commercial platform. They need read access to the repository, the CI logs and a static analysis run. Each one has a published reason to be trusted, so nobody has to take the auditor's word for the result. There is no universal alarm threshold for any of them, and this page does not invent one. The comparison that holds is against your own repository before assistants arrived, or between modules written with and without them.
| Metric | How it is computed | Why it can be trusted | What a bad reading looks like |
|---|---|---|---|
| Relative churn per file | Lines changed per file per period, divided by file size, from git log | Nagappan and Ball (ICSE 2005): relative churn measures are highly predictive of defect density, absolute churn is not | Files whose relative churn keeps rising after the assistant was adopted, with no matching feature work |
| Time to first fix after merge | For each merged change, days until the next commit touching the same lines that references a bug, a revert or a hotfix | Direct measure of the stability DORA reports as the cost of higher change volume without control systems | A shortening interval, or a cluster of fixes landing within days of merges from one part of the team |
| Ownership concentration | Share of commits held by the top contributor per module, and the count of contributors below a small share, from git blame and log | Bird and colleagues (FSE 2011): number of low-expertise contributors and top-owner share relate to pre-release faults and post-release failures | Modules where the top owner holds a shrinking share and the long tail of minor contributors keeps growing |
| Duplicated and inconsistently changed blocks | Clone detection across the repository, then a diff of each clone group to find copies that were changed in one place only | Juergens and colleagues (ICSE 2009): 107 developer-confirmed faults from inconsistent clone changes across five commercial and open-source systems | Clone groups with a bug fix applied to some copies and not others |
| Critical-path code without effective tests | Coverage restricted to the paths that handle money, identity and data, then mutation testing on those paths | Coverage alone says a line was executed; the mutation score says a test would notice if the line were wrong | High line coverage with a low mutation score on the paths that matter |
| Survival of assistant-introduced issues | Static analysis before and after each assistant-authored commit, then tracking each introduced issue to the current revision | The method Liu and colleagues (2026) used on 302.6k commits; it separates issues that get fixed from issues that accumulate | A growing backlog of introduced issues that are never closed, concentrated in unowned modules |
AI code remediation as a category of work, and where the audit stops
In discussions among experienced developers, remediation of AI-assisted code has become a job description: people are hired specifically to take over code nobody wrote and make it changeable again. The audit scopes that work: it produces the ranked list, the plan and the ownership handover, and does not execute the rewrite, for two reasons. The team that has to live with the code should be the one that restructures it, or the intent is lost a second time. And the audit is only worth something if the auditor has nothing to gain from a large remediation estimate.
The scope, stated plainly, so that it can be compared with other offers:
- In scope: the six metrics above computed on your repository, with the scripts left behind so the team can re-run them
- In scope: a debt report ranked by cost of change, where each item names the module, the mechanism and the metric that exposed it
- In scope: a remediation plan with an order of work, an owner per item and a definition of done expressed as a measurement
- In scope: a procedure for handing ownership of unowned modules to named people, with a deputy and a review date
- Out of scope: rewriting, refactoring or migrating the code; that is a separate purchase, from dfzoo AI Engineering or from anyone else, and the report is written so that it can be handed to either
- Out of scope: infrastructure, cloud configuration and penetration testing; the audit reads the repository, not the environment it runs in
Where this goes wrong, and what we do about it.
- 1Duplication instead of reuse
The assistant works on the files in its context. When a similar helper exists elsewhere in the repository it does not know, so it writes a second one, or adds a branch to the structure it can see. After a few months the same validation, retry or mapping logic lives in four places with small differences. A fix then lands in one of them and the other three keep the bug, which is exactly the inconsistent clone change that Juergens and colleagues traced to confirmed faults.
What we do about itWe run clone detection across the whole repository, not per pull request, and diff every clone group to find copies that were changed in one place only. Each inconsistent group gets a verdict with the team: intentional divergence, or a fix that missed its siblings. The ones that touch critical paths are fixed first, and the detector runs again after the fix to confirm the group is consistent. The team keeps the detector configuration so the next report is comparable.
What stays with you: clone register with every inconsistent group, its verdict and its priority, plus the detector configuration - 2Lost change intent
The pull request description is generated from the diff, so it explains what changed and never why. The prompt that produced the change is not stored anywhere, and the ticket says only what the user wanted, not what trade-off the engineer accepted. Six months later a reader can see that a timeout was set to eleven seconds and has no way to learn whether that was a decision or a default. The next change either preserves the accident or breaks the decision.
What we do about itWe take a sample of merged changes from the period after assistants were adopted and trace each one back to a ticket, a prompt or a recorded decision. The share that cannot be traced is the number the team needs. We then add a change-record convention to the pull request template, one line of intent and the constraint it satisfies, and re-sample after a quarter to verify the share moved.
What stays with you: intent traceability sample with the untraceable share, and the amended pull request template - 3Tests written to the implementation
Asked to add tests, the assistant reads the code it just wrote and asserts what it does, including the mistake. Line coverage on the module goes up, the dashboard turns green, and the tests would pass just the same if the logic were wrong. The team believes the module is protected and reduces review on later changes to it.
What we do about itWe restrict the question to the critical paths and run mutation testing there: small deliberate faults injected into the code, then a count of how many the suite catches. Tests that catch nothing are listed by name. We rewrite the ones on critical paths from the requirement rather than from the code, together with your team, and re-run the mutations to verify the score changed.
What stays with you: mutation score per critical path, before and after, with the list of tests that caught no mutants - 4Dependencies nobody chose
A package appears in the lockfile because the model has seen it in enough training data to suggest it, not because anyone compared it with what the repository already had. The result is two HTTP clients, three date libraries and a utility that duplicates a function from the standard library, each carrying its own upgrade cadence and licence. When a vulnerability notice arrives, nobody knows who owns the decision to keep or drop the package.
What we do about itWe diff the dependency manifest before and after assistants were adopted, and for each addition record whether it overlaps an existing dependency, when it was last released, and its licence. Every dependency gets an owner and a verdict: keep, replace, remove. We verify the removals build and pass the suite, and leave the log with the team so the next addition is a decision rather than a suggestion.
What stays with you: dependency decision log with an owner and a verdict per package - 5No module owner
With an assistant, every engineer can touch every module, and does. Ownership concentration falls, the count of minor contributors per file grows, and the person who could answer a question about the module is nobody, because the last five changes came from five different people each working with the tool. Bird and colleagues found this pattern related to failures long before assistants existed; assistants only make it cheaper to produce.
What we do about itWe build an ownership map from git for every module, compute the top-owner share and the minor-contributor count, and flag modules where both point the wrong way. For each flagged module the team names an owner and a deputy, and the handover is a written procedure with a review date. We recompute the map after a quarter to verify the shares moved.
What stays with you: ownership map per module with named owner and deputy, and the handover procedure
What stays with you.
- Metrics baseline for the six measures, with the scripts and configuration so the team can re-run them
- Debt report ranked by cost of change, each item naming the module, the mechanism and the metric that exposed it
- Remediation plan with an order of work, an owner per item and a measured definition of done
- Ownership handover procedure for unowned modules, with owner, deputy and review date
- Dependency decision log with a verdict per package added since assistants were adopted
- Written scope boundary stating what the audit did not cover, so the report can be handed to whoever does the rewrite
How we work.
- 11. Baseline from git
With read-only access we compute churn, time to first fix and ownership for every module, and agree with your team which paths count as critical. At this stage there are only numbers and the period they cover.
Week 1 - 22. Static analysis, clones and mutations
We run clone detection, issue tracking across assistant-authored commits and mutation testing on the critical paths. Each finding is tied to a module and a metric.
Week 1-2 - 33. Report and priorities
We rank the findings by cost of change and walk them with the people who maintain the code. Where the team disagrees with a ranking, the disagreement goes into the report with its reason.
Week 2-3 - 44. Ownership handover and re-measurement
We hand over the plan, the procedure and the scripts, and come back after a quarter to recompute the baseline and report what moved.
Week 3, then one re-measurement after a quarter
The rest of this cluster.
Prompt cache forensics and spend limits
How to attribute LLM cost to a call, session and feature, how Anthropic, OpenAI and Google bill prompt caching, what quietly breaks the cached prefix, and where an alert ends and a hard stop begins.
Measuring the real effect of AI in a team
Why faster ticket closure is not evidence, what the 2025-2026 controlled experiments measured, how to design a baseline, paired metrics and a comparison group, and which per-person metrics to avoid.
Comparing AI code review tools
Why vendor rankings of AI code review tools are not comparisons, which metrics they leave out (precision per class, off-diff comments, invented findings, cost per PR), and a protocol for your own PRs.
Where this turns into a service.
App Maintenance
Ongoing maintenance for AI-touched systems: provider migrations, prompt tuning, dependency upgrades.
Test Coverage
Test strategy for AI-assisted projects - what to test, what to mock, what to skip.
Production Readiness
Pre-release certification: observability, runbooks, rollback paths, on-call signals.
Where the dates and numbers come from.
- Liu et al., Debt Behind the AI Boom: A Large-Scale Empirical Study of AI-Generated Code in the Wild (arXiv:2603.28592, 2026)
- Borg et al., Echoes of AI: Investigating the Downstream Effects of AI Assistants on Software Maintainability (arXiv:2507.00788, Empirical Software Engineering 2026)
- Sawada et al., To What Extent Does Agent-generated Code Require Maintenance? An Empirical Study (arXiv:2605.06464, 2026)
- Ehsani et al., Faster Code, Deeper Debt? A Multivocal Literature Review on Technical Debt in LLM-Assisted Software Development (arXiv:2606.14796, 2026)
- Google Cloud, Announcing the 2025 DORA Report
- Bird et al., Don't Touch My Code! Examining the Effects of Ownership on Software Quality (ESEC/FSE 2011)
- Nagappan and Ball, Use of Relative Code Churn Measures to Predict System Defect Density (ICSE 2005)
- Juergens et al., Do Code Clones Matter? (ICSE 2009)
Questions teams ask.
Talk to an engineer.
Describe where you are with maintenance debt in your AI-assisted code. A reply within one business day.