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. gradeddraft 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. submittedgrading triggers nothing. gradinggraded 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 codeenum, 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