# Sequences

> Arc sequence reference for state machine declarations, transitions, and entry points

## Sequence declaration

```arc
sequence name {
    // sequence items
}
```

A sequence runs its items in order. Only one item is active at a time.

A sequence can be named or anonymous. A named sequence starts when an entry point triggers it. An anonymous top-level sequence starts automatically when the program loads.

```arc
sequence named {
    // ... items ...
}
start_cmd => named

sequence {
    // ... items, auto-started ...
}
```

## Sequence items

A sequence item is one of:

| Item           | Syntax                | Description                                   |
| -------------- | --------------------- | --------------------------------------------- |
| Condition gate | `expr => next`        | Pause until the expression is truthy, advance |
| Write          | `expr -> chan`        | Write once, advance                           |
| Wait           | `time.wait{duration}` | Pause for the duration, advance               |
| Sequence       | `sequence { ... }`    | Run nested items in order                     |
| Stage          | `stage { ... }`       | Enter stage; advance when a transition fires  |

Stages and sequences can be named. A named item is a valid `=> name` target for its siblings; an anonymous one can only be reached in order.

```arc
sequence prime {
    true -> vent_vlv_cmd              // write
    tank_pressure < 50 => next        // condition gate
    false -> vent_vlv_cmd             // write
    time.wait{5s}                     // wait
    stage pressurize {                // stage
        tank_pressure > 700 => abort
        true -> press_vlv_cmd
        tank_pressure > 500 => next
    }
    false -> press_vlv_cmd            // write
}
```

> A bare sequence can’t respond to safety conditions while a condition gate is holding. If you need to watch for abort conditions during a step, put the step inside a stage.

## Sequencing rules

1. When an item completes, the sequence advances; when the last item completes, the sequence exits.
2. `=> name` to a sibling item jumps there. Re-entry resets [`:=` variables](https://docs.synnaxlabs.com/reference/control/arc/reference/variables#declaration) and keeps [`$=` variables](https://docs.synnaxlabs.com/reference/control/arc/reference/variables#stateful).
3. `=> name` to a top-level scope stops the whole top-level sequence or stage that holds the transition, then starts the target in the same cycle. Nothing in the stopped scope resumes. A running target does not restart, but a jump to the scope that holds it restarts that scope.
4. Activations are independent: several top-level scopes can run at the same time.

## Entry points

Entry points trigger sequences from external events:

```arc
start_cmd => main  // channel triggers main sequence
em_stop => abort   // channel triggers abort sequence
```

Entry points use `=>` because they fire while the channel value is truthy. The target sequence activates on the first truthy tick; subsequent truthy ticks are no-ops because the sequence is already active.

### Triggering sequences

Entry point channels are typically `bool` virtual channels:

1. Create a `bool` virtual channel in Synnax (e.g., `start_cmd`)
2. Wire the channel to a button in Console
3. When clicked, the button writes `true` to the channel
4. Arc sees the truthy value and triggers the sequence

### Anonymous top-level sequences

An anonymous top-level sequence has no entry point and starts automatically on program load:

```arc
sequence {
    false -> vent_vlv_cmd
    true -> press_vlv_cmd
    time.wait{5s}
    false -> press_vlv_cmd
}
```

## Inline stages in a sequence

An anonymous `stage { ... }` used as a sequence item acts as a multi-exit gate. `=> next` advances the enclosing sequence; other [transition targets](https://docs.synnaxlabs.com/reference/control/arc/reference/flow#transition-targets) jump as usual.

```arc
sequence press {
    true -> press_vlv_cmd
    stage {
        tank_pressure > 500 => next
        time.wait{30s} => abort
    }
    false -> press_vlv_cmd
}
```

## Complete example

```arc
authority 200

sequence main {
    stage idle {
        false -> press_vlv_cmd
        false -> vent_vlv_cmd
        start_btn => pressurize
    }

    stage pressurize {
        // Safety first
        ox_pt_1 > 700 => abort
        fuel_pt_1 > 500 => abort
        abort_btn => abort
        // Control
        true -> press_vlv_cmd
        false -> vent_vlv_cmd
        // Progress
        ox_pt_1 > 500 => hold
    }

    stage hold {
        ox_pt_1 > 700 => abort
        abort_btn => abort
        true -> press_vlv_cmd
        time.wait{duration=5s} => vent
    }

    stage vent {
        false -> press_vlv_cmd
        true -> vent_vlv_cmd
        ox_pt_1 < 50 => complete
    }

    stage complete {
        false -> press_vlv_cmd
        false -> vent_vlv_cmd
    }
}

sequence abort {
    stage safed {
        false -> press_vlv_cmd
        true -> vent_vlv_cmd
    }
}
// Entry points
start_cmd => main
emergency_stop => abort
```

## Restrictions

| Restriction               | Description                                       |
| ------------------------- | ------------------------------------------------- |
| One active item           | Only one item per sequence is active at a time    |
| `next` needs a next item  | `next` in the last item of a sequence is an error |
| Entry points at top level | Entry points must be outside sequences            |
