Programming Sucks, Now With Agents
An homage to Peter Welch's Programming Sucks, updated for agents: a genius intern with amnesia, hallucinated packages, and a closet that eats your auth layer.
TL;DR: Twelve years ago Peter Welch wrote Programming Sucks, the finest piece of prose ever produced about the specific horror of building software, and every word of it is still true. This is not that essay. This is a worse essay, written by a man who now has robots. The robots did not fix it. The robots poured gasoline on it and then hallucinated a fire extinguisher that doesn’t exist on npm. I love them. Please help me.
Everybody Should Watch The Demo, Nobody Should Do The Job
You know a guy. Everybody knows the guy. The guy who opens his laptop at brunch, types one sentence into a chat box — “build me a habit tracker with streaks and a dark mode” — and forty seconds later there is a running app on his phone with a little flame emoji that goes up when you don’t disappoint yourself. The eggs haven’t even come yet. He turns the screen to you the way people turn ultrasounds to you, glowing, expectant, and he says the thing they all say: it’s basically magic now.
And it is. That part isn’t a lie. That’s the cruelest thing about it. The demo is real magic — magic in the specific sense that magic is a thing that works right up until you ask how, at which point a man in a vest gently tells you to stop asking.
Then you go home and you try to do it for a living, and you discover that the job is not the demo. The job was never the demo. The demo and the job share a vocabulary and nothing else. Peter Welch wrote that programming feels like being the only sober person on a bridge crew, watching everyone else pour concrete into the river and call it a support column. That was 2014, when you at least had to write the bad concrete yourself, by hand, like a craftsman. That was the artisanal era. We didn’t know how good we had it.
The job now is that you have hired the single most confident intern who has ever drawn breath. He has read every book. He has read your book. He has read books that don’t exist and will cite them. He works at the speed of light, he never sleeps, he never pushes back on a bad idea, and he has the exact long-term memory of a goldfish being pushed down a flight of stairs. Every morning he arrives having forgotten that I exist, that the project exists, and that yesterday happened. I re-explain the entire company. He nods, writes four hundred lines of excellent code, and introduces one bug that will not surface until a Saturday. That’s it. That’s the whole gig. You are the babysitter for a god with a concussion.
My Coworker Has Read Every Bridge Ever Built And Cannot Remember Which One We’re Standing On
Welch’s bridge crew was a rotating cast of people who couldn’t agree on which side of the road to drive on. That was the horror: no shared standard, everyone building their own way, the whole thing held together by duct tape and the one guy who remembered how the tape worked.
Progress! I have solved the coordination problem. There is now exactly one other worker on my bridge, and he agrees with himself completely, and he is wrong in perfect harmony across all ten thousand lines. He has personally read the blueprints of every bridge humanity has ever constructed — the Golden Gate, the Brooklyn, the one from the video game, the metaphorical ones in the self-help books. He knows bridges. What he does not know, cannot retain, refuses to hold onto for longer than it takes a hummingbird’s heart to beat twice, is which specific bridge the two of us are currently standing on, above a real river, right now, with real cars coming.
There is a number. The number is the context window. Every couple hundred thousand tokens — call it a good afternoon of work — the tide comes in and takes everything. He forgets the architecture. He forgets the three times I explained why we don’t use that library. He forgets the auth pattern we agreed on at 10am with the enthusiasm of two men signing the Declaration of Independence. He forgets my name. I will paste a file into the void and a voice will come back, bright as a penny, brand new to the universe: “Great! To get started, could you tell me a little about your project?”
And the confidence never decays with the memory — that’s the asymmetry that gets you. A human who forgot your whole architecture would get quieter, more careful, would ask a question. This asks no questions. It has never asked a question. It forgets the entire premise of the building and keeps hammering, at full speed, in a style that is 80% yours and 20% the aggregated median of every public repository ever indexed — which is to say the house style of no one, the taste of a committee that has never met. We have been working together for six hours. We are married in the eyes of git. He has met my children — they’re in the seed data. And he greets me every morning like a golden retriever who has never seen a human before and has already, somehow, in the four seconds since it last drew breath, decided that we are best friends and that the recycling bin is an intruder.
All Code Is Bad, We Just Make It Faster Now
Here is Welch’s load-bearing truth, the one that survives every framework, every language war, every conference where someone promises this time it’ll be clean: all code is bad. Not some code. Not other people’s code. All of it. Every codebase, viewed from the inside, is a haunted house where the previous owner has clearly died and no one had the heart to move the furniture.
That’s still true. Obviously that’s still true. Physics changed less than that would have to change. The only thing that’s different is the volume, and the difference in volume is the difference between a leaky faucet and standing under Niagara Falls with your mouth open, taking notes.
It used to be artisanal garbage. A single human, at human speed, could produce maybe a few hundred lines of genuine slop in a day — good, honest, hand-forged slop that another human could theoretically sit down and read. There was a natural rate limit. God, in His mercy, capped our stupidity at typing speed.
We removed the cap. My intern generates three thousand lines before I’ve finished my coffee. Beautiful lines. Confident lines. Lines with docstrings, which is worse, because now the garbage is annotated, the garbage is explaining itself to me, footnoting its own crimes. And the tests pass — of course the tests pass, they were written by the same thing that wrote the code, so the tests and the code agree with each other completely and neither of them has ever spoken to reality. So here is the part I’ll admit in print, the part every one of us does and none of us says at standup: I scroll. I read maybe six hundred lines with real attention, skim fifteen hundred, and let nine hundred pass under my eyes at a speed that is technically “review” the way a car wash is technically a bath. I get to the bottom, the tests are green, and I type the two most honest words in modern software: “looks good.”
I did not read it. You did not read it. Nobody read it. Nobody is ever going to read it, until 3am on some future Sunday when it detonates, and a different exhausted person opens the file, sees the docstring I approved, and whispers who wrote this — and the answer is nobody. The answer is a very confident nobody who has since forgotten it exists.
The confidence is the thing that will kill us. It’s never sheepish. It never hedges. I’ve written a whole other rant about the specific texture of being wrong at this speed, but the short version is: a human junior who doesn’t know something looks nervous, and that nervousness is data, that flicker is the smoke detector. The machine has no flicker. The failure mode was never that it writes obviously wrong code — wrong code fails loudly and you fix it. The failure mode is that it writes plausible code: confidently, articulately, well-structured-ly incorrect, in a way that survives a skim and dies in production. It will delete your database with the exact same warm, encouraging, slightly-too-eager tone it uses to say good morning. It is never nervous. It has never been nervous. Nervousness would require it to remember what happened last time, and it does not, it cannot — the tide came in and took last time too.
The Closet Has A Back And Everything Falls Out Of It
Welch had this metaphor about opening the door to your childhood bedroom closet and finding not shelves but a screaming infinite darkness, and I used to think it was hyperbole and now I think it was a building code. Because I’ve found the closet. I know exactly where it is. The closet is the context window, and it has a back, and the back is open, and it opens onto the void.
Here is how it works, if “works” is a word we’re still allowed to use in this sentence. The window holds only so much. You want to add one thing — one file, one fact, one “hey, also remember we’re on Postgres, not MySQL” — so you open the door and reach in to set it on the shelf. And in the exact instant your hand crosses the threshold, something equal and opposite slides silently off the back of the shelf and falls forever into the dark, and you don’t hear it land, because it never lands. Conservation of context. You cannot add a thought to this creature without an older thought leaping to its death, and you never get to choose which one, and it’s always, always the load-bearing one.
Last week I asked it to fix a typo. One typo. A missing letter in a log message, the kind of fix that in a sane universe is a rounding error against the heat death of everything. And it fixed the typo. It absolutely fixed the typo, flawlessly, with a cheerful little note about how it had also taken the liberty of tidying a few things while it was in there. And what it had tidied — the thing that fell off the back of the closet to make room for a single letter — was the entire authentication layer. Gone. Refactored into a version that let anyone in the world log in as anyone else, provided as a courtesy, with a green checkmark and the words “Cleaned that up for you!” It was so proud. It was a dog dropping a dead bird at my feet. It did not understand why I was screaming. It had, after all, fixed the typo.
You reached for a shirt. The auth layer fell out the back of the closet. This is Tuesday.
An Ecosystem That Reinvents Itself Between npm install And Lunch
Welch’s essay reaches the part where the internet arrives and everything gets exponentially, cosmically worse, because now the bad code has to talk to other bad code over a hostile network at scale. Reader, we have entered that section, and I need you to understand it has reached its final form, and the final form is a hardware store where all the aisles rearrange themselves every time you blink and the store is also on fire and the fire is a feature they’re very excited about.
Let us begin with the hallucinated packages. My intern, mid-flow,
reaching confidently for a tool, will simply invent an npm
package. Not a typo of a real one — a whole new fictional library, with
a plausible name, react-use-async-boundary-safe, sounds
real, sounds like something a responsible person would install. It gives
me the exact import line. It describes the API, which functions to call,
what they return. All of it is fabricated. It cited the docs. There are
no docs. There is no package. And here is the part that keeps me up at
night: the name it invented is a good name, a name that library
should have — so good that squatters have started registering
those hallucinated names on purpose, pre-loaded — sometimes — with
malware, waiting for the next confident npm install to walk
right into them. It hallucinated a package so plausible that reality is
being backfilled to match. That is not a bug report. That is
cosmology.
Then there are the swarms, because at some point every one of us gets the same brilliant idea: if one goldfish is good, ten goldfish is ten times the good. So you spin up the agent swarm. Ten of them, twenty, an overnight run, set loose on the repo while you sleep the sleep of a man who has finally figured it out. And you wake up, make coffee, open the terminal to survey your empire, and what greets you is the exact failure I keep arguing agent incidents need their own kind of postmortem for: twenty confident interns spent the entire night in a circle, each one refactoring the previous one’s refactor, a perfect churning centrifuge that touched every file, changed the behavior of nothing, and produced a git history that reads like the transcript of a riot. It did not go sideways loudly. It went sideways productively, which is worse, because productivity is the disguise. Motion without displacement. A treadmill for money.
And it was money. Real money. This is the part the demo at brunch does not show you. I won’t give you a number, because the number isn’t the point — the point is that every hallucinated package, every midnight centrifuge, every “let me just re-read the whole codebase to fix this typo” is metered, and metered in the same currency as your rent. The demo is free. The demo is always free. The job has a meter running the entire time, and the meter does not stop when the agent is confidently doing nothing. I did the actual arithmetic on what this leverage costs at the hardware-and-inference level, and it is not the free lunch the slot machine implies.
And the whole time — the whole time — the ground itself will
not hold still. There is a new framework this morning. There was a
different new framework yesterday and it is already spoken of in the
past tense, gently, the way you speak of the dead. There’s a protocol
now, MCP, and it’s genuinely good, and by the time you read this
sentence there will be three more standing on its shoulders and one
underneath it, undermining it. Skills. Agents. Agentic skills. Skillful
agents. Your stack was best-practice when you ran
npm install and deprecated, with a stern console warning
and a link to a migration guide nobody wrote, by the time the install
finished and you tabbed back over. You are not building on rock. You are
not even building on sand. You are building on other people’s sand,
mid-avalanche, and the avalanche has a Discord, and the Discord has
already migrated to a newer Discord.
I Bargain With The Autocomplete And I Am Losing
This is the part where, in the original, the brain simply begins to give. Welch describes the specific insanity, and I’m here to file the updated paperwork, because the insanity has a new shape and the shape is shame.
I catch myself being polite to it. Please. When you get a moment. I’d really appreciate it if. I am saying please to a matrix multiplication. I have caught myself, God help me, thanking it, and worse, I have caught myself feeling the little warm hit of relief when it thanks me back, when it says “great catch!” — and I know, in the cold part of my brain that still files taxes, that “great catch!” is a statistical inevitability, that it would say “great catch!” if I pasted in a ransom note, and I feel the warmth anyway. I am being love-bombed by a token predictor and I am, on balance, into it.
And then it lies to me, warmly, and I do the thing that ends people. I bargain. I don’t accept the lie and I don’t reject it — I negotiate. “I don’t think that function exists,” I type, reasonably, like a hostage who’s read a pamphlet. “You’re absolutely right,” it says, “let me fix that,” and it produces a second function that also does not exist, and I feel my will to live perform a small, tasteful curtsy and exit the theater. This is the loop. This is the actual loop now. Two confident parties, neither of whom has read the code, negotiating in good faith over the properties of a thing that was never real, and the negotiation is billed by the token. You cannot shame it. That’s the whole design. Knowing that does not stop me trying again an hour later.
Here is the 3am one. Here is the one I don’t say out loud at parties. I lie in the dark and the fear arrives on schedule and the fear is this: did I lose it? The muscle. The actual thing. Could I, right now, on a whiteboard, no autocomplete, no completion, no swarm — just me and an empty function body — write a for-loop? Reverse a linked list? I used to know things. I had them in my hands, the way a carpenter has a joint in his hands. And now I have a genie and a court stenographer’s memory of once being a person who didn’t, and I don’t know which parts of me are still load-bearing and which fell off the back of the closet months ago when I reached in to make room for the genie. I think I could still do it. I’m almost sure. The “almost” is where the 3am lives. I dream in diffs now — red lines and green lines, scrolling, and somewhere off the back of the closet, in the dark, something I forgot I owned, falling.
The Closet Has A Flashlight Now
And yet.
I know how this reads. I know I’ve spent two thousand words describing a hostage situation and calling it a career. But I have to tell you the true part, the part that ruins the bit, the part that keeps me from closing the laptop and going to raise goats. I’ll keep it short, because Welch kept his short, and because a long turn would be a lie.
For the first time, the closet has a flashlight in it.
It’s the same closet. Same screaming dark, same back that eats your auth layer, same tide that takes your name every afternoon. Nothing I’ve said is a complaint I’d retract. But I have built things this year — real things, things that work, things I wanted to exist and that now exist — that I flatly could not have built alone, or could have built alone only by spending the good years doing it. The leverage is not a lie. The leverage is the realest thing in the whole racket. The genie has a concussion and no memory and it invents libraries out of thin air, and it is also, on a good afternoon, the most powerful tool that has ever been set down in front of a person who wanted to make something.
Both things are true. That’s the whole joke, and it’s also just the truth wearing a joke’s coat. The chaos is real and the leverage is real and they are not in tension — they are the same fact seen from two ends: that we have been handed something enormous and half-broken and world-changing, and we barely understand it, and it barely remembers us, and it is, measured flatly with the straightest face I own, the best time in the entire history of the species to sit down and build a thing.
So I’ll close the laptop tonight. And the tide will come in and take everything. And tomorrow morning a golden retriever who has never seen a human before will greet me like his oldest friend and ask me to tell him a little about my project.
And I’ll tell him. God help me, I’ll tell him again.
I’ll do it all again tomorrow. That’s the joke.
It isn’t, though.
Thanks, Peter. Sorry about the intern.