Skip to content

State Machine Design ​

Lifecycle transitions for entities with more than three states. The disallowed transitions — the ones you forget to forbid — are the silent source of half the system's bugs.

Owners: Tech Lead, Developer Phase it lives in: What We Build (Volume III) The corpus principle this enacts: Name every state the person can be in — and every state the entity can be in.

Where it lives in the chain ​

How to do this ​

For any entity with more than three states (draft, submitted, grading, graded, published, revoked…), draw the state machine explicitly:

  • States — every state the entity can be in, named.
  • Transitions — which state can move to which, and what triggers each transition.
  • Disallowed transitions — what is explicitly not allowed, with a reason. graded → draft is forbidden; the system rejects the operation rather than corrupting history.
  • Terminal states — which states are end-of-life. From revoked, no transitions.
  • Side effects — which transitions fire events, send emails, charge cards. submitted → grading triggers nothing. grading → graded publishes ExamGraded and notifies the student.

What good practice looks like ​

The state machine is drawn, not described in prose. Mermaid in the ADR, or a hand-sketched diagram next to the schema. The states are enforced in code — enum, union type, or constraint table — so the type system rejects an Exam in an unknown state.

The state machine is read aloud in the amigos session. "What happens if a teacher submits a grade twice in 500ms?" — leads to a transition the diagram either allows (with idempotency) or forbids (with a clear error). "What happens if a student withdraws from the class mid-grading?" — leads to a withdrawn state and a transition the diagram either has or needs.

A team without a state machine ends up with boolean flags that combine into illegal states (isSubmitted=true, isDraft=true), and the bugs all live where two booleans disagreed. The state machine is what makes those bugs impossible to write, not just impossible to ship.

200apps · How We Work · NWIRE