The Fix Worked. The Understanding Didn't.
Sep 16, 2026 · 13 min read
An engineer described a production problem that could have become serious.
An AI coding assistant found the issue and produced a fix. The fix worked. The problem was resolved before it could cause the damage everyone had feared.
There was only one uncomfortable detail.
The engineer still did not know what the issue had been.
He joked that he was receiving credit for solving something he did not understand. The AI had identified it, the result was correct, and from the outside he was the person who had fixed it.
The room laughed, but the story stayed with me.
Not because using AI was wrong. Using it had helped prevent a production problem. That is a real outcome, and it is exactly the kind of leverage these tools can provide.
What stayed with me was the gap between resolving an issue and understanding it.
The fix worked. The understanding did not remain with the engineer or the team.
The first room I did not speak in
The conversation happened during an internal tech talk with around twenty to thirty engineers.
It was my first time being part of a discussion like that. The topic was how AI is changing engineering: writing code, reviewing merge requests, investigating production issues, and helping teams move through work that would otherwise take much longer.
The timing made the discussion especially relevant. The company had recently gone through an intense sprint. A large amount of work had moved at once, and people did not always have enough time to review every merge request manually in the depth they wanted.
AI tools became part of the review process. They helped people summarise unfamiliar changes, inspect implementations, and understand what an author was trying to do before a human reviewer went through the details.
The stories were interesting because they were not predictions about what AI might do one day. They were examples of what engineers in the room had already used it for.
I listened to all of them without contributing anything.
But there was one idea I wanted to add.
It came from a much smaller conversation at a previous workplace—usually just me and a team lead—and from a rule he had followed long before AI coding assistants existed.
Every file should be readable.
The rule from my previous team
For him, readable code meant more than good variable names or small functions.
Before a function, class, or important block of logic, he would often leave several lines explaining why it existed. The comment described the problem that had led to it, the architectural decision behind it, and sometimes the constraint that made a more obvious solution unsuitable.
Months later, when he returned to the file, he did not have to reconstruct the entire decision from the implementation. He could read the explanation and recover the model he had when he wrote it.
The code showed what the system did.
The comment preserved why it did it that way.
We started following the same practice on one of our projects. If a change touched ten or fifteen files, the important decisions travelled with those files. A reviewer did not have to begin with a blank page and infer the author’s reasoning from every branch and function call.
They could first read the intended behaviour and then ask a more useful question:
Does the implementation actually do what this explanation says it should do?
That changed the shape of review. The reviewer could understand the purpose before inspecting the mechanics. The author had to make the reasoning explicit. An AI assistant could also use the explanation as local context while analysing the change.
At the time, we treated those comments almost as a review requirement. If the reasoning was missing, the review could stop until the author explained it.
I still believe the underlying principle is valuable. I no longer think the best version of it is “write six lines before every function.”
Readable is not the same as heavily commented
There is an obvious objection to this approach.
Comments can become noise.
A comment that merely translates code into English adds another thing to maintain without adding understanding. A comment that says a counter is being incremented is less reliable than the line directly below it. If the implementation changes and the comment does not, the explanation can become more dangerous than having no explanation at all.
Requiring a fixed amount of commentary before every function can also reward volume instead of clarity. Simple code becomes surrounded by paragraphs, while the one non-obvious decision that truly needs an explanation can still be missed.
Readable files begin with the code itself: naming, structure, types, boundaries, and tests. Comments should not compensate for code that can be made clearer.
The comments worth preserving are the ones the implementation cannot express on its own.
Why was this boundary chosen?
Which production constraint makes the obvious solution unsafe?
What invariant must a future change preserve?
Which alternative was tried and rejected?
Why does this apparently unnecessary line exist?
Those are not descriptions of syntax. They are pieces of engineering history.
Some belong beside the relevant code. Larger decisions may belong in an architecture record, a design document, or a merge-request description. The format matters less than whether the reasoning remains discoverable when the original author is no longer present.
The documentation we promise to write later
The cleanest answer is usually a separate document that is updated after every important implementation.
Most engineers already know that.
The harder question is whether we consistently do it.
I do not. I have finished features while fully intending to document the decisions later, then moved to the next task once the code was working. I do not think I am unusual in that.
Documentation is easy to treat as a second piece of work. Under deadline pressure, the implementation is required and the explanation becomes optional. A few weeks later, the missing context is difficult to reconstruct accurately.
A useful comment has one practical advantage: it lives beside the decision it explains. It appears in the same diff, is reviewed with the same change, and moves with the code when the file changes.
That does not make separate documentation unnecessary. It makes the smallest durable explanation harder to postpone.
This becomes more important when AI is involved, because AI systems are extremely dependent on the context we give them.
AI can read the code, but it cannot recover missing intent
An AI coding assistant can inspect a function and explain what it appears to do. It can trace calls across a repository, compare a change with a test, and often find patterns a person missed.
What it cannot reliably recover is intent that was never recorded.
It may infer why an engineer chose a design, but an inference is not the decision itself. The tool does not know about the conversation that happened before the code was written, the production incident that made one edge case important, or the alternative that looked cleaner but failed under a constraint outside the repository.
Without that context, an AI-generated explanation can sound confident while being historically wrong.
This is why I think AI makes readable intent more important, not less.
When code becomes faster to produce, understanding becomes the slower and more valuable part of the system. A team can generate more changes and review them with more tools, but every unexplained decision still becomes a future investigation.
Context is not only something we provide in a prompt. It is something a team leaves behind in the codebase.
The review queue AI inherited
During a difficult sprint, using AI to get through a review queue is reasonable.
It can summarise a large merge request, identify affected areas, highlight suspicious paths, and help a reviewer decide where to spend attention. Used well, it gives the reviewer a better starting point.
But a summary is not accountability.
The reviewer still needs to understand the risk, verify behaviour, examine tests, and decide whether the change belongs in production. Asking an AI whether the code matches a comment is useful, but it answers only one part of the review.
There is also a circular failure mode worth noticing.
If an AI writes the code, writes the comment that explains the code, and then reviews whether the code matches its own comment, the team has not gained three independent checks. It may have repeated the same mistaken assumption three times.
The author still has to own the intent. The reviewer still has to challenge it. The AI can accelerate both sides, but it cannot become the person responsible for the decision.
The production story from the tech talk is a good example. Solving the immediate issue was valuable. The missing step was closing the loop afterward: identifying the root cause, recording why the fix worked, and leaving enough evidence for the next engineer who encounters the same class of problem.
AI can help write that explanation too. It should not be allowed to replace the need for one.
The skill we built
Even when a team agrees that explanations are useful, people forget to ask for them.
We did too.
So we created a small AI skill for the project. Its job was to remind the coding assistant to add or update comments around the functions and decisions it changed.
The automation helped with consistency. It meant the request did not depend on someone remembering to include “add comments” in every prompt.
But the best version of that skill should not blindly generate a paragraph above everything. It should ask a harder set of questions.
Is this decision non-obvious?
Is there a constraint that is not visible in the code?
Would a future engineer be likely to simplify this and accidentally reintroduce a problem?
Does the existing comment still match the implementation?
If the answer is no, the code may not need a comment. If the answer is yes, the assistant can help draft one, but the engineer who owns the change should confirm that it describes the real reason rather than a plausible-sounding invention.
Automation is useful for remembering the practice. It cannot supply intent that the team itself does not understand.
Why I stayed quiet
I thought about sharing this during the tech talk, but I did not.
I was new to the company. I was the only junior engineer in a room filled with people who had much more experience in the organisation and its systems. I had not yet built the credibility that comes from solving difficult problems with a team over time.
Part of me imagined somebody hearing the suggestion and wondering who the new person was to propose a change to the way they worked.
I am also introverted, especially in a new group. When I am comfortable with someone, I can explain an idea through a long conversation and adjust when I see what they understand. In a large room, I feel pressure to make the entire idea clear in the first attempt.
That pressure often makes the explanation less clear.
It is not mainly an English problem. It is a structure problem. I know the connections in my head, but I do not always deliver them in an order another person can follow without already knowing me.
So I listened.
Staying quiet was not necessarily a mistake. Being new means I do not yet know all the reasons behind the team’s current practices. An idea that worked in one project may not transfer cleanly to another. And as I thought about it afterward, I realised that the strongest version of my argument was more precise than the one I would have given in the room.
The point is not that every function needs a long comment.
The point is that important decisions need durable context.
Proving it before proposing it
I do not need to introduce a company-wide rule to test whether this helps.
I have an upcoming feature that I expect to implement largely on my own. That gives me a smaller experiment.
I can keep the implementation readable, add rationale comments only where a decision would otherwise be difficult to recover, and explain the larger tradeoffs in the merge request. When my team lead reviews it, I can ask a simple question:
Did this context make the review easier?
The useful signals are not the number of comments or the number of lines they contain. They are whether the reviewer understands the change more quickly, asks fewer questions that the code could have answered, and can identify where the implementation disagrees with its stated intent.
There is one more test: when the feature changes later, do those explanations remain true?
If the approach helps, I will have something better than a suggestion from the newest person in the room. I will have an example from our own codebase and feedback from someone who reviewed it.
If it does not help, I can adjust the idea without asking everyone else to adopt it first.
That feels like a better way to contribute: not waiting forever to prove that I deserve to speak, but doing enough work to make the conversation concrete.
The thing I wanted to say
If I had spoken during the tech talk, this is what I would have wanted to say:
AI is making us faster at producing fixes, reading unfamiliar code, and moving reviews forward. That is valuable, and I want to use it.
But speed creates a new responsibility.
When an AI finds an issue that we cannot explain, the task is not fully complete when the error disappears. When it helps us review a merge request, the review is not complete because the summary sounds reasonable. When it generates code, the intent behind that code does not automatically become part of the repository.
We still have to preserve the reasoning.
Not with comments that repeat every line. Not with documentation written only to satisfy a rule. With enough durable context that a future engineer—or a future AI assistant—can understand the decisions the implementation alone cannot reveal.
The engineer in the room solved the production problem. The tool deserved some of the credit. So did the person who knew when to use it and had the judgement to act on the result.
The next step was to make sure the understanding did not disappear when the conversation ended.
I did not say that in the room.
This post is my first attempt at saying it clearly.