When do you actually need a spec, not just a prompt?
Someone asked me last week when I actually bother writing a spec, because from the outside most of what I do looks like talking to a model until the code works. Fair question. The answer is a line I keep reaching for: I vibe-code anything I would be happy to throw away, and I spec anything I will need to trust later. The size of the task has nothing to do with it. The tell is whether I would ship the result without reading every line, and mean it.
So the plain answer to when you need a spec instead of a prompt: the moment the output has to be trusted by someone who was not there when it was written, and that includes you next month. A prompt gets you code. A spec gets you code plus the two things that let you check it without rereading all of it: the intent you wrote down first, and the gate that fails when the code drifts from it. That second half is the entire difference between output you generated and output you can stand behind.
This has been on my mind because the ground keeps moving. Another capable model landed this week, and another the week before, and the tool defaults shift under everyone every few days. If your process lives inside a single model or a single chat session, every one of those releases is a small earthquake. If your process lives in files, the release is a Tuesday.
when do you actually need a spec, not just a prompt?
Run the throwaway test. If the honest answer to "would I be fine deleting this and regenerating it from scratch" is yes, prompt away. A one-off script, a chart I will look at once, a layout I am sketching to see if I like it. Speed is the whole point and a spec is just friction. Vibe-coding earns its name here, and I do a lot of it.
The test flips the instant something has to hold. Anything that ships, anything another person depends on, anything that touches money or data or a promise I made, anything I will have to modify in six months when I have forgotten how it works. For those, "regenerate from scratch" is not a recovery plan, it is the disaster. The spec is what makes the thing survivable: it is the memory of why the code is shaped the way it is, sitting outside the model that happened to write it. The line I use for this is spec the invariants, vibe the rest.
how do you trust code you didn't write?
You don't, and that is the correct instinct. You trust the gate, not the code. This is the part vibe coders skip, because talking to a model feels like collaborating, and it is easy to slide from "it sounds right" to "it is right." Those are different claims. A model proposes. Only a measurement disposes.
Concretely, trust means three checks the code has to survive before I believe it, and none of them are me reading it and nodding. Does it match the shape the spec declared (structure). Does it actually do the thing, tested against real inputs and not vibes (function). Does it hold under the conditions it will meet in production, not just the ones in the demo (load). If it fails any of those, it does not matter how confident the prose around it was. The gate is the part that does not get tired, does not rubber-stamp, and does not care which model wrote what it is checking. A structure-only glance that greps for the right words is not this. Surface checks propose. Only the semantic measurement disposes.
the part that survives when the model changes
Here is the payoff, and it is why the file-based version wins over the long run. I built this site in sequenced legs: scaffold, then the design system, then one scene at a time, then the API surface. Every leg ran the same template. Capture the spec, generate against it, run the gate before the work counts as done. Same shape, leg after leg.
Somewhere in the middle of that, the model I started on was not the model I finished on, and the chat session that drafted the early legs was long dead by the late ones. It did not matter. The spec from leg two was still on disk when I got to leg nine, and the gate caught, on a late leg, exactly the class of mistake it was written to catch early, in code a fresh session wrote with zero memory of the decisions three legs back. That is the whole trick, and it has a name I keep coming back to: the spec and the gate outlive the session. The template lives in files, so it travels across every model swap and every context reset without losing a thing.
That is also the literal answer to trusting code you did not write, because I did not remember every constraint by leg nine. The spec remembered. The gate enforced it. I got to trust output whose reasons I had personally forgotten, because the reasons were written down where a machine could check them.
Contrast the version where the process lives in your head and the current session. Every new model is a re-litigation. You re-explain the constraints, hope the new one internalizes them, and find out in production which ones it dropped. You are not orchestrating, you are re-onboarding a stranger every week. The people who feel whiplash from the model churn are usually keeping their process in the one place the churn destroys.
I learned the cost of skipping this the unglamorous way, on a pipeline that committed to the wrong branch and shipped to nowhere. The fix there was never a smarter step, it was codifying the check as a written invariant every stage runs, instead of a thing I remembered to do. Same lesson from the other side. What you write down survives you. What you keep in the session dies with it.
so, spec or prompt?
Ask one question: if this breaks, or the model behind it changes, do I want to re-derive it or reread it. Re-derive, prompt it, move fast, enjoy the speed. Reread, spec it, because a spec is just the reread written ahead of time, for a version of you or a model that has no memory of today. The spec is the memory and the gate is the trust, and both of them keep working on a Tuesday when the whole model landscape shifted over the weekend.
If you are formalizing your own methodology after the messy phase and want to compare notes on what actually holds at production scale, work with VibeKoded.
questions that keep coming up
Isn't writing a spec just slower prompting? Only if you spec the throwaway stuff, which you should not. The spec pays for itself the first time something breaks and you read the intent instead of reverse-engineering it from code a model wrote in a session that no longer exists. On anything you will maintain, the spec is faster on the second day and every day after.
Do I need a heavy process for a solo project? No. The lightweight version is three lines before you generate: what this does, what must stay true, how I will know it works. That is a spec. The gate can be a single test that runs the real path. Weight should match stakes, but the shape stays the same whether it is a weekend build or a production system: intent, invariant, check.
A new model just dropped that is better at everything. Doesn't that make the spec obsolete? Backwards. A better model writes better code faster, which means it can drift from your intent faster too, in more convincing prose. The spec and the gate are what let you adopt the new model the day it lands without re-testing your whole worldview. The better the models get, the more the durable, checkable artifact is the thing worth owning.
The model you are using will be old news in a month. The spec you wrote and the gate that guards it will still be doing their job. Build the part that lasts.
// part of the spec-first methodology topic
// grab the free starter kit that makes your AI stop forgetting and stop guessing: get it →
// building with AI? the field manual has the structured lessons.
// hitting this on a real build? this is what I fix →