← The ADLC library
Foundations · 3

Who actually writes your code now, an honest audit

Most teams have a confident opinion about how much of their code is agent-written and no evidence for it. Here is how to find out, and why the answer is usually uncomfortable in both directions.

Ask an engineering leader what percentage of their code is now written by agents and you will get an answer within about two seconds. That speed is the interesting part. Nobody hesitates. Nobody says “let me look.”

The answers cluster in two places. One group says something like “maybe fifteen percent, we are being careful.” The other says “honestly most of it at this point.” Both are delivered with the same confidence, and both are usually guesses assembled from whatever the person saw over someone’s shoulder last week plus a general feeling about the direction of things.

I am not being snide about this. There is no dashboard for it. Nobody’s tooling reports it by default. The commit says the human’s name because the human’s credentials pushed it, and that is the end of the audit trail. So the guess is the only thing available, and people guess.

The problem is that essentially every decision downstream depends on that number. How much review capacity you need. Whether your acceptance criteria are good enough. Whether your incident response assumptions still hold. Whether the ADLC framing applies to you at all or is a solution to somebody else’s problem. Running your engineering organisation on a number nobody has checked is not a small thing, and it is very easy to fix, which is the only reason this piece is worth writing.

Why the guess is wrong in both directions

The underestimate and the overestimate have different mechanisms, and it is worth knowing which one you are prone to.

The underestimate comes from counting sessions instead of lines. Leaders picture the visible cases: the engineer who talks about their agent setup, the one who demos it in a team meeting. They do not picture the quiet majority who use completion constantly, accept most of it, and would not describe that as “using an agent” because it does not feel like delegation. It feels like typing. Autocomplete that finishes your function is producing code you did not write, and it does not register as such because the interaction has no ceremony around it. Ask the same leader how much of their code passes through a completion model on the way in and the number moves a lot.

The overestimate comes from counting generation instead of survival. An agent produces two hundred lines. The engineer keeps sixty, rewrites forty, and deletes the rest. If you count what was generated, agents wrote the change. If you count what survived to main, it is a collaboration, and the human made every decision that mattered. Teams that have gone hard on agent workflows frequently overstate their position, because the generation is loud and the editing is silent.

Both errors matter, and they matter differently. Underestimating means you build review process for a volume you no longer have. Overestimating means you assume the machinery is more autonomous than it is and you go looking for a control problem that has not arrived yet, while the actual bottleneck sits somewhere unglamorous.

The underestimate

  • Counts sessions instead of lines
  • Pictures the visible enthusiasts
  • Misses quiet, routine, constant use
  • Result: review process built for a volume you no longer have

The overestimate

  • Counts generation instead of survival
  • Two hundred lines produced, sixty kept
  • Ignores the rewriting and deleting
  • Result: assuming more autonomy than exists
Two different mechanisms, two different downstream mistakes. Knowing which one you are prone to is most of the value of asking.

The audit

Here is a version you can run this week. It is not sophisticated. Sophistication is not the missing ingredient, attention is.

Step one: pick a real window. Four weeks, ending last Friday. Not a sprint, because sprints are selected for tidiness. Include the bad week. If you had an incident, include it, because incident work has a completely different authorship profile and excluding it is how you get a flattering answer.

Step two: count pull requests before you count anything clever. How many merged in the window, and how many merged in the same window a year earlier? You want the ratio, not the absolute. Most teams find something between 1.5x and 4x, and the ones at the high end have almost always not adjusted a single process to account for it. That ratio alone tells you more than any percentage-of-code figure, because it is the number your review capacity has to absorb.

Step three: classify authorship into three buckets, not two. This is where the interesting data is, and where the binary framing fails.

Human-authored, machine-assisted. A person decided what to do and how, and used completion or a chat window along the way. Attribution here is genuinely human. Intent, structure and judgement all came from the person.

Machine-authored, human-directed. The person specified an outcome, an agent produced the change, and the person reviewed and adjusted it. Intent is human, implementation is not. This is the bucket that matters most, and it is the one that has grown fastest on most teams.

Machine-authored, machine-directed. An agent picked up a ticket, made a plan, executed it and opened a pull request, and the first human involvement was review. Small on most teams today. Not small on some. If this bucket is non-trivial for you, everything else in this series is urgent rather than interesting.

Classify a sample. Forty pull requests, picked randomly, judged by whoever merged them. You do not need every change, you need an unbiased sample, and forty is plenty to tell 10% from 60%.

Human-authored, machine-assistedA person decided what and how, using completion along the way. Intent, structure and judgement are genuinely human.
Machine-authored, human-directedThe person specified an outcome, an agent produced it, the person reviewed. Intent human, implementation not.
Machine-authored, machine-directedAn agent picked up a ticket, planned, executed, opened the PR. First human involvement is review.
Three buckets, not two. The binary framing is where the interesting data goes to die, because the middle bucket is where most teams actually live.

Step four: ask the reviewers what changed. One question, asked of the people who actually do the reviewing: “Compared to a year ago, how confident are you that a review you did this week would catch a serious problem?” You are not measuring code quality. You are measuring whether the safety mechanism still believes in itself. The answers are usually more informative than the counts, and considerably more alarming.

