Skip to main content
Version: 2.0.0

Run a workflow

This page is how you start a workflow and follow the execution it creates. There are two paths. orca run is the simple one: fire-and-forget a single-group, standalone submission. Multi-group and batched submissions drop down to orca submission submit. Both shapes are explained on Submissions.

orca run​

orca run <workflow> --run-mode <PURE_SIM|DEVICE_SIM|LIVE> [options]

A run mode is required on every submission. There is no deployment-level fallback and no default. Omitting --run-mode exits 2.

Run modeWhat it means
PURE_SIMEvery device runs against its in-process sim driver. No wire calls, so no device bridge is involved. Fast.
DEVICE_SIMThe live driver runs, so the wire is exercised, and the device bridge binds a sim backend on the far end. No hardware moves.
LIVEThe live driver runs against the real hardware backend.

The submitted mode is combined with each device's topology sim_override at dispatch time. See sim hierarchy. The --sim flag on orca topology mount is a different thing and picks no mode: see the --sim flag on a mount.

LIVE and DEVICE_SIM cannot be in flight at the same time. Both dispatch over the same wire to the same on-prem device connections, so a DEVICE_SIM run would switch a device to its sim backend while a LIVE run drives it for real. Submitting one while the other is alive is refused, and the refusal names the execution to wait on. This holds across separate executions and regardless of --batch-mode. Two concurrent LIVE runs are fine, two concurrent DEVICE_SIM runs are fine, and PURE_SIM never reaches the wire so it runs alongside anything.

Quick patterns​

# Fire-and-forget
orca run smc_assay --run-mode PURE_SIM

# Block until terminal, give up after 2 minutes
orca run smc_assay --run-mode PURE_SIM --wait --timeout 120

# Pass workflow variables
orca run smc_assay --run-mode DEVICE_SIM --vars plate_count=2,reagent_batch=L7

# LIVE submission against devices that declare a sim_override
orca run smc_assay --run-mode LIVE --confirm

Flags​

FlagRequired?Effect
--run-modeyesPURE_SIM / DEVICE_SIM / LIVE. No default.
--waitnoBlock until the execution is terminal (completed / failed / aborted).
--timeout <s>with --waitSeconds before the CLI gives up. Default 300. The execution keeps running; the timeout only stops the CLI waiting. Exit 50.
--poll <s>with --waitPolling interval. Default 0.5.
--vars KEY=VAL,KEY2=VAL2noPer-submission variable overrides. See typing below.
--profile <path>noPath to a JSON deployment profile, loaded into the execution before any thread ticks. Local-only; with --backend cloud exits 2.
--confirmLIVE plus sim_overrideAcknowledges the LIVE_SUBMISSION_WITH_SIM_OVERRIDES_UNACKNOWLEDGED gate. Without it the runtime refuses the submission.

--vars values are typed best-effort, in this order: true or false (case-insensitive) becomes a bool, then an integer parse, then a float parse, and anything left over stays a string. So plate_count=2 is an int, dry_run=TRUE is a bool, and reagent_batch=L7 is a string. An entry with no = exits 2.

--profile is validated locally first: the CLI resolves the path to an absolute one and checks it is a file, then hands the daemon the path. The daemon binds 127.0.0.1 only, so it reads the same filesystem the CLI sees.

Output​

$ orca run smc_assay --run-mode PURE_SIM
submitted execution 7a3f1c0e (smc_assay)

With --wait the CLI polls until terminal, then prints a key-value summary:

execution 7a3f1c0e
workflow: smc_assay
status: completed
error:

The --json shapes differ between the two paths. Without --wait you get the ExecutionRecordDTO the submission returned. With --wait you get the ExecutionDetailDTO from the final poll, the same shape orca execution detail returns.

--wait exits 1 when the execution reaches a terminal state that is not completed, so a failed run is a failed command.

--wait and an error-paused thread​

An action error whose failure policy is PAUSE parks the labware thread and waits for an operator. The execution never reaches a terminal state on its own, so a naive poll would burn the whole timeout.

--wait detects this and fails fast with exit 31, naming the thread, the device call it was inside, the error, and the recovery command:

error: execution 7a3f1c0e has an error-paused thread 22b9d1a4 (sample_plate)
while running device call 'shake': device did not respond.
Recover with `orca execution thread recover <exec-id> <thread-id>
<retry|retry-op|continue|abort-action|abort-method|abort-thread>`.

See Recover from errors for what each recovery decision does, and Failure policies for what makes a thread pause in the first place.

