# Sequences and stages

> How to think about Arc's sequence and stage constructs

Sequences and stages are Arc’s two building blocks for multi-step procedures.

A **sequence** runs its items one at a time, in order. Items can be writes, waits, condition gates, or stages.

A **stage** runs multiple flows in parallel and stays live until a transition fires. Stages are how you watch many conditions at once: hold a valve open while monitoring pressure, temperature, and an abort button, then exit when whichever condition fires first.

The two compose freely. A stage inside a sequence adds parallel monitoring to a single step. A sequence inside a stage runs an ordered sub-procedure while the stage’s flows continue watching for safety conditions.

This is the most common use case for Arc: test sequences, startup routines, shutdown procedures, and any workflow that progresses through distinct phases.

## A simple example

Here’s a basic pressurize, hold, and vent sequence:

```arc
start_btn => main

sequence main {
    stage pressurize {
        true -> press_vlv_cmd
        tank_pressure > 700 => abort    // safety
        tank_pressure > 500 => next     // target reached
    }
    false -> press_vlv_cmd
    time.wait{10s}
    stage vent {
        true -> vent_vlv_cmd
        tank_pressure < 50 => next
    }
    false -> vent_vlv_cmd
}

sequence abort {
    stage safed {
        false -> press_vlv_cmd
        true -> vent_vlv_cmd
    }
}
```

The `main` sequence has five items that run in order. `pressurize` is a stage that holds `press_vlv_cmd` open while watching two exits: an over-pressure abort at 700 psi and a success at 500 psi. Whichever fires first decides what happens next. Once the stage exits, the sequence continues: close the valve, wait ten seconds, open the vent stage, close the vent valve.

The `start_btn => main` is the entry point. When `start_btn` receives a truthy value, the sequence starts.

## Parallel monitoring

> **Everything in a stage runs at the same time.** The code looks sequential, but Arc executes all flows in a stage concurrently.

```arc
stage pressurize {

    // ALL lines run at the same time:

    abort_btn => abort                   // operator abort
    tank_temp > 300 => abort             // temperature limit
    tank_pressure > 600 => abort         // safety limit

    true -> valve_cmd                    // keep valve open
    tank_pressure -> pressure_display    // update display
    tank_pressure > 500 => next          // success condition
}
```

You don’t write loops to “keep checking” these conditions. Arc monitors all of them concurrently while the stage is active.

> **Line order determines priority for transitions.** When multiple conditional edges (`=>`) are truthy in the same cycle, the one listed first wins. Always put safety conditions before success conditions.

## Transitions

A **transition** is a flow statement whose target is a stage or sequence name. When the edge fires, the current stage or sequence deactivates and control jumps to the target.

```arc
stage running {
    stop_btn => idle         // jump to named sequence or stage
    emergency => abort       // jump to different sequence or stage
    pressure > 500 => next   // advance to the next
}
```

Transitions fire while the source expression is truthy. Transitioning to an already-active target is a no-op, so a source that stays truthy will not re-enter a running sequence or stage.

## Reference

For full syntax and rules, see the language reference:

* [Sequences](https://docs.synnaxlabs.com/reference/control/arc/reference/sequences) covers sequence declaration, the full set of sequence items, entry points, and inline stages.
* [Stages](https://docs.synnaxlabs.com/reference/control/arc/reference/stages) covers stage declaration, entry semantics, parallel monitoring rules, and inline sequences.
* [Flow](https://docs.synnaxlabs.com/reference/control/arc/reference/flow) covers the `->` and `=>` operators and the full table of transition targets.
