ReferenceControlArcConceptsSequences and Stages

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:

start_btn => main

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

sequence abort {
    stage safed {
        0 -> press_vlv_cmd
        1 -> 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.

stage pressurize {
    // ALL lines run at the same time:
    1 -> valve_cmd                       // keep valve open
    tank_pressure -> pressure_display    // update display
    tank_pressure > 600 => abort         // safety limit
    tank_temp > 300 => abort             // temperature limit
    abort_btn => abort                   // operator abort
    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.

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 covers sequence declaration, the full set of sequence items, entry points, and inline stages.
  • Stages covers stage declaration, entry semantics, parallel monitoring rules, and inline sequences.
  • Flow covers the -> and => operators and the full table of transition targets.