Skip to content

Architecture ​

Use a restricted workflow DSL in Dart. A workflow function may use normal control flow, but every durable boundary goes through WorkflowContext:

  • perform for I/O and side effects;
  • request for assigned work;
  • waitForEvent for external events;
  • sleep for durable time;
  • a stable operation id on every await.

Direct I/O, wall-clock reads, randomness, mutable globals, and unregistered futures are forbidden in orchestration code.

WorkflowRuntime is the canonical runtime.

Component Split ​

ComponentOwnsMust not own
SchemaReusable structural shape, typed encoder/decoder, validation, examples, sensitivityWorkflow orchestration
Workflow definitionImmutable identity and input/output/failure schemasExecutable orchestration
Workflow handlerDeterministic orchestration and await IDsI/O, clocks, randomness
Decider / runtimeReplay, commands, retries, statusBusiness side effects or SQL
Operation workerVersioned handlers, heartbeats, idempotencyWorkflow control-flow state
Work APIAudience, claim, response, validation, expiryA long-lived process
Storage interfaceAtomic run/history/command transitionsSupabase-specific SQL
Postgres adapterTransactions, row locks, SKIP LOCKED, fencingWorkflow-domain branching
Timer / recoveryTimers, expiry, expired leases, interrupted decisionsArbitrary business code
DesignerConstrained document and visualizationRuntime state

API, decider, worker, and recovery roles can be separate processes or one WorkflowServerApplication. Correctness comes from storage contracts, not from which replica handled the last request.

Progress Model ​

  • history.sequence is the ordered audit trail.
  • runs.revision fences concurrent decisions.
  • commands are pending, claimed, completed, failed, or cancelled.
  • operationKey identifies a logical await across replay.
  • claimGeneration fences stale workers after lease reaudience.

blocked is healthy. It means the run is waiting for durable external work.

Definition Digest ​

A run stores code, version, and digest. Workers reject a digest mismatch instead of replaying history against changed logic. Changing behavior requires a new version.

Visualization ​

Arbitrary Dart cannot be converted into a complete graph. Attach an optional WorkflowDocument when you need a pre-run inspector map. Without it, the inspector builds an observed operation map from history as the run executes.

See Also ​