Pitfalls​

  • --wait --timeout 60 is not a kill switch. It abandons the CLI's poll loop; the execution keeps running. To actually stop one, use execution stop.
  • --run-mode LIVE against any device with a topology sim_override is refused unless --confirm is passed. The refusal lists the overriding devices, so you can see which ones the LIVE submission would route to a simulator.
  • --profile is local-only. Passing it with --backend cloud exits 2 with a redirect; the cloud REST surface does not accept profile paths.
  • --vars is per-submission. It overrides defaults declared on the workflow's variables. To set a default for every future submission, use var set-global. The resolution order is on Variables.

orca submission submit: multi-group and batched​

run is single-group and STANDALONE. For anything richer, use submission submit. What a labware group and a batch mode do to labware sharing is on Submissions.

# Multi-group: N samples per submission, each in its own group
orca submission submit smc_assay --run-mode PURE_SIM \
--groups-file groups.json

# Batched: join an in-flight accepting execution of the same workflow
orca submission submit smc_assay --run-mode PURE_SIM \
--groups-file groups.json --batch-mode JOIN_EXISTING

The workflow name is a positional argument, not --workflow. The group spec is a plain path via --groups-file, or inline JSON via --groups-json; there is no @file syntax. The content is a single group object or a JSON array of them.

FlagEffect
<workflow> (positional)The registered @orca.workflow template name.
--run-modeSame as run. Required.
--groups-file <path>Multi-group spec file: one group object or a list of them.
--groups-json <json>The same spec inline as a JSON string. Mutually exclusive with --groups-file.
--batch-mode STANDALONE|JOIN_EXISTINGDefault STANDALONE. Any other value exits 2.
--vars KEY=VAL,...Submission-scope variable overrides. Same typing rules as run.
--operator-id <id>Optional operator id recorded on the submission.
--profile <name>Optional deployment-profile name recorded for audit. This is not run --profile, which takes a file path.
--confirmAcknowledges the LIVE plus sim_override gate, same as run.

A group looks like this:

{
"id": "batch-1",
"members": [
{"thread_template_name": "sample_plate", "acquisition": {"kind": "pool"}},
{"thread_template_name": "tip_rack",
"acquisition": {"kind": "location", "source_location": "stack_1",
"verify_barcode": "ABC123"}}
]
}

Submitting with zero groups is the same one-shot path orca run takes.

Confirmation​

submission submit prompts before it submits, unlike orca run:

Submit workflow 'smc_assay' with 2 group(s), batch_mode=STANDALONE? [y/N]:

Pass --force (--yes, -y) to skip it. Declining exits 40, and so does a non-TTY stdin with no --force.

What it prints on acceptance​

submission 4c1e77a2 accepted (execution=7a3f1c0e, groups=2)
3 thing(s) nobody has settled. Nothing is blocked; settle what this run depends on:
tip_rack_1: nothing has ever said what 'tip_rack_1' holds, which is not the same as empty
settle with: set-tip-state
ml_star: what 'ml_star' is carrying was known, then nobody was watching
settle with: confirm-mounted-tips
assay_plate_2: an action that has not finished did things to what 'assay_plate_2'
holds, and the record only hears about them when the action ends; settle the
action (retry, continue, or abort) rather than confirming or restating this

The unsettled list prints here because this is the moment somebody is looking. Nothing in it blocks the submission. The same list is available any time from orca state unsettled. See State.

Each line names the subject and why the record cannot answer for it. The second line is the verb that settles it, and which verb it names is the useful part:

  • confirm-* means the record is still the best value there is, and you are agreeing with it after a look. A rack that merely went unwatched gets confirm-tip-state, not a demand that you retype ninety-six positions the record already has right.
  • set-* means there is nothing worth agreeing with. Three cases produce it: nobody ever said, an aborted action threw away work so the record is short by an amount nothing can state, or the record holds nothing the confirm verb could back.
  • No second line at all means no verb answers, as on assay_plate_2 above. An unfinished action is holding operations: confirming would freeze a number that is behind, and stating one is worse, because the action's own operations get folded on top when it ends. Settle the action instead, with retry, continue or abort. See Recover from errors.

In --json, each row also carries subject_id. Labware verbs take a labware id and two live instances can share a name, so act on the id rather than re-looking-up the name.

List and detail​

orca submission list                           # all submissions on this runtime
orca submission list --execution <exec-id> # one execution's submissions
orca submission detail <submission-id> # one submission

