ADR 0001: Declarative step graphs, not code-as-workflow with replay
Status: accepted · 2026-09-02
Context
Temporal, Cadence and SWF’s Flow framework let you write a workflow as an ordinary function and make it durable by recording every result and replaying the function after a restart. It is expressive, and it is the source of most of the operational pain: workflow code must be deterministic, every edit to in-flight workflows needs version markers, and debugging means understanding why a function ran to line 40 without doing anything.
Herd’s model, as far as it is public, is a work item with a current step and a scheduled time, advanced by an engine that never runs tenant code.
Decision
A workflow is data: an ordered list of steps (task, sleep, wait, choice)
with transitions. Handlers are plain HTTP endpoints or pull workers. Branching is
declared (choice with a data-only predicate) or chosen by a handler returning
next from the declared steps. The engine never evaluates user code.
Consequences
- No non-determinism bugs; any language can implement handlers with no SDK.
- Definitions are immutable per version and a run finishes on the version it started on.
- Less expressive: unbounded loops and dynamic fan-out need explicit steps or later features (child runs, map).
- If a tenant needs dozens of dynamic branches, that is the signal to reconsider.