Skip to main content
Unlisted page
This page is unlisted. Search engines will not index it, and only users having a direct link can access it.

ADR-004: Workflow Engine Inline vs Dispatch Step Types

  • Status: Accepted
  • Date: 2026-02-01

Context

The workflow engine supports multiple step types. Some are pure data operations (conditions, transforms, delays) while others require external execution (jobs, sub-workflows). Running all steps through the job dispatch pipeline adds unnecessary latency and complexity for steps that can be resolved locally.

Decision

Split step types into two categories:

Inline Steps (executed synchronously in the engine)

Step TypeBehavior
conditionEvaluate expression, choose branch
delaySchedule timer, mark pending
approvalCreate approval request, wait for human
notifyFire notification event
transformEvaluate template expressions against run context
storageRead/write workflow context paths
switchMulti-branch condition evaluation

These execute within the engine's scan loop — no job dispatch, no worker involvement. Results are written directly to the run's step state in Redis.

Dispatch Steps (require external execution)

Generic step types have no dedicated engine handler — they are dispatched as jobs to worker pools:

Step TypeBehavior
workerSubmit to scheduler for worker dispatch (default job type)
llmDispatch to an LLM worker
httpDispatch an HTTP-call job
containerDispatch a containerized job
scriptDispatch a script-execution job
inputDispatch a job that collects input

These create jobs that execute outside the engine process.

parallel, loop, switch, and subworkflow have dedicated engine handlers (see the inline/handler list above and core/workflow/models.go): they are orchestrated by the engine, which in turn dispatches the underlying worker/generic jobs.

Expression Syntax

Inline steps use ${ expression } template syntax (not {{ }}). The evalTemplates function recursively evaluates expressions against the run's context scope, resolving input.*, steps.<id>.output.*, and context.* references.

Key source files:

  • core/workflow/engine.go — step handler dispatch and inline execution
  • core/workflow/models.goStepType constants
  • docs/workflow-step-types.md — user-facing step type reference

Consequences

Positive:

  • Inline steps complete in microseconds (no network round-trip)
  • Simpler error handling — no job state machine for data transforms
  • Workflow engine can process data-only workflows without scheduler involvement
  • Reduces load on scheduler and NATS for internal operations

Tradeoffs:

  • Engine scan loop must handle inline step failures without blocking
  • Two execution models to understand and debug
  • Inline steps cannot leverage worker pool scaling