# You Do Not Have an AI Adoption Problem. You Have a Verification Problem.

Source: https://normanholz.de/en/articles/ai-adoption-verification-problem/
Language: en
Last updated: 2026-08-14
Reading time: 9 min read

Senior engineers often avoid AI-generated code for rational reasons. The real constraint is not adoption, but the cost of proving that a change is safe.

A client recently considered hiring a Director of AI Engineering. The brief sounded familiar: increase adoption of AI coding tools, convince skeptical developers, and help the company avoid falling behind.

They had already bought the tools. They were also hiring developers who work AI-first. What they did not have was the expected jump in engineering output.

Someone had heard the usual claim that coding assistants could multiply developer productivity. If one engineer could produce five times as much, perhaps one engineer could manage five products.

There was one problem.

Nobody could explain what "five times the output" meant.

It could not mean lines of code. That metric has been useless for decades. It could not mean commits or pull requests because people would optimize for the count. Token usage would be even worse. Burning more tokens proves only that you burned more tokens.

Once we stopped discussing adoption and started looking at the actual work, the problem changed completely.

The company did not have an AI adoption problem. It had a verification problem.

## The senior engineers were already using AI

The initial theory was that experienced developers resisted the tools. Other departments had adopted AI quickly. HR, consulting, and operations teams used it for repetitive work, summaries, drafts, research, and internal workflows. They saved time and moved on to more valuable tasks.

Engineering looked different. The more senior the developer, the less willing they seemed to use AI on the software that mattered most.

That sounded like a culture problem. It was not.

The engineers used coding assistants for prototypes, small internal tools, dashboards, documentation, and isolated helpers. They avoided them in a large, old, business-critical part of the product.

That distinction mattered.

The critical system had grown over years. It contained domain rules that were not fully documented. Small calculations moved real money. A change that looked local could affect customer balances, orders, invoices, or downstream processes. Some shortcuts were intentional. Some were historical accidents. The difference lived in the heads of a few experienced engineers.

Those engineers could write a change themselves and understand every decision they made. With generated code, they had to reconstruct someone else's reasoning after the fact.

Reviewing the generated change often took longer than writing it.

Refusing that workflow was not resistance. It was professional judgment.

## Generation became cheap. Confidence did not.

AI coding tools reduce the cost of producing plausible code. They do not automatically reduce the cost of proving that code is correct.

That gap grows with the risk and complexity of the system.

In a small dashboard, a wrong margin or broken filter is annoying. You fix it and redeploy. In a payment, pricing, or order-processing module, a subtle error can lose money, corrupt data, or create a customer incident that takes days to unwind.

The same generated diff has a different verification cost in each context.

Senior engineers understand this instinctively. They do not ask only whether the code compiles or whether the tests pass. They ask:

- Which undocumented assumption did this change make?
- Which old workaround did it remove by accident?
- Does the test cover the business rule or only the implementation?
- What happens with data created five years ago?
- Which downstream process depends on this strange output?
- Can I put my name on this pull request?

That last question is the real one.

Accountability stays with the human reviewer. The tool does not take the incident call. It does not explain the loss to a customer. It does not own the rollback.

If the reviewer cannot build confidence efficiently, more generated code creates more work, not more throughput.

## Output is the wrong metric

The attraction of output metrics is obvious. They are easy to count.

Code volume, commits, pull requests, completed tickets, and tokens all produce clean dashboards. None tells you whether the company became better at delivering valuable software.

AI makes these metrics worse because it makes production volume cheap. A team can create more code while increasing review time, rework, defects, and operational risk.

Measure the flow of validated value instead.

Useful questions include:

- How long does a change take from decision to safe production use?
- How much review time does it need?
- How often is generated code discarded or heavily rewritten?
- How many defects escape into production?
- How often do changes need rollback or follow-up work?
- Did the change improve a customer or business outcome?

These metrics are not as comfortable as counting commits. They are closer to the work the company actually cares about.

The goal is not maximum code output. The goal is minimum time to a trustworthy outcome.

## Map the software by consequence

The client's system was not one uniform codebase. It had at least two very different change environments.

The first was a protected core. It contained old, complex, business-critical logic. Errors had direct financial or operational consequences. Verification depended heavily on domain knowledge.

