Blog
Before the First Line of Code
Zero Lines of Site Code
Let me tally up what I’ve produced for this portfolio so far:
- a constitution — the project’s non-negotiable principles,
- a spec for the first slice — user stories with acceptance criteria,
- a fix to the git binding, so the tooling knows which spec I mean,
- a wireframe — the page structure — and a throwaway visual mock,
- a design system, promoted into the constitution as law, with a token doc.
And the amount of site code I’ve written is: zero. Not one line of the thing a visitor will ever load.
For a small static blog, that should feel ridiculous. Five artifacts and a process, to put up a few pages? Here’s the thing I want to sit with: it does feel like a lot — and that feeling is exactly the trap. The discipline that looks like overkill for a blog is the same discipline whose absence quietly destroys complex systems. The blog is a safe place to practice a habit that becomes non-negotiable at scale.
”Before the First Line” Is the Work
None of those five artifacts is busywork. Each one is a decision, captured cheaply, before it gets expensive to change. Look at what they really are:
- The constitution decides what’s non-negotiable — so nothing downstream quietly violates it.
- The spec decides what “done” means — acceptance criteria written before code, so “finished” is a checklist, not a feeling.
- The branch binding decides which context is active — so the agent operates on the right feature, deterministically.
- The wireframe decides structure — what’s on the page, and in what order.
- The design system decides identity — so the look can’t drift slice to slice.
Notice the verb in every line: decides. “Before the first line of code” isn’t a delay before the real work. It is the work. The code is just the last, most mechanical translation of decisions already made.
Why Before Beats During
There’s an old, boring truth that AI makes urgent again: the cost of changing a decision rises the later you change it. Moving a block in a Markdown wireframe is ten seconds. Moving it after the page is built, styled, and SEO-wired is a rewrite. Renaming a concept in a spec is a find-replace. Renaming it after twelve files depend on it is a migration.
Here’s the part specific to building with AI, and it’s the whole game:
An agent will decide anything you leave undecided — instantly, plausibly, and without telling you. Leave the structure unspecified and it’ll invent a hero and an order for the blocks. Leave the identity unspecified and it’ll pick a font and a color. The output will look deliberate. That’s the danger: plausible-but-not-chosen is indistinguishable from chosen, until you notice it’s not what you wanted — usually after it’s expensive.
So every decision you don’t make up front isn’t skipped. It’s delegated to the agent, silently, at the worst possible moment — mid-generation, with no review.
The Vibe-Coding Mirror
Now run the opposite of everything above. Vibe coding is: open the editor, describe what you want, let the AI produce, react to what comes out, repeat. No constitution, no spec, no wireframe. Just vibes and iteration.
For a weekend toy, that’s genuinely fine — I’ll defend it below. But notice what each missing artifact costs you the moment the thing matters:
- No definition of done → you can’t actually tell if it works. You eyeball it. “Looks done” replaces “meets the criteria,” and the two diverge exactly where bugs live.
- No constitution → the agent drifts. Every session re-decides things, slightly differently, and the inconsistencies accumulate into a codebase with no point of view.
- No structure decided → you rewrite, because the first plausible layout wasn’t the right one and nobody chose.
- No single source of truth → the same fact (a color, a profile field, a route) gets duplicated and then contradicts itself.
- No verification list → you become a reviewer of code you never designed. That’s the worst seat in the house: maximum cognitive load, minimum leverage.
Vibe coding optimizes the one step AI already made cheap — typing — and ignores every step that stayed expensive: deciding, integrating, verifying. It feels fast because the part you can see (code appearing) is fast. The slow part just moved somewhere you can’t see it yet.
Now Imagine It Isn’t a Blog
Here’s where it stops being a cute process story. Everything above, for a static blog, has a blast radius of roughly one page. Get the hero wrong, fix the hero. The system is small and uncoupled; mistakes are local and cheap.
Now picture a real architecture built with AI: several services, a data model, API contracts between them, auth, infrastructure, async jobs. Three things change, and they change multiplicatively:
-
Decisions become coupled. A wrong data model doesn’t poison one file — it poisons every service that reads it. A wrong service boundary metastasizes through every contract that crosses it. In a blog, errors add up. In a coupled system, they multiply.
-
AI multiplies your speed in whatever direction you’re pointed — including wrong. The thing that makes AI miraculous (it produces fast) is neutral about correctness. If the groundwork is thin, you don’t slowly drift toward a mess; you sprint there, generating ten coupled components on the same bad assumption before you notice. Speed without direction just means you arrive at the wrong place sooner, with more of it built.
-
Verification gets harder precisely as it gets more important. A blog you can eyeball. A distributed system you cannot. The only thing that tells you a complex build is correct is criteria you defined up front — exactly the artifact vibe coding skips.
So the scaling is brutal and counterintuitive: the groundwork that feels optional on a blog is what bounds the blast radius on a system. The bigger and more coupled the build, the more of your total value is created before the first line of code.
The Thing People Get Backwards About AI
Here’s the nuance I’d most want you to leave with. The common intuition is: “AI writes the code, so I can be vaguer about what I want.” It’s exactly inverted.
An agent builds faithfully from whatever you hand it — including your ambiguity. Hand it a vague spec and it won’t push back; it’ll confidently build a specific interpretation of your vagueness, and it’ll be wrong in a way that looks finished. The fast, literal producer doesn’t make precision less valuable. It makes precision the binding constraint on the entire output. AI raises the value of specification; it doesn’t lower it.
That reframes “before the first line of code” entirely. It’s not ceremony you do to feel organized. It’s the highest-leverage work there is, because it’s the input that a tireless, literal, lightning-fast machine will faithfully amplify — for better or for worse.
Leverage, Not Ceremony
I want to be honest, because the opposite failure is real too: process for its own sake. Writing a constitution for a script you’ll delete tomorrow is cargo-cult SDD. The artifacts I listed are valuable because they’re reused (across slices), checked (against the build and the criteria), and binding (the agent obeys them). Strip away the reuse and the enforcement and you’re left with paperwork.
So the rule isn’t “always do all of it.” It’s match the groundwork to the blast radius:
- Throwaway script, prototype, weekend toy → vibe away. The cost of being wrong is near zero; the speed is the whole point.
- Anything that other things depend on, that lives longer than a week, or where “wrong” is expensive or coupled → decide before you code. The bigger the dependency graph, the more of the decisions move up front.
The mistake isn’t vibe coding. The mistake is vibe coding where the cost of being wrong is high — and AI, by making the wrong thing as fast to produce as the right thing, makes that mistake much easier to make at speed.
The Role This Leaves You
Do all of this and your job changes shape. You stop being the typist and become the director: you decide, you encode the decisions as artifacts, you verify against criteria. The agent does the producing. Skip all of it and you’re stuck as a frantic reviewer of code you didn’t design — busy, but not in charge.
That’s the quiet argument under this whole series. The groundwork isn’t there to slow the AI down. It’s there to move you up the stack — from the part that got automated to the part that didn’t: judgment, written down where a fast machine can faithfully execute it.
Takeaways
- “Before the first line of code” isn’t delay — it’s the work. Every pre-code artifact is a decision captured while it’s still cheap to change.
- An agent decides anything you leave undecided, instantly and plausibly. Undecided isn’t skipped; it’s silently delegated at the worst moment.
- Vibe coding optimizes the step AI already made cheap (typing) and ignores the ones that stayed expensive (deciding, integrating, verifying). Fine for toys; corrosive for anything that matters.
- It scales terrifyingly: on a blog, errors stay local; in a coupled system they multiply, and AI’s speed multiplies them faster. Groundwork bounds the blast radius.
- AI raises the value of precise specification — it faithfully amplifies exactly the clarity (or ambiguity) you give it.
- Match groundwork to blast radius. The real skill is judgment, encoded as artifacts — which promotes you from typist to director.
This blog is built slice by slice with Spec-Driven Development. Start with “No CMS, No BDD, Just Git,” see the whole system in “How I Built This Portfolio with SDD,” or browse the rest at /blog.