Build06 Standards & CI/CD · 3 of 3
Definition of done
A definition of done is only useful if a reviewer can check every line of it in under a minute without asking the author anything.
Stand 29.07.2026
#A definition of done that bites
WhatDefinition of done for a warehouse pull request
The usual version — code reviewed, tests written, documentation updated — cannot be checked, so it is never enforced, so it is decoration. Each row below names the artefact and where the reviewer looks for it.
| Done means | Reviewer checks |
|---|---|
| Grain is declared | the table COMMENT contains a 'one row per …' sentence, in the DDL in this diff |
| The transform is importable | a test imports it directly, with no pipeline and no table; no dbutils, spark or widget read appears at module level anywhere outside an entry/ notebook |
| Business rules are asserted, not described | each rule touched by the diff maps to an EXPECTATIONS entry or a .sql assertion returning zero rows |
| Behaviour-neutral changes are proven neutral | a symmetric EXCEPT ALL result is linked in the pull request |
| The bundle still validates | bundle validate -o json is green for every target including prod, run with the same --var values the release uses — not only test |
| No literals that vary by environment | grep the diff for dwh_dev / dwh_prod; the catalog arrives as a variable |
| Identifiers pass the rule | ^[a-z][a-z0-9_]*$ — the CI identifier step is green for object names; new COLUMN names are read by eye, because the grep does not cover them and no new identifier in the diff needs backticks |
| Ownership is real | the object is owned by a group; no individual appears as owner in the DDL |
| The re-run question is answered | the runbook says whether this job is safe to re-run blind, updated here if the answer changed |
| PII is classified | any new column carrying personal data has its governed tag applied in the DDL, not clicked in the UI |
Ten rows. Each is binary, each is visible in the diff or in the build, and none of them requires the reviewer to trust the author. That is the whole design goal.
Why
An unenforceable definition of done fails in a specific and expensive way: the first three sprints look fine, then the first person leaves and it turns out nothing was written down. The grain lived in someone's head, the re-run question was answered in a chat thread, and the tags were clicked in the UI by a contractor whose access has since been revoked.
It also decides whether handover is possible. Every row above is something the team must be able to check without you in the room. A row that only works when the consultant reviews it is not a standard — it is a dependency.
Doing it
- Put the ten rows in the pull-request templateThe reviewer then reads them at the moment they matter.
- Automate every row that can be automated — identifiers, environment literals, bundle validateLeave the rest as explicit reviewer questions.
- Add a row only when a real defect escaped that it would have caughtName that defect in the commit message.
- Delete a row that has never once failed, and timebox reviewIf checking the list takes more than five minutes, the pull request is too big and that is the finding.
Defaults
- Ten rows or fewer, each binary, each visible in a diff or a build
- Anything automatable is automated; the manual rows are the ones needing judgement
- The list lives in the pull-request template in the repository, versioned like code
- Rows are added in response to escaped defects and removed when they stop firing
Gotchas
- Rows that cannot be checked — 'code is clean', 'documentation updated'They train reviewers to tick boxes without looking, which devalues the rows that do matter.
- A twenty-row listReview becomes a chore, people tick everything, and the list now provides false assurance rather than none.
- Enforcing it only on the consultant's pull requestsThe standard has to bind everyone from week one or it reads as an outsider's rule and dies at handover.
- No written exception pathThere will be an emergency fix; without one carrying an expiry date, the emergency becomes the precedent.