This split is familiar from Temporal.io: workflows are deterministic while activities are idempotent.