The second was a speed zone. It included dashboards, internal applications, reporting tools, prototypes, and user interfaces where mistakes were visible but recoverable.

Treating both zones with one AI policy made no sense.

For the speed zone, the default could be aggressive AI use. Generate the first implementation. Iterate quickly. Keep changes small. Test the important paths. Fix mistakes when they appear.

For the protected core, the initial rule could be the opposite. No agent-generated production changes until the team has a reliable way to compare behavior and assess risk. The experienced engineers keep ownership.

This is not a permanent ban. It is a boundary based on evidence.

You can make the boundary more precise with three questions:

1. What is the consequence of a wrong change?
2. How quickly can we detect it?
3. How confidently can we restore the previous state?

High consequence, slow detection, and difficult recovery belong in the protected core. Low consequence, fast detection, and easy recovery belong in the speed zone.

Everything else sits between them and needs an explicit decision.

## Use AI to build the safety net first

Legacy systems often lack the tests needed to validate large generated changes. Writing complete tests for every module would take too long, especially while the team still has to deliver features.

This is where coding agents can provide useful leverage before they write production logic.

Start with characterization tests.

A characterization test records what a system does today for a defined set of inputs. It does not claim that the behavior is correct. If the system contains an old rounding error or strange edge case, the test may capture that too.

That is the point.

Before you improve a system, you need to know when you have changed it.

For a selected module, the workflow looks like this:

1. Identify representative inputs, outputs, side effects, and failure cases.
2. Record the current behavior in executable tests.
3. Review the tests with engineers who know the domain.
4. Run them against the current implementation to establish a baseline.
5. Let the agent propose a refactoring or implementation change.
6. Compare the behavior, then investigate every intentional or accidental difference.

Coding agents are often good at the repetitive parts of this work. They can read existing code, enumerate branches, propose input combinations, create fixtures, and turn observed inputs and outputs into tests. They still need review, but the review target is narrower.

You are not asking the agent to invent the correct business behavior. You are asking it to help describe behavior that already exists.

That is a much safer delegation.

## Do not test everything at once

The lazy answer would be to demand full test coverage before any AI-assisted work touches the legacy system. It would also ensure that nothing changes for months.

Pick the modules where a safety net creates immediate value.

Good candidates have several of these properties:

- They change often.
- Engineers avoid them because the risk is unclear.
- They block valuable product work.
- Their inputs and outputs can be observed.
- They have repeated incidents or regressions.
- Their current owners spend too much time on manual verification.

Start with one module. Create the characterization tests. Measure whether review becomes faster and more confident. Then repeat where the result justifies the effort.

This turns AI adoption into an engineering improvement program instead of a motivational campaign.

## Expand autonomy in stages

Once the safety net exists, do not jump straight from "no AI changes" to "agent owns the module."

Increase autonomy in small steps:

1. **Explain:** The agent maps the module, dependencies, and known risks.
2. **Characterize:** It proposes tests for current behavior.
3. **Assist:** It suggests small changes while a developer writes or directs the implementation.
4. **Implement:** It creates bounded changes behind strong tests and review.
5. **Operate:** The team considers broader automation only after production evidence supports it.

The exact stages matter less than the direction. Trust should follow evidence. It should not precede it.

This also gives senior engineers a productive role in adoption. They are not obstacles to work around. They are the people who know where the system is fragile, which behaviors matter, and which tests would create real confidence.

Their experience becomes the control system for AI-assisted development.

## The role disappeared when the problem became concrete

At the start, the company thought it needed a senior leader to persuade engineers to use AI.

By the end, that role was no longer the obvious answer.

The engineers did not need a motivator. They needed a safer delegation model, better verification, and clear boundaries for different parts of the product. The existing team could start that work with the tools it already had.

A Director of AI Engineering may still make sense for a company with a broad platform strategy, multiple AI products, model infrastructure, governance needs, or a large organizational rollout. It did not make sense as a response to weak coding-tool adoption.

Do not hire someone to fix resistance before you understand what people are resisting.

If experienced engineers avoid AI in one part of the system, look at the consequence of being wrong. Look at the review burden. Look at the missing tests. Look at who carries the accountability.

When generated code is expensive to trust, adoption is not the first problem to solve.

Make verification cheaper. Adoption will follow.
