Specify before building
Before implementation starts, I write the domain model, the constraints, and a decidable definition of done — the written contract an AI coding agent implements against.Before implementation starts, I write down the domain model, the constraints, and a decidable definition of done. That spec is what an AI coding agent implements against — not a vague prompt, a written contract. Types, lint, and schema validation act as fast oracles that drive the agent's loop as it works, catching mismatches in seconds rather than after the fact. The expensive test suite against real infrastructure runs last, gating the merge once the cheap layers have already caught what they can.The specification work and the verification work are the same effort, done in the right order. What a spec decides up front is what later becomes a type, a lint rule, or a test. Skipping the spec does not skip that work — it just forces it to be rediscovered after the code already exists, when changing course is expensive.This is especially true for properties that cut across every code path rather than one function's inputs and outputs. A requirement like every payment attempt is logged, including failed ones, will not fit in a type signature. Naming it in the spec is what puts it on the list as a runtime check or a standing rule — so it is enforced deliberately, not hoped for.
In practice: before a commerce flow ships, the domain model, the illegal state transitions, and the pass/fail criteria for checkout are written down. An AI coding agent implements against that contract; types, lint, and schema validation drive the loop until the expensive real-infra suite gates the merge.