The complete specification checklist
A spec is the contract you didn't sign. The clauses missing from it are the change orders you'll pay for later.
What a spec is actually for
A specification is the document you and your vendor will reach for when you disagree. Its job is not to look impressive. Its job is to be specific enough that "done" has a single meaning, and that the person paying and the person building agree on what they signed.
The most expensive spec failure is omission. The page about "responsive design" is fine until you find out it means three breakpoints, not actually fluid. The page about "search" is fine until you discover it returns 50 hardcoded results, not the catalogue. The change order to fix each gap is more expensive than putting the line in the spec to begin with.
In-scope checklist
Every section here should appear in every spec, with a one-line answer. "Standard" is not an answer.
Functional
- User stories with acceptance criteria, not just feature names.
- User roles and permissions, with what each role can and cannot do.
- All entry points: web, mobile web, native app, embedded, API.
- All entry languages and content locales.
- All states for every screen: empty, loading, error, partial, success.
Non-functional (where the cost hides)
- Performance budget. LCP, INP, total JS payload, image policy. Per route if it matters.
- Accessibility. WCAG level (AA is the floor in the EU), keyboard support, screen reader testing.
- Browser and device support. The actual list, with a cutoff date for OS versions.
- Responsive scope. Min/max viewport, supported orientations, foldables and split-screen.
- Internationalization. Number, date, currency formats; right-to-left if relevant.
- Security baseline. Auth flow, session length, rate limits, secret management, GDPR scope.
- SLAs. Uptime target, response time target, MTTR target.
Integrations
- Each external system, with the version of the API in scope.
- What we do when each integration is down or rate-limited.
- Who owns the credentials and the rotation plan.
- Webhook reliability assumptions (at-least-once, ordering, idempotency).
Operational
- Deployment topology and environments (preview, staging, production).
- Observability: logs, metrics, traces, alerts, ownership.
- Backup, retention, and disaster-recovery RPO/RTO targets.
- Secrets and config management: where, who, rotation.
Out-of-scope, in writing
A spec without an explicit out-of-scope section is a spec that will absorb every late request as a fight. Be generous with this section. "Customer support tooling, admin dashboards beyond X, dark mode, in-product analytics dashboard, native mobile app — not in this engagement" is a paragraph that prevents a year of arguments.
The line item you didn't write down is the line item you'll pay for as a change order.
Acceptance criteria, every story
Every user story needs acceptance criteria written in the form: "given X, when Y, then Z." That format makes the story testable. Without it, "done" becomes a negotiation between the person paying and the person who wants to be paid.
If you can't write the acceptance criteria, you don't know the story well enough to estimate it. That is a research task, with its own estimate and its own deliverable, before any code is written.
Change process, in the spec itself
The spec should describe how it gets changed. Who can request a change. Who estimates it. Who approves it. What happens to the timeline and budget. Without this section, every change becomes a fresh meeting and a fresh negotiation.
- Requested in writing, not in a hallway.
- Estimated within X working days.
- Approved by a named role, not the whole stakeholder list.
- Timeline impact and budget impact stated explicitly, not absorbed.
Want this kind of judgment on your project?
I read every email within one working day. Bring a project, a quote, or a system you're stuck on.
The hidden costs of software projects
Beyond the initial quote: maintenance, hosting, scaling, and the true total cost of ownership.
15 things every Contentful enterprise project gets wrong in the first 6 weeks
The 15 production gaps every enterprise Contentful + Next.js build hits in the first six weeks — and how to close each one without burning a sprint. A pre-kickoff checklist for technical leads on a Contentful enterprise starter.
REST + GraphQL hybrids for multi-locale CMS-driven sites
Why neither REST-only nor GraphQL-only is the right call for an enterprise multi-locale CMS site, and how to split by concern instead. Includes the circular-reference problem on full REST payloads, the bundle cost of GraphQL on the client, the decision matrix per call site, the unified fetcher, granular cache tags, the block-as-fragment pattern, locale fallback in one round trip, Live Preview survival, Server Actions for CMA writes, the Algolia Sync API exception, and the migration sequence.