Decisions
Ce contenu n’est pas encore disponible dans votre langue.
The decide step evaluates conditions and routes execution accordingly. Use it when your machine needs to take different paths based on data. Each branch decision is recorded in the behavioral ledger, making your control flow auditable after the fact.
Basic syntax
Section titled “Basic syntax”decide <name> when <condition> <expression or steps> when <condition> <expression or steps> otherwise <expression or steps>Conditions are evaluated top to bottom. The first when that matches executes. If nothing matches, otherwise runs. If there is no otherwise and nothing matches, the step returns null.
Simple branching
Section titled “Simple branching”machine ticket_router
accepts priority as text, is required
responds with queue as text sla_hours as number
behaves decide route when input.priority == "urgent" {queue: "critical", sla_hours: 1} when input.priority == "high" {queue: "priority", sla_hours: 4} when input.priority == "medium" {queue: "standard", sla_hours: 24} otherwise {queue: "backlog", sla_hours: 72}
verifies test "urgent goes to the critical queue" given {priority: "urgent"} expect {queue: "critical", sla_hours: 1} test "unknown priority lands in the backlog" given {priority: "someday"} expect {queue: "backlog", sla_hours: 72}Natural language conditions
Section titled “Natural language conditions”decide supports both symbolic and natural-language operators. These are equivalent:
// Symbolicwhen input.amount > 10000when steps.score.value != "pass"when input.count >= 5 && input.active
// Natural languagewhen input.amount is greater than 10000when steps.score.value is not "pass"when input.count is at least 5 and input.active| Symbolic | Natural language |
|---|---|
== |
is |
!= |
is not |
> |
is greater than |
< |
is less than |
>= |
is at least |
<= |
is at most |
&& |
and |
|| |
or |
Branching on step results
Section titled “Branching on step results”The most common pattern: use the output of an ask step to decide what happens next.
machine approval_workflow accepts amount as number, is required department as text, is required responds with approved as boolean approver as text behaves ask evaluate, using: "anthropic:claude-haiku-4-5" with task "Evaluate this expense. Amount: ${input.amount}, Department: ${input.department}. Return risk level." returns risk_level as text decide route_approval when input.amount is greater than 10000 {approved: false, approver: "CFO review required"} when steps.evaluate.risk_level is "high" {approved: false, approver: "Risk committee"} when input.amount is at most 500 {approved: true, approver: "auto-approved"} otherwise {approved: true, approver: "manager"} ensures permissions allowed to model verifies test "small low-risk expense auto-approves" assuming evaluate {risk_level: "low"} given {amount: 200, department: "engineering"} expect {approved: true, approver: "auto-approved"} test "large expense needs the CFO" assuming evaluate {risk_level: "low"} given {amount: 50000, department: "engineering"} expect {approved: false, approver: "CFO review required"}Branching to named flows
Section titled “Branching to named flows”For branches that need multiple steps, dispatch to a named flow with run flow(name):
machine order_processor
accepts quantity as number, is required items as list
responds with status as text
behaves compute check_inventory {in_stock: input.quantity <= 100}
decide fulfillment_path when check_inventory.in_stock run ship_direct otherwise run backorder
flows flow ship_direct ask create_shipment, from: "@mashin/actions/http/post" url: "https://fulfillment.internal/shipments" body: {items: input.items} compute result {status: "shipped"}
flow backorder ask notify, from: "@mashin/actions/http/post" url: "https://fulfillment.internal/backorders" body: {message: "Backorder needed"} compute result {status: "backordered"}
ensures permissions allowed to network.http to "fulfillment.internal"
verifies test "in-stock orders ship directly" assuming create_shipment {id: "shp_1"} given {quantity: 5, items: ["widget"]} expect {status: "shipped"}decide vs. compute ternary
Section titled “decide vs. compute ternary”For simple value selection, a ternary in compute is shorter:
// Simple: use ternarycompute label {tier: input.amount > 1000 ? "premium" : "standard"}
// Complex: use decidedecide route when input.amount > 10000 {tier: "enterprise", handler: "account_manager"} when input.amount > 1000 {tier: "premium", handler: "priority_support"} otherwise {tier: "standard", handler: "general_support"}Use decide when: there are more than two branches, each branch needs multiple fields, or you want branches visible in the ledger trace. Use ternary when: it is a simple two-way value choice on a single field.
Governance
Section titled “Governance”Decide steps are pure control flow. They do not require permissions and do not make external calls. However, every branch decision is recorded in the behavioral ledger with the condition that was evaluated and which branch was taken. This makes control flow auditable.
Steps inside branches inherit normal governance. An ask step inside a when clause still requires model permission.
Try it
Section titled “Try it”Build a machine that takes a customer order with amount, customer_tier, and item_count. Use a decide step to route: VIP customers with large orders get express handling, small orders get auto-processing, and everything else goes to standard review.
Next steps
Section titled “Next steps”- Actions - Calling external machines from branches
- Flows - Multi-flow machines in depth
- decide reference - Full specification