Skip to content

Context & Variables

Context variables ($) represent data owned by a machine instance. They persist across events and can be manipulated with natural language operations.

Basic Concepts

Every machine instance has its own context - isolated data that belongs only to that instance:

flow
machine: @order

scenario: cart management

  on> :add_item from @customer
    $items adds $item           // This order's items
    $total increases by $price  // This order's total

Different order instances have their own $items and $total - they don't share data.

Setting Values

Basic Assignment

flow
$total becomes 100
$name becomes "John Doe"
$is_active becomes true
$items becomes empty

With Type Annotations

Type annotations are optional but help with documentation and validation:

flow
$total: number becomes 100
$name: string becomes "John Doe"
$is_active: boolean becomes true
$items: array becomes empty
$config: object becomes empty

Supported Types

TypeDescriptionExample
stringText values"Hello"
numberIntegers and decimals100, 99.99
booleanTrue/falsetrue, false
arrayList of items["a", "b"]
objectKey-value pairs{key: value}

Arithmetic Operations

Increase

flow
$total increases by 25
$count increases by 1
$balance increases by $deposit

Decrease

flow
$total decreases by 10
$stock decreases by $quantity
$attempts decreases by 1

Examples

flow
on> :add_item from @customer
  $total increases by $item.price
  $item_count increases by 1

on> :apply_discount from @customer
  $total decreases by $discount_amount

on> :remove_item from @customer
  $total decreases by $item.price
  $item_count decreases by 1

Collection Operations

Add to Collection

flow
$items adds "Laptop"
$items adds $new_item
$tags adds "urgent"

Remove from Collection

flow
$items removes "Laptop"
$items removes $item
$tags removes "completed"

Clear Collection

flow
$items clears
$tags clears
$history clears

Complete Example

flow
machine: @shopping_cart

scenario: cart operations

  on> :add_to_cart from @customer
    $items: array adds $product
    $total: number increases by $product.price

  on> :remove_from_cart from @customer
    $items removes $product
    $total decreases by $product.price

  on> :clear_cart from @customer
    $items clears
    $total becomes 0

Reading Context in Guards

Use context variables in conditions:

flow
? $total is greater than 100
  apply free shipping

? $item_count equals 0
  show empty cart message

? $items contains "Gift Card"
  apply gift card discount

? $user_type is "premium"
  apply premium discount

Comparison Patterns

PatternMeaning
$var equals valueEqual to
$var is valueEqual to
$var is not valueNot equal to
$var is greater than value>
$var is less than value<
$var is at least value>=
$var is at most value<=
$var contains valueArray/string contains
$var is emptyEmpty collection/string
$var is not emptyNon-empty

Context in Assertions

Verify context values in expect: blocks:

flow
scenario: checkout

  given:
    $total: number is 0

  on> :add_item from @customer
    $total increases by $item.price

  expect:
    = $total equals 1200
    = $items contains "Laptop"
    = $item_count equals 1

Context in Given Blocks

Initialize context for testing:

flow
scenario: apply discount

  given:
    $total: number is 1200
    $discount_code: string is "SUMMER20"
    $items: array contains "Laptop"

  on> :apply_discount from @customer
    ? $discount_code is valid
      $total decreases by 100

  expect:
    = $total equals 1100

Accessing Nested Data

Access properties of complex objects:

flow
$total increases by $item.price
$customer_name becomes $order.customer.name
? $payment.status is "completed"
  order moves to #paid

Context Scope

Instance Scope

Each machine instance has its own context:

@order:abc123 → $total: 1200, $items: ["Laptop"]
@order:xyz789 → $total: 50, $items: ["Mouse"]

Event Data Access

Event data is available during event handling:

flow
on> :checkout from @customer
  // $order_id comes from the event payload
  $internal_order_id becomes $order_id
  $customer_email becomes $customer.email

Built-in Values

Some values are provided by the runtime:

flow
$created_at becomes now        // Current timestamp
$updated_at becomes now
$id becomes generated_id       // System-generated ID

No Binding Required

Simple context operations work without PHP binding:

flow
// These work automatically
$total becomes 100
$total increases by 25
$items adds "Laptop"
$items clears

Complex operations that require business logic can be bound to PHP when needed.

Best Practices

Use Descriptive Names

flow
// Good
$order_total: number becomes 0
$cart_items: array becomes empty
$customer_email: string becomes ""

// Avoid
$t becomes 0
$arr becomes empty
$e becomes ""

Initialize in Given Blocks

flow
scenario: checkout

  given:
    $total: number is 0
    $items: array is empty
    $discount_applied: boolean is false

Use Type Annotations for Clarity

flow
// Clear intent
$retry_count: number becomes 0
$is_premium: boolean becomes false
$tags: array becomes empty

Released under the MIT License.