Skip to content

Instantly share code, notes, and snippets.

@tamnd
Created May 7, 2026 19:18
Show Gist options
  • Select an option

  • Save tamnd/11665e492d7a3b91ce54e26ecbd97248 to your computer and use it in GitHub Desktop.

Select an option

Save tamnd/11665e492d7a3b91ce54e26ecbd97248 to your computer and use it in GitHub Desktop.
The Programmer After AI

The Programmer After AI

Programming used to leave fingerprints.

A person who wrote a piece of code had usually spent enough time inside it to know something about it. Not everything, and often less than they claimed, but enough to carry some memory of the choices. They had named the variables, moved the data around, found the missing branch, stared at the error, and returned to the same file often enough that the program had passed through them.

That link has weakened. A programmer can now produce a large diff without having lived with the decisions inside it. The code can arrive with good names, reasonable structure, plausible tests, and a calm explanation of the tradeoffs. It can look considered before anyone has really considered it.

This changes the job.

The first time I felt it clearly, I was reading a pull request that looked fine in all the ordinary ways. The description was clear. The implementation had the shape of something written by a competent person. The tests covered the expected path. Nothing looked absurd. Then I asked why one boundary had been placed where it was. The answer drifted. It was not ignorance exactly. It was a kind of borrowed certainty. The person could describe the change, but the reason for the change seemed to live somewhere else, probably in the conversation that produced it.

That moment has become familiar. AI can produce code that looks like it came from judgment. Sometimes it did. Sometimes the judgment came from the programmer, and the tool merely saved time. Other times the tool supplied the shape, the explanation, and the confidence, while the programmer supplied acceptance.

Those two cases look similar from the outside. They matter very differently.

Code volume has become cheap

For years, software teams had a confused relationship with code volume. Everyone knew that more code did not automatically mean more progress, yet large diffs still carried a certain weight. They suggested time spent. They suggested effort. A person may have written the wrong thing, but they had at least passed through the thing.

AI removes much of that cost. One person can now generate an implementation, tests, configuration, documentation, and a migration in the time it takes another person to understand the first file. The writer moves faster because generation has become cheap. The reviewer still reads at human speed.

That is where the pressure moves. The bottleneck after AI is judgment.

The valuable programmer becomes the one who can look at a pile of plausible code and say what should stay, what should shrink, what should be deleted, and what should never have been written. This sounds ordinary. It becomes much harder when the code looks familiar enough to pass. Bad generated code rarely announces itself as bad. More often it arrives as slightly excessive software: a layer too many, a helper too broad, a test that proves little, a comment that explains the obvious, an abstraction created before the need exists.

Each piece looks harmless. Together they make the program heavier.

The programmer after AI has to become less impressed by the presence of code. Code used to be expensive enough that its appearance meant something. Now it means less. Attention means more. Taste means more. The ability to keep a system small means much more.

Reading becomes real work

Software organizations like to say that reading code matters. Their incentives often say otherwise. New code shows up in tickets, commits, dashboards, demos, and performance reviews. Reading code looks quiet. It can look like delay.

After AI, that quiet work becomes central.

When generation gets cheap, reading protects the system. Someone has to build the mental model. Someone has to ask whether the behavior matches the requirement, whether the error path makes sense, whether the data belongs in that shape, whether the new abstraction earns its place. The person doing that work may look slower than the person producing the diff. They may also be the only person preventing the team from turning motion into debris.

Generated code needs a different kind of review. You cannot assume the author paid the old price of writing. They may have prompted well, edited some pieces, run the tests, and understood the happy path. That still leaves many decisions unowned. A reviewer has to ask very plain questions.

What problem does this solve?

Where does the data enter?

Where does it persist?

What happens when the call fails halfway through?

Which part of this design will we regret if the requirement changes next month?

These questions have always mattered. AI makes them harder to avoid because it produces so much code that seems to have already answered them. The fluency is the danger. It makes unfinished thought look finished.

A good programmer after AI will read with suspicion, but not with reflexive contempt. Some generated code will be useful. Some will be better than a rushed human draft. The task is evaluation, not rejection. The programmer has to separate useful output from confident residue.

The junior problem

Junior programmers used to learn through small work. Fix a bug. Add a field. Write a test. Rename a thing and see what breaks. Read a stack trace badly, then a little better. These tasks were not glamorous, but they put the beginner close to cause and effect. The lesson was often hidden inside the chore.

AI threatens that path in two directions. Companies may give less simple work to juniors because the tool can do much of it. Juniors may also use the tool to make their work look more senior before their judgment has caught up. Everyone can feel satisfied for a while. The junior ships more. The manager sees movement. The senior reviewer sees fewer obvious mistakes. The tool explains everything in a voice that sounds like experience.

The loss appears later. The junior has fewer memories of struggling with small, real pieces of the system. They have fewer chances to build the reflexes that make larger work possible. They may learn how to ask for code before they learn how to read it. They may learn how to recover from errors by pasting them into a chat before they learn how errors move through a program.

This creates a strange apprentice: productive on the surface, fragile underneath.