list prints id, execution, workflow, group count, status, batch mode and submission time. detail adds the operator id and the deployment profile. Both id arguments accept a prefix of 4 or more characters.

Pitfalls​

  • JOIN_EXISTING with nothing live starts a fresh execution. It is not an error. The join only happens when an execution of the same workflow is already accepting; otherwise the submission boots its own.
  • JOIN_EXISTING is refused against an execution that is draining or stopping, and the refusal tells you to resubmit as STANDALONE or wait for the current one to terminate.
  • JOIN_EXISTING is refused against a paused execution. A pause gates new work, and queuing behind it would hide the submission. Resume first.
  • One execution carries one run mode. Joining an execution submitted under a different --run-mode is refused rather than mixing dispatch routes inside one run.
  • Groups are independent within a submission. Each group gets its own thread spawns. Groups whose labware templates declare SHARED_ACROSS_GROUPS converge on shared physical labware, so read the template flags before assuming isolation. See Submissions.

Run one method in isolation​

To exercise a single method without its surrounding workflow (testing, recovery rehearsal), use method execute:

orca method execute <workflow> <method> \
--labware-start '{"sample_plate": "stack_1"}' \
--labware-end '{"sample_plate": "stack_2"}' \
--run-mode PURE_SIM [--vars '{"plate_count": 2}'] [--confirm]

The workflow and method names are positional. --labware-start and --labware-end are required JSON objects mapping labware name to location name. --run-mode is required, with the same modes and the same --confirm gate as run. Note that method execute --vars takes a JSON object, not the KEY=VAL form the other two verbs take. Works against both backends.

Track an execution​

Once submitted, these read-only verbs follow its progress. Mid-flight inspection goes further: where every plate is, what is in it, and who is holding which device.

orca execution list                                    # all executions
orca execution detail <id> # full snapshot
orca execution threads <id> # thread roll-up
orca execution thread detail <id> <thread-id> # one thread, all fields

execution list takes no filters. It lists every execution known to the loaded system as id, workflow, status, paused and error. Narrow it yourself with --json | jq if the count is large.

execution detail <id> prints workflow, status, paused, error and the three thread counts (total, active, completed). Every id argument accepts a prefix of 4 or more characters, and execution ids also accept last.

execution threads <id> prints id, name, status, completed-method count and the current method for each thread in the execution.

execution thread detail <id> <thread-id> prints the per-thread snapshot: name, status, current location, current method, current action, completed methods, and the pause fields (pause_reason, last_error, pause_message, pause_site, honoured_decisions, paused_device_command).

Status vocabulary​

Both list and detail report the same value, and it comes from one of two vocabularies depending on where the row was read from.

While the runtime owns the execution, the status is its phase:

PhaseMeaning
acceptingLive, and open to further JOIN_EXISTING submissions.
drainingclose was called. No new submissions; running threads finish.
stoppingA confirmed stop is unwinding the execution. Non-terminal; it becomes aborted once the task fully unwinds.
completedEvery thread terminal, no crash and no abort.
failedA thread crashed with an unhandled error.
abortedTerminal via a confirmed stop, or via unload.

An execution rehydrated from a terminal database row reports the flatter task state instead: running, completed, failed or aborted.

Pause is a latch, not a status​

A pause never changes the status. A paused execution stays accepting or draining, so the status column alone reads as if the stop never landed. That is what the separate paused column is for:

id        workflow   status     paused                          error
7a3f1c0e smc_assay accepting paused (operator), abort armed

paused (operator) means an operator set the latch; paused (system) means the runtime paused itself. abort armed means a second confirmed stop would abort the execution.

Error-paused threads are separate again. execution detail prints a block per error-paused thread under the summary, carrying the last error, the pause message, the action it stopped in, the pause site, the recovery decisions that site will honour, the device call it was inside, and the ready-to-run execution thread recover command line.

Stopping and closing​

orca execution close <id> moves an execution from accepting to draining: no new JOIN_EXISTING submissions, live threads run to completion. It prompts unless you pass --force. Standalone submissions for the same workflow still boot a fresh execution afterwards.

orca execution stop <id> is a two-call confirmed abort. The first call pauses the execution and arms the abort, and is undone by orca execution resume. A second call with --confirm performs the abort. It is documented in full on Operator interventions.

Pitfalls​

  • list returns every execution, terminal ones included, with no server-side filters. Pipe --json through jq to narrow by status.
  • thread detail returns only the per-thread snapshot. Variables and reservations live on the parent; use execution detail <id> for those.

See also​