Skip to content

Flow documentation

Flow runs BPMN 2.0 processes, CMMN 1.1 cases and DMN decisions as written. An AI agent is one step inside them. Every case keeps a record of what it was handed and what it derived, and that record replays against the process definition the case started on.

Each engine is a pure reducer. Advance(state, event) returns the commands to carry out and the next state, and does no I/O of its own. FEEL conditions and DMN decisions evaluate inside the engine. Service tasks, user tasks, timers, messages and agent calls leave it as commands.

A host stores the state and carries out the commands. Flow has two:

  • The broker is the main host. It runs the engines over a Raft log, and every replica applies each turn’s result as data. kirto-flow runs the broker, the engines, the connectors and the gateway in one binary. With no DATABASE_URL it keeps its stores in an embedded SQLite file and needs only a data directory. kirto-flow-broker runs the broker as a cluster.
  • DBOS runs cases durably on Postgres.

The model and the connector code are the same on both. Where a feature runs on one host only, the page that describes it says so.

A case’s history is a JSON array of audit events in sequence order, the body of GET /v1/cases/{kind}/{id}/history. Some events are inputs the world handed the case: signals, messages, timer fires and task results. The rest the engine derived from them: conditions evaluated, decisions made, commands dispatched, state transitions, completion.

kirto-flow-replay feeds the inputs back through a fresh engine on the pinned model, derives the rest again, and compares it with what was stored, row by row:

Terminal window
$ kirto-flow-replay -model refund.bpmn -history case-4821.json
{
"chainLen": 5,
"match": true,
"recordedWith": "0.1.0-dev",
"replayedWith": "0.1.0-dev",
"versionSkew": false
}

The comparison covers each derived row’s type, element id and attributes. The sequence number, the timestamp and the pins are written by the host, so they are not compared. Every mismatch is listed with its index, the field that differs, and both values.

The exit code is the verdict:

Exit Meaning
0 The derived rows match the stored ones.
1 At least one row diverged, or the build doing the replay differs from the recording build at MAJOR.MINOR.
2 The replay could not run: a missing flag, an unreadable file, or a history with no case.started record.

A version skew exits 1 because a reducer change between minor versions can change what the engine derives. The verdict reports both versions. The same replay runs in the browser modeller and on the gateway at GET /v1/cases/{kind}/{id}/replay.

  • AI agents in a process: the two AI capabilities, the provider seam, and why an agent’s tools are the process’s connectors.
  • The static agent: an agent with a fixed tool allowlist, wired into a BPMN service task or a CMMN task, and the error codes it raises.
  • Agents governed by the case: the mode where the case decides, turn by turn, which tools the agent may call.
  • Sentries as tool gates: the argument for governing agent tools with CMMN, for architects and risk owners.
  • Flow and agent frameworks: how this differs from graph and conversational agent frameworks, and when one of those fits better.