The workflow is a value you can inspect — steps, dependencies and schemas are all
readable before anything runs. Temporal, Inngest and Trigger.dev take the opposite
approach: you write a function, and the graph exists only as the trace of what it did.
Typed end to end
Zod schemas per step. A step’s dependency outputs arrive typed, and a mismatch is a
validation failure at runtime rather than a surprise three steps later.
Your Postgres, nothing else
The store is Postgres and the queue (pg-boss) is
Postgres too. Nothing else to operate. import 'octaflow' pulls in neither
pg, pg-boss, nor the AI SDK — they are optional peers.
The whole durable toolkit
Auto-parallelism, retry and timeout, durable sleep, concurrency caps and rate limits,
dynamic fan-out, signals, sub-workflows and saga compensation — every transition
persisted, so a restart picks up where it left off.
A pipeline exercising most of the engine: fan-out over two map steps at once, a
concurrency cap, a retried step, a sub-workflow, a suspend-and-resume on an external
event, a durable sleep — then a second workflow failing and rolling back in reverse.
Every line is an engine transition emitted through the
FlowObserver seam — not a console.log in a handler.