Why a State Machine?

Think of a state machine as a subway map:

  • Stations are states — the discrete places the system can be (Cart, Placed, Shipped).

  • Turnstiles between stations are events — you cannot teleport from any station to any other; you may only take the connections the map allows.

  • A transition is one ride through one turnstile: it either works (you arrive at the next station), or it is not allowed (you pushed a turnstile that does not exist here), or there is no such station on this map at all.

Modelling a workflow this way — instead of a tangle of if/else and callbacks — buys you three things that matter at scale.

Illegal transitions are rejected by construction, not discovered at runtime. The map is the contract: if an edge isn’t drawn, the move can’t happen.

2. Failures are types, not nulls or booleans

Every push returns a sealed TransitionValid, Invalid, or NoFromState — so the caller is forced to handle "this can’t happen" rather than silently ignoring it.

3. Durable resume

Because the position is an explicit value, a run that dies mid-flight knows exactly which step it was at and can resume from there. This is the property that makes Hydra a good fit for long-running asynchronous orchestrators.

Hydra is a Mealy machine: the output (the action) emitted on a transition depends on both the current state and the event. That’s what lets a bare event like PaymentSucceeded produce a data-carrying action like ShipParcel(address) — the address comes from the state, not the event. See State, Event & Action.