A prototype exists to answer one question, and only a question that running code can answer: does this state machine shape hold up, does the data model fit, is this library viable, does this UI feel right. Reading the code, the docs, or an ADR answers most design questions — those never earn a prototype. The governing rule is the leitwort: prototype code never graduates. The deliverable is a decision, not code.
The discipline
- State the prototype question first. Before writing a line, write the question the prototype must answer, in one sentence with a decidable outcome: "can the reducer express undo without a history array?" — not "explore the reducer". No question, no prototype.
- Timebox it. Set the box when you state the question (an hour or two is typical; a day is the ceiling). When the box expires, the answer is whatever the evidence says so far — "unresolved, and here is why" is a valid answer.
- Build the cheapest thing that answers the question — and say so out loud. No tests, no error handling, no naming polish: "skipping error handling — this is a prototype and the question is about the state shape." Saying it marks the corners as cut on purpose, so nobody (including you) mistakes them for the standard. Hardcode everything the question doesn't touch.
- Extract the decision. Record the answer plus the decision-rich snippets
— the state machine, reducer, schema, or type shape that encodes the
decision more precisely than prose. These snippets may be pasted into the
PRD: the one exception to
to-spec's no-code-in-the-PRD rule. Trim to the decision-rich parts; the demo scaffolding stays behind. - Throw it away. Delete the branch or directory. Prototype code never
graduates to production — the production version is rebuilt test-first
via
tdd, with the extracted decision as its spec. The rebuild is not wasted work; the prototype bought the certainty that makes the rebuild fast.
Prototype vs tracer bullet
Deliberately different tools — the decision rule for which one a task needs
lives in coding-design-plan, not here:
- A prototype answers "what shape should it be?" — throwaway by contract, quality deliberately absent.
- A tracer bullet answers "does the path work end to end?" — a production-quality vertical slice that is kept and grown.
If you catch yourself wanting to keep it, it was a tracer bullet question — stop, and restart under that discipline instead of promoting junk.
Output contract
Return: question (the one it was built to answer), answer (the decision,
including negative or unresolved results), snippets (the decision-rich
parts, for the PRD), and disposition (discarded — with the deletion done,
not promised).
Gotchas
- Do not let a prototype quietly become the implementation branch — the moment real work lands on it, you are shipping code with quality deliberately absent.
- Do not prototype what reading the code or docs already answers — the prototype question must require running code.
- Record negative results too: "the library can't do X" is exactly the decision the prototype existed to buy, and it saves the next person the same spike.
- Do not polish. Time spent on naming, structure, or edge cases in a prototype is time stolen from the question.