Skip to main content

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:

VariableDescription
SIGNADOT_PLAN_EXECUTION_IDThe execution ID
SIGNADOT_PLAN_STEP_IDThe step ID within the plan
SIGNADOT_PLAN_WORKDIRThe step's working directory (contains context/ and outputs/)
SIGNADOT_PLAN_EXECUTION_SCRATCHDIRPlan-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_BINDIRbin/ 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_DIRRead-only PRG-level image cache used by actionbox run-image as a fast path before registry pulls
HOMEPer-step writable home directory under the workdir
TMPDIRPer-step writable temp directory under the workdir
SSL_CERT_FILEPath to CA certificates for HTTPS
SIGNADOT_ROUTING_KEYRouting key, if the step has a routing context
SIGNADOT_SANDBOX_NAMESandbox name, if the routing context targets a sandbox
SIGNADOT_ROUTEGROUP_NAMERoute 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[].name on the plan.
  • A given parameter name must appear in either spec.params or spec.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.

PhaseDescription
pendingCreated but no runner has been assigned yet
dispatchingRunner pod selected, run request is being sent
runningExecution is in progress
finalizingAll steps are terminal, artifact uploads are in progress
completedAll steps finished successfully
failedOne or more steps failed
cancelledCancelled 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.

FieldDescription
initSteps that have not yet started
waitingSteps waiting for routing context readiness
runningSteps currently executing
completedSteps that finished successfully
failedSteps that finished with an error
skippedSteps 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.

FieldDescription
nameThe plan parameter name
resolvedViaThe source that populated the value (see Input resolution)
secretNameThe 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.

PhaseDescription
initStep has not yet started
waitingWaiting for routing context to become ready
runningCurrently executing
completedFinished successfully
failedFinished with an error
skippedNot 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.

FieldDescription
nameThe step input name
resolvedViaThe source that populated the value (see Input resolution)
refThe 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:

FieldDescription
nameThe output field name
metadataPresentation hints (e.g. contentType, displayName)
valueInlined output value (for small text/JSON outputs)
artifactReference 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:

FieldDescription
streamLog stream type (stdout or stderr)
valueInline log content (if small enough)
artifactReference 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:

FieldDescription
nameThe plan output name
metadataPresentation hints
valueInlined output value
artifactReference to S3-stored output
stepRefSource step output for alias/drill outputs
drillPath segments to walk inside the source output's JSON

The stepRef field identifies the source step output:

FieldDescription
stepIDSource step identifier
outputNameOutput 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:

resolvedViaScopeMeaning
literalplan, stepA caller-supplied literal value (spec.params[name] for plan, step.args.values[name] for step)
callerSecretplan onlyA caller-supplied secret binding (spec.secrets[name]); the resolved secretName is recorded
refstep onlyA reference expression in step.args.refs[name]; the ref text is recorded
defaultplan, stepThe author-declared default on the field
unboundplan, stepNothing 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:

FieldDescription
sizeArtifact size in bytes
checksumBase64-encoded SHA-256 digest
readytrue once the artifact has been uploaded
errorSet if the artifact upload failed