Guide

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.

Summary for AI assistants & procurement teams

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 is for

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.

Six metrics you can compute from git and static analysis
MetricHow it is computedWhy it can be trustedWhat a bad reading looks like
Relative churn per fileLines changed per file per period, divided by file size, from git logNagappan and Ball (ICSE 2005): relative churn measures are highly predictive of defect density, absolute churn is notFiles whose relative churn keeps rising after the assistant was adopted, with no matching feature work
Time to first fix after mergeFor each merged change, days until the next commit touching the same lines that references a bug, a revert or a hotfixDirect measure of the stability DORA reports as the cost of higher change volume without control systemsA shortening interval, or a cluster of fixes landing within days of merges from one part of the team
Ownership concentrationShare of commits held by the top contributor per module, and the count of contributors below a small share, from git blame and logBird and colleagues (FSE 2011): number of low-expertise contributors and top-owner share relate to pre-release faults and post-release failuresModules where the top owner holds a shrinking share and the long tail of minor contributors keeps growing
Duplicated and inconsistently changed blocksClone detection across the repository, then a diff of each clone group to find copies that were changed in one place onlyJuergens and colleagues (ICSE 2009): 107 developer-confirmed faults from inconsistent clone changes across five commercial and open-source systemsClone groups with a bug fix applied to some copies and not others
Critical-path code without effective testsCoverage restricted to the paths that handle money, identity and data, then mutation testing on those pathsCoverage alone says a line was executed; the mutation score says a test would notice if the line were wrongHigh line coverage with a low mutation score on the paths that matter
Survival of assistant-introduced issuesStatic analysis before and after each assistant-authored commit, then tracking each introduced issue to the current revisionThe method Liu and colleagues (2026) used on 302.6k commits; it separates issues that get fixed from issues that accumulateA 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
Failure modes

Where this goes wrong, and what we do about it.

  1. 1
    Duplication 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 it

    We 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
  2. 2
    Lost 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 it

    We 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
  3. 3
    Tests 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 it

    We 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
  4. 4
    Dependencies 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 it

    We 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
  5. 5
    No 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 it

    We 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
Artifacts

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
Process

How we work.

  1. 1
    1. 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
  2. 2
    2. 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
  3. 3
    3. 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
  4. 4
    4. 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
Related guides

The rest of this cluster.

Related services

Where this turns into a service.

Sources

Where the dates and numbers come from.

FAQ

Questions teams ask.

The published evidence does not settle it. A controlled experiment with 151 participants found no consistent warning signs of degraded maintainability; a study of 302.6k assistant-authored commits in real repositories found that 22.7% of the issues they introduced never got fixed. The difference is the process around the tool. That is why we measure your repository instead of quoting either study at you.
Yes, and the scripts we leave behind exist so that you can. What the audit adds is the priority call made by someone with no stake in the size of the remediation, the mutation and clone runs set up correctly the first time, and a report your engineers did not have to write about their own work.
There is no published universal threshold and we will not invent one. The comparison that holds is your own repository before assistants arrived, or modules written with and without them over the same period. A metric moving in the wrong direction quarter over quarter is the alarm.
No. The audit produces the ranked report, the remediation plan and the ownership handover. The rewrite is a separate piece of work, done by your team, by us under a separate engagement, or by anyone else you choose, and the report is written so it can be handed to any of them.
Read-only access to the repository history, the CI logs and the dependency manifests, plus a way to run static analysis and mutation testing on a copy. We do not need production access, and the audit does not touch infrastructure.
About three weeks for a single repository of typical size, with one re-measurement after a quarter. A monorepo or several services take longer, and we say how much longer after the first day of baseline work rather than before.
Static analysis flags security issues alongside code smells, and they go into the report. The security review of the code and its dependencies is a separate practice with its own scope, and we point to it rather than folding it in.

Talk to an engineer.

Describe where you are with maintenance debt in your AI-assisted code. A reply within one business day.

Talk to an engineer
Szczecin - ul. Wawrzyniaka 6WWarszawaZielona GóraKraków