Step five: measure drift, not just volume. For each merged pull request in the sample, how long between merge and the linked ticket reaching a done state? And how many had no linked ticket at all? That second number tends to be the one that makes people sit up, because it is not a percentage of anything abstract. It is a count of changes that are in production and invisible to the system your organisation uses to decide what to do next.

What the answers usually mean

A few patterns worth naming, because the same numbers point to different problems.

High volume, low machine-directed, small drift

Faster and still disciplined. The pressure is review capacity, not control. Do not rebuild the life cycle.

High volume, high drift, unlinked PRs

The record has failed and you have been deciding on it anyway. The common case.

Machine-directed share, prose criteria

The genuinely dangerous configuration. This is what produces confidently wrong at speed.

Everything low

Genuinely fine. Regulated environments and old codebases often sit here legitimately.

The same audit produces four different diagnoses. Which quadrant you are in determines what to fix, and three of the four are not a code quality problem.

High volume, low machine-directed share, small drift. Your team has got faster and stayed disciplined. The pressure you are feeling is review capacity, not control. Do not rebuild your life cycle. Invest in making review cheaper and better targeted, push more of it into automated checks, and revisit in six months.

High volume, high drift, unlinked pull requests in double digits. Your record has failed and you have probably been making decisions on it anyway. This is the common case and it is the one worth fixing first, because it is the cheapest to fix and everything else you might do depends on having a true picture. Linking every change to its ticket and deriving status from the merge rather than from someone remembering is not a strategic initiative. It is plumbing, and it is the plumbing that everything else stands on.

Meaningful machine-directed share, acceptance criteria written in prose. This is the genuinely dangerous configuration and it is the one that produces the “confidently wrong at speed” outcome. An agent given “the export should handle large files gracefully” will do something. It will do it well. It will not be what you meant, and the change will look competent enough to pass a fast review. If this is you, the definition of done is your problem and no amount of review capacity fixes it.

Everything low. Genuinely fine. Some teams have not shifted much, particularly in regulated environments or on old codebases where the agent’s context window cannot hold enough of the system to be useful. Adopting new machinery for a change you have not experienced is a way to spend a quarter feeling modern.

The attribution problem underneath all of this

There is a deeper issue the audit surfaces without solving, and it is worth stating plainly.

Your version control system records who pushed. It does not record who decided. For fifty years those were the same, so nobody built the distinction, and now that they have come apart there is no field for it. The commit author is the human whose credentials were used, whether they wrote every character or typed “yes” once.

This is not a metadata inconvenience. It is the reason the audit above has to be done by hand and by sampling rather than by query. It is the reason incident review gets strange, because “who wrote this” now has two answers and only one of them is recorded. And it is the reason that when someone eventually asks you to prove which changes in your system were made autonomously, you will find you cannot, because nothing captured it at the time.

Some of this is being addressed by tooling, including ours. Attribution and a signed trail of what was automated, by what, on whose authority, is one of the things GroundTruth exists to keep. But I would not want the takeaway to be “buy something.” The takeaway is that the field does not exist by default, so if you care about the answer you have to arrange to capture it, and the arranging is the work.

Where this breaks down

Several places, and one of them undercuts the whole exercise.

The percentage may not be the right question. I have spent this piece telling you to measure something, and there is a real case that the number is a vanity metric. What actually matters is whether your outputs are correct and whether your record is true, and both of those can be measured directly without knowing who wrote what. A team with 90% agent-authored code, excellent criteria and a self-maintaining record is in better shape than a team at 10% with neither. If you only have appetite for one measurement, measure drift and defect escape, not authorship.

Sampling is fragile in exactly the way that flatters you. Whoever picks the forty pull requests will pick the ones they remember, and the ones they remember are the interesting ones. Randomise properly or accept that your number is directionally useful and nothing more. And the classification itself is subjective at the boundary: an engineer who wrote a detailed prompt, rejected three attempts and hand-edited the fourth will classify that differently on different days.

Buckets blur fast. The three-bucket model I gave you is already showing its age. Real workflows interleave: a person starts, an agent continues, a second agent reviews, the person finishes. In a year the taxonomy will need rewriting, and any process you build tightly around today’s categories will need rewriting with it. Build around the questions (is intent captured, is the record true, can we reverse it) rather than around the categories.

And the audit is a snapshot of something moving quickly. The number you get is out of date by the time you present it. Run it as a repeating measurement or do not bother, because a one-off figure will be quoted in strategy documents for eighteen months after it stopped being true.

The takeaway

You almost certainly do not know how much of your code is agent-written, and the confident number in your head came from vibes. Sample forty pull requests, classify them into human-authored, machine-authored-human-directed and machine-authored-machine-directed, count unlinked changes, and ask your reviewers whether they still trust review. That is a week of work and it will change what you prioritise.

The most likely finding is not that agents write more of your code than you thought. It is that your record of what happened is worse than you thought, and that you have been running on it anyway.

The next piece argues that the code generation, the part everyone is watching, is genuinely the least interesting thing about this shift, and that the attention it gets is the reason the actual problem stays unaddressed.