Skip to content

Workflow Specification

Status

Current specification for Workflow DSL v2.

Workflow definitions are governed data. They are stored in namespace registry processes and are deployed through signed process_event events. TypeScript and frontend code render workflows only; workflow parsing, validation, graph building, canonicalization, and execution semantics live in Rust/WASM.

Workflow identity

Every non-bootstrap workflow declares a canonical $path:

json { "$version": "2.0", "$path": "customer/retail/retail-customer", "$description": "Retail customer onboarding" }

Rules:

  • $path is the workflow identity.
  • namespace = dirname($path).
  • workflow = basename($path).
  • File/workspace path is $path + ".json".
  • No $category or other active organization metadata.
  • No basename version suffixes like -V1.

Bootstrap exception:

  • system/bootstrap is the only visible bootstrap workflow.
  • Non-system registries are governed by the hardcoded Rust bootstrap workflow internally, but do not store or list */bootstrap definitions.

Workflow shape

Workflow DSL v2 is graph-first. States and actions are explicit top-level maps.

json { "$version": "2.0", "$path": "customer/retail/retail-customer", "$description": "Retail customer onboarding", "initial": "intake", "states": { "intake": { "label": "Intake" }, "review": { "label": "Review" }, "approved": { "label": "Approved", "terminal": true } }, "actions": { "create": { "role": "admin,analyst", "from": "intake", "to": "review", "mutate": { "$set": { "state": "review" } } }, "approve": { "role": "manager", "from": "review", "to": "approved", "when": "risk_score < 70", "mutate": { "$set": { "state": "approved" } } } } }

Metadata fields

Field Required Meaning
$version yes Workflow schema version, currently "2.0" for active workflows
$path yes for non-bootstrap Canonical identity and organization path
$description no Human-readable summary
initial yes Initial state key for new processes
states yes Map of state keys to state definitions
actions yes Map of action keys to action definitions

State fields

Field Required Meaning
label no Human-readable state label
terminal no true if no further business action should advance the process
description no State context/help text

State keys must be unique. Terminal status is derived from the active workflow state definition, not a separate process flag.

Action fields

Field Required Meaning
role no Comma-separated actor roles. * or absent means any actor.
from no Source state. Required for transition actions.
to no Target state. Optional for self-effect actions.
when no Pre-condition expression evaluated against current process data and canonical action input.
mutate no Mutation operators applied to process data.
then no Post-condition expression evaluated after mutation.
spawn no Child-process spawn definitions using canonical workflow paths.
schedule no Scheduled/system action definitions.

Actions are looked up from workflow.actions.get(action.name). There are no hardcoded business action lists.

Roles

Roles are comma-separated strings:

json "role": "admin,manager,analyst"

Matching is case-insensitive. * or missing role means any verified actor may perform the action.

Expressions

when and then expressions are parsed and evaluated by Rust, not SQL.

Category Operators Example
Equality =, != state = 'review'
Comparison >=, <=, >, < risk_score < 70
List IN state IN ('intake', 'review')
Null IS NULL, IS NOT NULL reviewer IS NULL
JSON key test ? input.note ? 'content'
Logic AND, OR, NOT, () state = 'review' AND score > 0
Unary minus - score > -1

Unsupported: SQL, subqueries, function calls, arbitrary JavaScript, and binary arithmetic.

Mutation operators

Mutations are deterministic JSON transformations.

Operator Effect
$set Set top-level keys.
$append Append to an array.
$merge Shallow-merge an object.
$remove Remove a top-level key.
$increment Increment a numeric field.
$spawn / spawn Create child process using canonical workflow path.
$schedule / schedule Register future/system action.
$unschedule Cancel scheduled action.

Special values:

  • "input.fields.x", "input.refs.x", and other input.* paths resolve from the signed event input.
  • "$timestamp" resolves to the single timestamp captured for the event.

State authority

For active v2 workflows:

  • process.data.state is authoritative.
  • data.phase exists only as legacy/migration fallback where needed.
  • get_process_flow exposes current_state.
  • terminal status is read from states[current_state].terminal.

Deployment

Workflow definitions are stored in namespace registry processes:

text registry process id = namespace with / replaced by - + "-registry"

Examples:

Namespace Registry process
customer/retail customer-retail-registry
case/review case-review-registry
system system-registry

Deployment rules:

  • Business/demo workflows are deployed through signed add_workflow or update_workflow events.
  • Event action.workflow uses the target registry governance path, e.g. customer/retail/bootstrap internally for the registry process.
  • Non-system registries do not store bootstrap; runtime loads the hardcoded bootstrap workflow for registry actions.
  • Deployment target namespace/key must match $path.
  • No raw UPDATE processes, jsonb_set, or direct registry mutation.

Spawn references

Spawn references are full canonical paths:

json { "spawn": [ { "workflow": "case/review/kyc-review", "from": "review", "to": "open" } ] }

Rules:

  • No relative spawn references.
  • Runtime validates the target workflow exists.
  • Child process namespace/workflow are derived from the target path.

Validation requirements

Validation must reject:

  • missing $path for non-bootstrap workflows,
  • invalid path shape,
  • duplicate state/action keys,
  • duplicate workflow paths in a workspace/export/import set,
  • $category in active definitions,
  • legacy $version: "1.0" in active definitions,
  • basename suffixes like -V1,
  • unresolved spawn.workflow references,
  • deployment target/path mismatches.

Warnings may be shown for non-fatal authoring guidance, but errors block import, deployment, or execution.