The broken apprenticeship
The boring middle was the school. Agents just closed it.
A junior engineer opens a pull request. The feature works, the tests pass. You ask why they put a queue there instead of calling the service directly, and the answer does not survive a second question. Not because they are careless. Because nothing in the work they did required them to know.
I have written before about what this does to an individual engineer: the reps that build judgment, and the way an agent lets you skip them. This is about the layer above that. Software had a training system. Almost nobody designed it, most of us never noticed it was there, and it ran entirely on the work we were most eager to hand away.
That system is the apprenticeship, and it is coming apart.
What the boring middle taught
Apprenticeship used to have a shape. An apprentice spent years on the drudgery of a trade, preparing materials, doing the parts no master wanted to touch, and somewhere in those years, with no syllabus, absorbed the judgment of the craft. The drudgery was the training.
Software never formalized any of that. The version we got was the boring middle, and it rolled downhill to whoever was newest. The fourth CRUD endpoint. The migration you ran against production with your stomach in a knot. A day lost to a bug that turned out to be a timezone. The glue between two systems whose schemas almost matched, until the afternoon they didn't. Nobody called it teaching. It was just the work.
And it taught the whole time. You learned what to name things by naming a few hundred things badly and living in the wreckage. You learned which failure modes are real, as opposed to the ones the textbook warns about, by being the person holding the pager when one of them finally went off.
You developed a feel for when an abstraction is wrong before you could say why, because you had built the wrong one once and spent a quarter paying it back.
None of it was on a syllabus. The judgment came from doing enough of it, and nobody could point to the day it arrived.
Why it's gone
The boring middle is the first thing the agents took, and they are good at it. The fourth CRUD endpoint is exactly the kind of thing a model writes correctly in seconds. I am not mourning the work itself; it was boring for a reason, and I have argued elsewhere that most of it was never worth a human's afternoon.
The tedium was carrying a second job nobody wrote on the invoice. Automate it and you also automate the apprenticeship that was hiding inside it. The endpoint still gets built. The lesson the endpoint used to teach does not get taught, because no one had to sit in the tedium long enough to learn it.
The break
You cannot judge what you have never built.
The junior in the opening is as capable as we were. They are just further from the work. The feature arrives correct, so the questions that getting it wrong used to force are never asked. The gap between shipping something and understanding it used to close on its own, one painful bug at a time, because the bugs were yours and you had no choice. Now it stays open. Nothing walks you through it.
And the gap hides. Polished output looks the same whether or not anyone understands it, so the person with the gap is often the last to see it, right up until the day the thing breaks in a way no agent was asked to consider.
Reading the diff
The friction used to be free. You built judgment by doing the work, because the work would not let you avoid it. That is gone. If you want the friction now, you have to put it back by hand.
The place to put it back is the diff. An agent hands you two hundred lines. The cheap move is to check that it works and merge. The slower one is to read every line and make it explain itself.
Say the change is this:
async def charge(order, card):
- card.charge(order.total)
+ await card.charge(order.total)
return Receipt(order.id, order.total)
Four lines, tests green. Now sit with it. Why was that call synchronous a second ago, and what was it doing to the event loop before the await went in? What happens to the Receipt if the charge raises halfway through? Which of these lines has never once run against a real card? You are not writing the code anymore, so reading it is the only place left to do the thing writing used to do to you.
This is not the same as reviewing. Reviewing asks whether the code is good enough to ship. Reading the diff, the way I mean it, asks the code to teach you what writing it would have. You reconstruct the reasoning you never got to have, find the choice you would have made differently, and make yourself say why. Done honestly it is slow and a little humiliating, which is what the boring middle always felt like.
It is the new grinding. Nobody will assign it to you, because on paper the work is already done.
Who rebuilds the ladder
I can tell one person to read the diff. I have no idea how you make a field do it.
That is the part I cannot resolve. Reading the diff is a private discipline. It scales to exactly one engineer who chooses it, on their own time, against every incentive pointing at merge and move on. The apprenticeship it replaces worked the other way. It was structural, something that happened to you whether you wanted it or not, because the work itself demanded it. You do not rebuild that out of a habit a few conscientious people keep.
Maybe teams start protecting the boring middle on purpose, the way some of them learned to protect code review once it stopped looking worth the time. Maybe apprenticeship becomes an explicit line item instead of a side effect nobody has to fund. Maybe the tools grow a mode that makes you earn the answer. I would not bet on any of it, and I do not have a better fourth option.
So I will end where I actually am. The old ladder is losing its lower rungs, and the fix I trust is one person deciding to climb the hard way anyway. That is enough for you. It is not enough for the field. Ask me again in a few years, and hope one of us has a better answer by then.