Atomic Vibe Coding
There’s no good vibe coding. Or is there?
The usual explanation is that coding agents derail because models aren’t there yet. Twitter keeps prescribing waiting for the next model, bigger context, better tool use, new protocols. It really is a comfortable story because it makes it someone else’s problem.
What broke it for me is that the same model on the same repo on the same afternoon nailed a task phrased one way and produced AI Slop when I phrased it otherwise. And this should not be a new thing for any of you reading this. What’s new is what is going to follow.
In b/w those runs what changed was only my sentence(s). So I realised the bottleneck isn’t capability but It is the handoff.
We do carry a lot of intention and unspoken structure in our head. Template of the design doc, some personal preferences, some over time acquired habits of typing git command. What “clean” means in this particular repo, the three edge cases we would actually be annoyed about, the two files we absolutely don’t want to get touched. But then we squeeze all this in a 11 worded prompt and hit Enter.
11 words go in and four hundred decisions come out. To make up for the lost words we were supposed to say, something has to invent the difference, and it is the coding agent.
Picture a contractor who has read every renovation magazine ever printed and has never set foot in your house. You tell him to redo the kitche and he redoes a kitchen. Open shelving, subway tile, a pot filler that you didn’t even ask for. It’s competent and it’s on budget & and it is the statistical average of every kitchen on the internet. This means it is nobody’s kitchen in particular.
There’s research on this and this has a grim name: detrimental semantic collapse. The model locks onto one coherent reading of an ambiguous task. It generates internally consistent code that’s confidently misaligned with what you wanted.
The Atom
The actual argument in Atomic Habits isn’t “set smaller goals” but that the unit of change is the rep and not the resolution. Same idea applies with atomic vibe coding too. The feature is the goal. It was never the unit.
An atom is the smallest piece of work where you can define & convey the intent of in ~1 sentence and check the result in one go.
Both halves matter. If you can’t say it in a sentence, the model will invent the rest of the sentence for you. If you can’t check it with a command, you won’t find out that it did.
Seven Habits
1. If the prompt has an “and” in it, it’s two atoms. “Add the endpoint and wire up the UI and write tests” is three coin flips you’re resolving at once. Splitting it costs twenty seconds and saves you the ninety-minute unwind.
2. Name only the decisions you’d be annoyed to get wrong. Not a spec. Two or three constraints. Usually a file path, a library, and the one behaviour you care about. Anything you don’t name gets filled in with the median, and anything you over-name is context rot you paid for yourself, so this is a real trade and not a “more detail is better” situation.
3. Point instead of describing. “Follow the pattern in useCart.ts“ beats four sentences describing that pattern, because your codebase is a far better spec than your prompt and it’s already sitting in the context window.
4. Make it write the plan, and edit the plan yourself. Editing a plan is cheap. Reviewing a diff is not. Plan mode isn’t ceremony, it just moves the argument to the point where it costs three lines instead of three hundred. This is also the whole premise behind spec-driven toolkits like GitHub’s Spec Kit: specify, plan, break into small testable tasks, then implement.
5. End every atom on a command that can fail. pytest tests/cart_test.py. curl localhost:3000/api/feed | jq.
Load the page.
“Looks good” is a feeling, not a check.
6. Commit per atom. Not for the history, for the blast radius. A cheap undo is what lets you be genuinely reckless inside the atom, which is the fun part and the actual vibe part. Vibes are great when rollback is one command.
7. Kill it, don’t nurse it. When a run derails, don’t patch inside the same thread. The context that produced the wrong answer is now actively arguing for the wrong answer, and you’ll spend an hour negotiating with it. Clear the thread, rewrite the sentence using whatever you just learned, run it again. Ninety seconds.
What This Isn’t
I’m not telling you to write a PRD before every function. Nobody has ever shipped faster by producing documents, and if your version of this takes twenty minutes you’ve reinvented waterfall and I want no part of it.
An atom is a sentence and a check. Call it twenty seconds.
It is a real trade, though. Decomposed workflows measure slower per pass than one-shotting it. You’re giving up peak throughput in exchange for actually finishing.
Which, if you’re honest, is a trade you’re already making. Just badly, when the one-shot lands at 30% and you spend the rest of the afternoon on rework you don’t count as work.
Worth remembering too that Karpathy’s original vibe coding line, “fully give in to the vibes, forget that the code even exists,” was about throwaway weekend projects. It was never a production methodology. It got promoted into one by people who read the tweet and skipped the caveat. Vibe away on the weekend toy. The atoms are for the thing with users.
The uncomfortable version of this is that agent output quality is now mostly a function of how precisely you can think, which is a much less flattering bottleneck than waiting on the next model.
You can outsource nearly everything downstream of intent. The typing, the boilerplate, the API you’ve never read, the tests you were planning to skip. But the sentence describing what you actually want has to come from you, because it’s the one thing in the pipeline that doesn’t exist anywhere in the training data.
Good news is it’s a skill and skills respond to reps. The agent isn’t guessing because it’s stupid. It’s guessing because you left a blank and it filled it with the entire internet’s idea of what you probably meant.
Vibe coding was never the problem. It just never had a unit.
TL/DR
Atomic vibe coding is simple.
Just give the agent one thing at a time, where “one thing” means “one result you can name” and one check that can fail. The reason isn’t that models are weak.
It’s that anything you leave unsaid, the model fills in with the most common answer from everything it has ever read, and that answer is rarely the one your codebase needs.
A big vague task hides dozens of those unsaid decisions and getting most of them right still leaves you with the whole thing wrong. So you shrink the ask until there’s nothing left to guess about, check the result before moving on, and commit.
You still vibe. You just do it one decision at a time.




