Skip to content

run

run

Execute a named flow and return to the current flow when it completes. A run directive is the call-and-return mechanism for flow-to-flow control. Execution jumps to the named flow, runs all its steps, and then resumes from the statement after run in the calling flow. This is the primary way to organize multi-flow machines and to dispatch from decide branches.

When to use

Use run when you need to:

  • Execute a named flow from within another flow and continue after it finishes
  • Dispatch to different flows from decide branches
  • Organize a machine into reusable flow segments
  • Call event handlers from subscribes > on declarations

Use goto when you want to jump to a flow without returning (true tail-call). Use launch for async fire-and-forget execution of another machine. Use ask ... from to call another machine (not a flow within the same machine).

Syntax

run flow(<flow_name>)

Or within event subscriptions:

subscribes
on "<event>" run <flow_name>

Examples

Simple flow dispatch

machine report_generator
accepts
report_type as text, is required
data as map, is required
implements
decide choose_report
when input.report_type is "summary"
run flow(generate_summary)
when input.report_type is "detailed"
run flow(generate_detailed)
otherwise
run flow(generate_default)
flows
flow generate_summary
compute build
{report: "Summary: " + input.data.title, type: "summary"}
flow generate_detailed
ask analyze, using: "anthropic:claude-sonnet-4-6"
with task "Generate a detailed report from this data.\n\nData: ${JSON.stringify(input.data)}"
returns
report as text
assuming
report: "Detailed analysis..."
compute build
{report: steps.analyze.report, type: "detailed"}
flow generate_default
compute build
{report: "Default report for " + input.data.title, type: "default"}

Call-and-return: continue after flow

machine pipeline
implements
compute setup
{ready: true}
// run = call-and-return: execute process flow, then continue here
run flow(process)
// This step executes AFTER the process flow completes
compute finalize
{done: true, processed: steps.setup.ready}
flows
flow process
compute work
{result: "processed"}

Event-driven flow dispatch

machine order_handler
implements
subscribes
on "order.created" run validate_and_process
on "order.cancelled" run handle_cancellation
flows
flow validate_and_process
ask validate, from: "@myorg/orders/validate"
order_id: event.order_id
returns
valid as boolean
assuming
valid: true
compute result
{processed: steps.validate.valid}
flow handle_cancellation
action refund call
machine: "@myorg/billing/refund"
order_id: event.order_id
compute result
{cancelled: true}

Run vs goto

run flow(name)goto flow(name)
BehaviorCall-and-returnTrue tail-call
After executionReturns to calling flow; remaining steps executeDoes not return; remaining steps are skipped
StackAdds to call stackDoes not add to stack (replaces)
Use caseSubroutines, modular flowsSelf-loops, state machines, recursion

Both are subject to flow depth protection (max 100 by default) to prevent infinite recursion.

Governance

run is a control-flow directive. It does not perform I/O and does not require governance approval. However, the steps inside the target flow inherit normal governance. If the target flow contains ask or action steps, those are governed individually.

The flow dispatch itself is recorded as a control-flow event in the behavioral ledger (Inv 5: Control-Flow Observability), including which flow was dispatched and from where.

Translations

LanguageKeyword
Englishrun
Spanishejecuta
Frenchexecute
Germanstarte
Japanese実行
Chinese运行
Korean실행

See also

  • decide - Branching logic, often uses run in branches
  • launch - Async fire-and-forget (different machine)
  • implements - The section where flows and run directives live
  • goto - Tail-call variant (no return)