Skip to content

Definition of done

Status: Accepted

What “finished” means before a PR opens. The single checklist a change is held to, gathering the obligations scattered across this section into one place.


Production-ready always. Shipped code is finished — no deferral notes, no “come back to this”, no TODO (comment policy). If work remains, the work is not done, and the PR is not ready.

This is not a high bar arbitrarily set. A codebase where “done” means “mostly done” accumulates a second, invisible backlog inside the code itself, and that backlog is never paid down because it isn’t visible.

A change is done when all of these hold:

  • Cites a spec identifier that exists on the spec’s main (GOV-R2, GOV-R3)
  • If it changed behaviour, the spec PR merged first (GOV-R4)
  • Citation is in a commit trailer and the PR body (GOV-R5)
  • No requirement ID appears in any code comment (GOV-R6)
  • The cited requirements are actually satisfied — not approximately
  • New behaviour has tests; the must-cover paths are covered
  • Coverage on applicable code is 100% — the gate is green, and any exclusion is annotated in the source, not a silent gap (Q-R61, Q-R62)
  • Every new user-facing error carries a remedy (Q-R16 — it won’t compile otherwise)
  • No unwrap/expect/panic in non-test code (Q-R12)
  • rustfmt, strict clippy, arch tests, unit, golden, integration all pass (Q-R30)
  • No lint suppression added to src/ (Q-R13)
  • cargo-deny clean; no new advisory or disallowed licence (Q-R32)
  • No secret in any tracked file, tests included (Q-R33)
  • Public items documented (Q-R20)
  • Comments obey the policy — why not what, 2–4 line blocks, no IDs
  • Repo-specific how is in .docs/, linked from code, not inline (Q-R10)
  • Interactive additions have a non-interactive equivalent (F1-R6)
  • User-facing output obeys the error model and accessibility
  • Platform-conditional code goes through the platform component, not scattered cfg! (ARCH-R35)

Stated so they can’t be smuggled in as done:

Not done Why
“Works on my machine, untested elsewhere” The platform matrix is a promise; a change that only works on one is unfinished
“Passing but with a suppressed lint” The suppression is the unfinished part (Q-R13)
“Feature works, error path panics” A panic is an unhandled error with no remedy (Q-R12, G4)
“Spec change to follow” That’s drift with a promise attached — the exact thing governance prevents
“TODO for the edge case” Shipped code is finished; handle it or scope it out explicitly

The checklist is the author’s; the reviewer verifies it, and answers two questions CI cannot:

  1. Does the code actually satisfy the cited requirement? CI confirms the citation resolves; only a human confirms the behaviour matches it.
  2. Is anything here a judgment-rule violation? Redundant comments, premature abstraction, a runtime check where a type would do — none are machine-detectable, all are review-blocking.

A review that only re-runs what CI already ran adds nothing. The value is in the two questions above.

A spec change is done when:

  • Every new requirement has a permanent, unique ID (GOV-R8)
  • Every cited identifier resolves (spec-side CI)
  • A requirement-altering change names the affected repos (GOV-R7)
  • Every internal link resolves
  • The doc carries a status (Draft / Accepted / Superseded)
ID Requirement
Q-R47 A change MUST satisfy every item on the done checklist before its PR is marked ready.
Q-R48 “Done” MUST NOT include deferred work, suppressed lints, panicking paths, or promised follow-up spec changes.
Q-R49 Review MUST verify that code satisfies the cited requirement, beyond CI confirming the citation resolves.
Q-R50 A spec change MUST satisfy the spec definition of done before merge.

This page lives in another repository Rendered from lemonfiber/spec at 1d10402, 2026-09-09. Read the source of this page