Execution Specification
Overview
An Execution is a single run of a compiled plan. Plans are immutable, so the execution references the plan by ID and provides the actual parameter values for that run.
Here is an example:
id: exec_abc123
spec:
cluster: staging-us
runner: default
planID: pl_xyz789
params:
cluster: "staging-us"
sandbox: "my-sandbox"
secrets:
apiToken: prod-api-token
status:
phase: running
createdAt: "2026-01-15T10:30:00Z"
updatedAt: "2026-01-15T10:31:00Z"
stepCounts:
init: 0
waiting: 0
running: 1
completed: 2
failed: 0
skipped: 0
inputs:
- name: cluster
resolvedVia: literal
- name: sandbox
resolvedVia: literal
- name: apiToken
resolvedVia: callerSecret
secretName: prod-api-token
Execution semantics
Delivery guarantees
Plan executions provide at-least-once semantics. Under normal conditions each step runs exactly once, but if the runner pod is evicted or loses connectivity, the control plane may re-dispatch the execution to another runner. A re-dispatched execution restarts from scratch --- all steps run again, including any that had already completed in the previous attempt. Action code should be written with this in mind --- idempotent actions are safest.
Within a single attempt, each step runs at most once: a failed step is not retried, and its downstream dependents are skipped.
Step scheduling
Steps are scheduled based on the DAG derived from reference expressions. A step becomes ready when all steps it depends on have completed. Ready steps run concurrently (up to 10 steps in parallel per execution).
If a step has a condition that evaluates to false, the step is
skipped. If a step fails, all transitive dependents are
cascade-skipped.
If a step specifies a routingContext, the runner waits for the
referenced sandbox or route group to become ready before executing
the step.
Environment variables
The following environment variables are set for each step:
| Variable | Description |
|---|---|
SIGNADOT_PLAN_EXECUTION_ID | The execution ID |
SIGNADOT_PLAN_STEP_ID | The step ID within the plan |
SIGNADOT_PLAN_WORKDIR | The step's working directory (contains context/ and outputs/) |
SIGNADOT_PLAN_EXECUTION_SCRATCHDIR | Plan-execution scratch dir, writable by every step in the execution and bind-mounted read-write into containerized steps via actionbox run-image |
SIGNADOT_PLAN_EXECUTION_BINDIR | bin/ subdir of the scratch dir, prepended to PATH in both dispatch paths so a binary staged by step N is callable by step N+1 |
SIGNADOT_CACHE_DIR | Read-only PRG-level image cache used by actionbox run-image as a fast path before registry pulls |
HOME | Per-step writable home directory under the workdir |
TMPDIR | Per-step writable temp directory under the workdir |
SSL_CERT_FILE | Path to CA certificates for HTTPS |
SIGNADOT_ROUTING_KEY | Routing key, if the step has a routing context |
SIGNADOT_SANDBOX_NAME | Sandbox name, if the routing context targets a sandbox |
SIGNADOT_ROUTEGROUP_NAME | Route group name, if the routing context targets a route group |
Steps also inherit the runner process's full environment, with
SIGNADOT_PLAN_EXECUTION_BINDIR prepended to PATH so per-execution
binaries take precedence over the runner image's tools.
id
The id is a server-assigned unique identifier for the execution.
spec
The execution spec provides the inputs needed to run a compiled plan.
spec.cluster
The cluster is the target cluster for this execution. This is the
cluster name registered with Signadot where the plan will be executed.
cluster is required unless the plan's
cluster affinity can resolve
a cluster from the execution's params. If both are present, they must
agree.
spec.runner
The runner is the runner group name assigned to execute the plan.
runner is required unless the plan's
spec.runner is set.
spec.planID
The planID is the ID of the compiled plan being executed.
planID is required.
spec.params
The params field is a map from parameter names to JSON values,
providing the actual values bound to the plan's declared parameters.
Example:
params:
cluster: "staging-us"
sandbox: "my-sandbox"
verbose: true
params is optional.
spec.secrets
The secrets field is a map from plan parameter names to org secret
names. At dispatch time, the control plane resolves each named secret
to its decrypted value and delivers it to the runner alongside regular
params. API responses always return the name mapping --- never the
decrypted values.
Example:
secrets:
apiToken: prod-api-token
dbPassword: staging-db-password
Constraints:
- Each key must match a declared
spec.params[].nameon the plan. - A given parameter name must appear in either
spec.paramsorspec.secrets, never both. - Each referenced secret must already exist in the org's secret store.
secrets is optional.
status
The execution status is server-managed and reflects the runtime state of the execution.
status.phase
The phase represents the overall execution state.
| Phase | Description |
|---|---|
pending | Created but no runner has been assigned yet |
dispatching | Runner pod selected, run request is being sent |
running | Execution is in progress |
finalizing | All steps are terminal, artifact uploads are in progress |
completed | All steps finished successfully |
failed | One or more steps failed |
cancelled | Cancelled by user |
The terminal phases are completed, failed, and cancelled.
status.runnerHost
The hostname of the runner executing the plan.
status.createdAt
When the execution was created. Serialized as RFC3339.
status.updatedAt
When the execution status was last updated. Serialized as RFC3339.
status.completedAt
When the execution finished. Serialized as RFC3339. Only present for executions in a terminal phase.
status.stepCounts
The stepCounts field provides the count of steps in each step phase.
| Field | Description |
|---|---|
init | Steps that have not yet started |
waiting | Steps waiting for routing context readiness |
running | Steps currently executing |
completed | Steps that finished successfully |
failed | Steps that finished with an error |
skipped | Steps that were not executed |
status.inputs
An array of plan-level input resolution status objects, populated at
the transition to dispatching. Each entry records how a single
plan parameter was resolved.
| Field | Description |
|---|---|
name | The plan parameter name |
resolvedVia | The source that populated the value (see Input resolution) |
secretName | The caller-supplied secret name when resolvedVia is callerSecret |
status.steps
The steps field is an array of step status objects providing
per-step runtime status.
status.steps[_].id
The step identifier, matching the corresponding step ID in the plan spec.
status.steps[_].phase
The current execution state of the step.
| Phase | Description |
|---|---|
init | Step has not yet started |
waiting | Waiting for routing context to become ready |
running | Currently executing |
completed | Finished successfully |
failed | Finished with an error |
skipped | Not executed (condition was false or upstream step failed) |
status.steps[_].inputs
An array of step input resolution status objects, populated at the
transition to running. Each entry records how one of the step's
declared inputs (action params or extraInputs)
was resolved.
| Field | Description |
|---|---|
name | The step input name |
resolvedVia | The source that populated the value (see Input resolution) |
ref | The reference expression text when resolvedVia is ref |
status.steps[_].outputs
An array of step output status objects, populated when the step phase
is completed.
Each output has the following fields:
| Field | Description |
|---|---|
name | The output field name |
metadata | Presentation hints (e.g. contentType, displayName) |
value | Inlined output value (for small text/JSON outputs) |
artifact | Reference to S3-stored output (for large outputs) |
Exactly one of value or artifact is set.
status.steps[_].logs
An array of log status objects for the step's captured log streams, populated when the step reaches a terminal phase.
Each log has the following fields:
| Field | Description |
|---|---|
stream | Log stream type (stdout or stderr) |
value | Inline log content (if small enough) |
artifact | Reference to S3-stored log |
status.steps[_].error
A human-readable error message, populated when the step phase is failed.
status.outputs
An array of plan-level output status objects, populated on completion. Each output extends the step output status with additional fields:
| Field | Description |
|---|---|
name | The plan output name |
metadata | Presentation hints |
value | Inlined output value |
artifact | Reference to S3-stored output |
stepRef | Source step output for alias/drill outputs |
drill | Path segments to walk inside the source output's JSON |
The stepRef field identifies the source step output:
| Field | Description |
|---|---|
stepID | Source step identifier |
outputName | Output name in that step |
The drill field is an array of path segments used to extract a
sub-field from structured step output JSON. For example,
["response", "statusCode"] would extract the statusCode from a
response object.
status.error
A human-readable error message for execution-level failures (e.g.
artifact upload failures, plan output resolution errors). Step-level
errors are found in status.steps[_].error.
Input resolution
Each declared input --- whether a plan parameter or a step input ---
records how it was bound at execution time via resolvedVia. The
recognized values differ slightly between scopes:
resolvedVia | Scope | Meaning |
|---|---|---|
literal | plan, step | A caller-supplied literal value (spec.params[name] for plan, step.args.values[name] for step) |
callerSecret | plan only | A caller-supplied secret binding (spec.secrets[name]); the resolved secretName is recorded |
ref | step only | A reference expression in step.args.refs[name]; the ref text is recorded |
default | plan, step | The author-declared default on the field |
unbound | plan, step | Nothing resolved; only valid when the field is not required |
Resolution is purely classificatory --- required inputs that are not bound by any source are rejected by pre-dispatch validation, so this list never reflects an unbound required field.
Artifacts
Large outputs and logs are stored as artifacts. An artifact reference contains the following fields:
| Field | Description |
|---|---|
size | Artifact size in bytes |
checksum | Base64-encoded SHA-256 digest |
ready | true once the artifact has been uploaded |
error | Set if the artifact upload failed |