Spec Before Code
Have it write what it's going to build, then have it write code.
Ask for code directly and you'll read four hundred lines before realizing it misunderstood. Ask for a one-page spec first and the same error shows up in twenty lines in thirty seconds.
What you'll run into:
- The code runs, but nested replies, pagination, and edit permissions — it decided all of those for you
- By round three, it forgets round one's conventions and you restate the requirement
- When something's wrong, the only move is pointing at spots one by one, and the same issues recur
Before letting the AI write code, have it state in plain language what it intends to build: data structures, screen states, edge-case handling, and where it's unsure. You read that page, change a few lines, then let it proceed.
This looks like an extra step, but it saves the most expensive one. The AI writing code costs you almost no time, but reading the code, discovering it misunderstood, then describing how to fix it — these three things all drain your attention, and they scale linearly with code volume. A spec is twenty lines you can scan in thirty seconds; catching an error there costs almost nothing. A software requirements specification exists precisely to align on requirements before building; here you compress it to one screen so the same thing happens inside a single conversation. srs
More importantly, the spec forces out questions you haven't thought through. "Build a comment section" hides seven or eight decisions — threaded replies, editability, soft vs. hard delete, whether logged-out users can see it. If you don't say, the AI decides, and it usually picks the most common convention, not necessarily yours.
The four parts of a spec
- Data. Which entities, key fields, and relationships — get this wrong and everything downstream is wrong.
- States. What the screen can look like and under what conditions. At minimum: normal, empty, loading, error.
- Edge cases. Extra-long content, zero records, concurrent edits, missing permissions, network failure — list as many as you can.
- Open questions. Everything the AI would have to guess, listed for you to answer; this part decides whether you redo work.
The last part is where it admits what it can't — without it, a spec quietly hands away every decision.
Design considerations
- Say explicitly not to write code yet, or it will finish anyway. The model defaults to something complete and runnable; without this line you get a spec plus four hundred lines of code, which defeats the purpose. Put it at both the start and the end.
- Ask it to list anything it's unsure about. This is the most valuable part of the pattern. It exposes the holes in your requirement; unfilled, the model quietly guesses and buries the answer in code — usually caught only at test time.
- Keep the spec within one screen. Past that, you stop reading carefully and the step is wasted; a too-long spec usually means the task is too big — split it (see One Thing at a Time). Twenty to thirty lines is comfortable.
- Keep the agreed spec in context, not just in your head. Write it into a markdown file and bring it along every time you ask for changes; otherwise by round three it forgets round one's conventions and you re-explain everything.
- Change the spec, not the code. When output is wrong, add the missing line to the spec rather than saying "change this to that." The former fixes the whole class of issue you haven't noticed; the latter fixes one spot.
- Write what and why, not how. Naming a library or a function split over-constrains the AI and makes it abandon what it already knows. You judge; it implements; clear boundaries save both sides work.
A note for the AI
You can fix this as the opening line every time you start a new module.
PROMPT · first step
I want to build: [one-sentence feature description]
Do not write any code yet. First give me a spec of no more than
30 lines with four parts:
1. Data: which entities, key fields, and relationships.
2. States: what this screen can look like and under what
conditions. At minimum cover normal, empty, loading, error.
3. Edge cases: the exceptions you can think of and how you plan
to handle them (extra-long content, zero records, missing
permissions, concurrent edits, network failure).
4. Open questions: anything I haven't specified and you'd have
to guess. List them and ask me; do not decide for me.
Write in English, list form, no elaboration. Write code only
after I confirm.
After you confirm, the second line:
PROMPT · after confirmation
The spec is finalized with these changes:
- [your change 1]
- [your change 2]
- Answers to open questions: [answer each one]
Write the finalized spec to docs/specs/[module].md, then
implement according to it. For any future change I request on
this module, update that spec file first.
Real examples
docs/specs/comments.md
## Data
Comment { id, postId, parentId?, body, author, createdAt }
Threaded replies go at most two levels; parentId can only point
to a top-level comment
## States
Normal / Empty (invite the first one) / Loading (3 skeletons) / Error (retry)
## Edge cases
Body longer than 500 chars folds; a failed submit keeps the
draft in localStorage
Save the finalized spec as a project file and bring it along on every round of changes. Weeks later, it's the one thing you can still read when you come back.
Open questions (listed by the AI)
- Can logged-out users see comments, or is login required?
- Can authors edit their own comments? With a time limit?
- Is delete a soft delete (showing "this comment was deleted") or does it vanish?
- Do we need likes or reports?
The "open questions" part is the core payoff. Any one of those four guessed wrong means starting over; answering before code costs five seconds each. It's also the foundation for the other collaboration patterns — three-part prompts and distilling constraints.
