Definition of Done - Spec-First Build

What this is: the bar your work has to clear to count as done - not “it runs on my machine”, but specified, contracted, tested, reviewed, and signed. Every item cites the real corporate-standards ID it comes from, so this sheet is three things at once: a gate during the session, a grading sheet for facilitators, and a takeaway you keep for Monday.

It is the practical form of The 5 Ways We Work With AI. Print one per person.

How to read it:

  • MUST items gate the merge. Miss one and the work is not done - it cannot pass Gate 2 and cannot be scored as shipped.
  • SHOULD items are quality points: they raise your score and they’re what “good” looks like.
  • The arc this enforces: spec → contract → code → six-layer tests → human review. Tick top to bottom.
MUSTgates mergenon-negotiable
SHOULDearns pointswhat “good” looks like

Contract - the machine-readable agreement

ItemLevelCite
The endpoint has a machine-readable OpenAPI definition (the contract is a file, not a conversation).MUSTREQ-API-2
The contract is kept in sync with the implementation - the response the code returns matches the schema exactly.MUSTREQ-API-2
The /recommend 200 response is a real $ref to a defined schema (RecommendResponse), not a TODO, and was frozen at Gate 1.MUSTREQ-API-2, REQ-API-5
Errors use the shared error envelope (RFC 7807 Problem / problem+json), not ad-hoc shapes.MUSTREQ-API-5
Explicit versioning is present and governed (info.version; version belongs in the path for a real service).MUSTREQ-API-4
Schemas are reused, not copied - Lesson / DimensionScore are $ref-ed, consistent conventions throughout.SHOULDREQ-API-5
The API is treated as a product - named, summarised, with examples a consumer could build against.SHOULDREQ-API-1, REQ-API-3

Spec - describe before you generate

ItemLevelCite
Acceptance criteria written before any feature code (defects prevented at inception, not caught after).MUSTQUAL-PRINC-SHIFT-LEFT
An ADR captures the decision and, crucially, the why - the trade-off, not just the choice.MUSTENG-PRIN-DOC-STMT
The ADR includes idempotency reasoning: why GET is safe/idempotent here, and what would change (an Idempotency-Key) if it became a write.MUSTREQ-API-6
The solution is the simplest thing that meets the contract - no speculative abstractions (KISS / YAGNI).SHOULDENG-PRIN-SIMPLE-STMT
The decision is durable - the ADR will outlive the chat it was made in, and lives where the team can find it.SHOULDENG-PRIN-DOC-STMT

Implementation - small steps, on trunk

ItemLevelCite
The endpoint fulfils the frozen contract - it actually returns the agreed shape for the happy path.MUSTREQ-API-2
Work landed as small, reviewable commits, not one mega-change.MUSTENG-PRIN-INCR-STMT
The first commit was stub + a failing contract test (red), then the implementation drove it green.MUSTENG-PRIN-INCR-STMT, QTEST-CONTRACT
Code is clean and self-explanatory - readable names, no dead code, no commented-out experiments.SHOULDENG-PRIN-CLEAN-STMT
Branch was short-lived and integrated to trunk frequently (no long-running fork).SHOULDENG-PRIN-TRUNK-STMT
It builds and the suite passes locally before push - green on your machine first.SHOULDENG-PRIN-LOCAL-STMT, ENG-PRIN-CI-STMT

Tests - test at the lowest viable layer, no duplication

ItemLevelCite
A contract test asserts the response matches the OpenAPI schema.MUSTREQ-API-7, QTEST-CONTRACT
Each behaviour is tested at the lowest viable layer - pure logic as a unit test, not pushed up to E2E.MUSTQTEST-EARLY, QUAL-PRINC-AUTOMATION
No duplicated coverage - the same rule isn’t asserted at three layers; each layer earns its place.MUSTQTEST-NO-DUP, QUAL-PRINC-WASTE
The pyramid is right-shaped: many unit, some component/contract, few system/E2E.SHOULDQTEST-UNIT, QTEST-COMPONENT, QTEST-SYSTEM, QTEST-E2E
Quality was shifted left (fast tests catch it early) and shifted right is considered (what you’d monitor in prod).SHOULDQUAL-PRINC-SHIFT-LEFT, QUAL-PRINC-SHIFT-RIGHT
Any remaining manual checks are deliberate, named, and minimal - not the default.SHOULDQTEST-MANUAL

UX - every state has a design

ItemLevelCite
The UI handles the core states: loading, empty, error, and populated.MUSTQUAL-PRINC-SDLC
The error state consumes the contract’s error envelope - the UI reads Problem, it doesn’t invent its own.SHOULDREQ-API-5
Edge / boundary states are designed (e.g. user with N/A dimensions, fewer than 5 recommendations).SHOULDQUAL-PRINC-SDLC

Review - a human always signs the work

ItemLevelCite
Approved by a named non-author human, reviewed against this DoD. AI may assist the review; AI may not approve. No self-merge.MUSTENG-PRIN-REVIEW-STMT
An owner is named - You Build It, You Own It - accountable for what shipped.MUSTENG-PRIN-OWN-STMT
The merge respects the team’s Definition of Done as the shared SDLC bar (this sheet).MUSTQUAL-PRINC-SDLC
Cross-role handoff is real and visible: the build used Product’s criteria, Architecture’s ADR, QA’s tests - quality is a team property, not one person’s.SHOULDQUAL-PRINC-TEAM
If a criterion changed mid-build, the contract and its test were updated before merge (no stale spec).MUST (if triggered)REQ-API-2, REQ-API-7

The merge bar, in one sentence

A change is done when its contract is machine-readable and in sync (REQ-API-2), its behaviour is proven by a contract test at the lowest viable layer (REQ-API-7, QTEST-EARLY), its decision and the why are in an ADR (ENG-PRIN-DOC-STMT), and a named non-author human has signed it off against this list (ENG-PRIN-REVIEW-STMT). Anything less runs, but it isn’t done.

Part of Innovation Day. The five ways: ways-of-working.md. How the gates run: facilitator-guide.md. How it’s scored: scoring-rubric.md.

Downloads for this session

Grab the templates and sample files used here.