Core concepts

Decision

The root object. A decision is a human approval requested at a point in a run. It's keyed by the engine's run — engine, externalRunId, stepRef — not by a Flowplane-executed step. It carries the reviewer context, the assignee/approvers, the quorum thresholds, the SLA (timeoutAt), and the verdict. The verdict lives on the decision and nowhere else — it's the single source of truth.

Status flows PENDING → APPROVED | REJECTED | EXPIRED.

Engine

The thing that actually executes your workflow steps. Flowplane supports two modes, declared per workflow via engine:

EngineWho executesWhat Flowplane stores
bundledFlowplane's own durable enginefull run + step ledger
inngest (and future adapters)the external engineonly the decisions — no step rows are seeded

The decision-first model is what makes the external case clean: Flowplane never pretends to run steps it doesn't own. A claim processed on Inngest creates zero Flowplane step rows — just the decision when a human is needed.

The Inbox

The reviewer-first surface. It lists decisions awaiting a human, sorted by SLA urgency, each showing its context. A reviewer opens one, sees what they're deciding (the AI output, the fields, the diff), and approves or rejects — which resolves the decision and resumes the engine.

The Inbox is the dashboard's home. Execution views (runs, steps) are a bundled-engine detail, intentionally demoted — Flowplane leads with the decision, not the DAG.

Notifications

When a decision is created, each approver is notified through the outbox (a durable, idempotent delivery queue) → email today, Slack/DocuSign on the roadmap. SLA reminders re-nudge as the deadline nears, and the SLA sweeper auto-expires abandoned decisions so a workflow never wedges.