The fix will look inefficient. Juniors need to write some boring code by hand. They need to explain their changes without the generated summary. They need to debug before asking for a patch. They need to read code they did not write and say what it does. They need tasks small enough that their understanding can catch up to the artifact.

A company that removes all of this in the name of speed may save time in the present and destroy its future senior engineers.

The senior problem

Senior programmers face a quieter risk. They can use AI well because they already know enough to reject bad output. That makes the tool genuinely powerful for them. They can ask for a draft, spot the weak parts, keep the useful ones, and move faster.

But the same skill can hide decay. A senior engineer can slowly shift from doing judgment to receiving judgment-shaped text. Ask for the design alternatives. Ask for the migration plan. Ask for the edge cases. Ask for the review comments. Ask for the incident summary. Each request makes sense. Together, they thin the contact between the person and the material.

Expertise requires maintenance. You keep it by reading the diff, tracing the failure, checking the assumption, following the data, and sitting with the part that refuses to become clear. If the model always enters before that discomfort, the senior person may still speak like an expert while touching the system less and less.

This decay does not look dramatic. It looks efficient. That makes it harder to catch.

The senior programmer after AI has to guard the acts that keep them senior. They can use the tool for leverage, but they should not let it consume the parts of the work that sharpen judgment. Reading, debugging, simplifying, and taking responsibility cannot all be delegated. At least some of the hard contact has to remain human.

Ownership matters more than authorship

AI makes authorship messy. A line of code may come from a model, a library example, a teammate, an old Stack Overflow answer, or some mixture of all of them. This was already true in a softer form. Programmers have always built with borrowed pieces.

Ownership matters more.

Can you explain the code without reopening the chat? Can you change it safely? Can you remove part of it? Can you say why the data has this shape? Can you debug it when the model gives the wrong explanation? Can you defend the behavior to a teammate, a user, or yourself three months from now?

If the answer is no, the code may be in your repository, but it has not fully entered your understanding.

The programmer after AI does not need to type every line. That standard would be silly. They need to become the accountable mind through which the code passes. The code can be drafted by a model. It can be suggested by a tool. It can be adapted from somewhere else. Before it matters, someone has to understand it well enough to own the consequences.

This is a higher standard than keeping a human in the loop. A human can sit in the loop as a clerk, approving, copying, and forwarding. The useful human in the loop can say no. Or smaller. Or not yet. Or this fails when the input is empty. Or this abstraction will outlive the problem and make every future change worse.

Smaller becomes a professional skill

AI likes to be helpful, and helpful often means more.

More files. More layers. More configuration. More tests. More explanation. More options for future extension. The answer looks complete because completeness has a visible shape. It is harder to see the value of the code that never gets written.

The programmer after AI needs a strong bias toward smallness. Not smallness as an aesthetic. Smallness as a way to preserve understanding. A smaller function can be read. A smaller interface can be replaced. A smaller diff can be reviewed. A smaller system can fail in ways people can still trace.

This will often require cutting down what the model gives you. Ask for the plain version. Remove the layer. Inline the helper. Delete the option. Replace the generic mechanism with the concrete operation. Do the boring thing until the boring thing no longer works.

There is a certain maturity in disappointing the generator. It means you know the problem well enough to refuse the extra furniture.

Trust becomes the product underneath the product

Users and clients do not really buy code. They buy behavior they can trust. They want the program to do the thing, keep doing it, fail in understandable ways, and change without turning into a new problem.

AI will produce more software-shaped output than organizations know how to absorb. More prototypes, more dashboards, more internal tools, more services, more automation around processes that may not have needed automation. Some of it will help. Some of it will become maintenance sediment. The difference will not always be visible at the demo stage.

The programmers who remain valuable will be the ones whose work can be trusted after the demo. They will know what they shipped. Their systems will have fewer strange corners. Their tests will point at real risks. Their explanations will survive contact with the code. Their incident reports will describe causes, not activity.

This may look slower. Trust often looks slower until the faster path breaks.

What remains human

The human part of programming was never the typing. Typing only made the work visible. The human part was deciding what should exist, understanding what does exist, and carrying responsibility for the gap.

AI can help with many parts of that. It can make examples cheap. It can explain unfamiliar APIs. It can draft tests. It can translate between languages. It can search a neighborhood of possible solutions quickly. Used well, it gives good programmers more room to think.

Used badly, it gives everyone more room to avoid thinking while appearing productive.

The programmer after AI has to live in that tension. Refusing the tool entirely will become impractical in many environments. Trusting it completely will become professional negligence. The job sits between those failures.

Read more than you generate. Keep the hard parts close. Use the model for drafts, not for ownership. Treat fluent explanations as claims to inspect, not conclusions to inherit. Be suspicious of code that appears faster than your understanding. Prefer the smaller version until the larger one has earned its place.

At some point, after the generated diffs, the summaries, the review comments, the agents, and the explanations, a program will fail for a specific reason in a specific place. Someone will have to find that reason. Someone will have to understand the system well enough to fix it without making it worse.

That person is the programmer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment