Status Diagram
queued ──→ in_progress ──→ completed
│ │ │
│ │ ├──→ pending_approval ──→ completed (after auto-apply)
│ │ │
│ │ ├──→ pending_policy ──→ completed
│ │ │
│ │ └──→ rejected
│ │
│ ├──→ failed
│ ├──→ timed_out
│ └──→ aborted
│
└──→ (stays queued until claimed)
All Statuses
| Status | Terminal | Description |
|---|---|---|
queued | No | Run is waiting to be executed |
in_progress | No | Run is currently executing |
completed | Yes | Run finished successfully |
failed | Yes | Run finished with an error |
timed_out | Yes | Run exceeded the timeout |
pending_policy | No | Run is waiting for policy evaluation |
pending_approval | No | Run is waiting for human approval |
rejected | Yes | Run was rejected by governance |
aborted | Yes | Run was cancelled by a user |
unlocked | Yes | Force-unlock run completed |
Run Types
| Type | Description |
|---|---|
plan | Produces a plan showing what would change |
apply | Executes a previously created plan |
unlock | Releases a stale Terraform state lock |
Trigger Sources
| Trigger | How it starts |
|---|---|
manual | User clicked “Run Plan” or called the API |
push | Git push webhook matched the workspace |
schedule | Scheduled run (cron) |
pr | Pull request webhook |
promotion | Upstream workspace promoted changes |
Concurrency
One run at a time per workspace. Only one run can be in_progress for a given workspace. Additional runs stay in queued until the active run completes. This prevents concurrent state modifications.
Per-org concurrency for managed runs. Managed execution has a per-org limit on concurrent runner jobs (default: 3). If your org has more queued runs than this limit, they execute in order as slots free up. Large orgs with many active workspaces should expect queueing during busy periods.
Lifecycle Flow
Plan Run
- queued — Run is created and waiting for a runner slot
- in_progress — Runner claims the run on its first heartbeat and starts executing
- completed — Plan produced successfully
- Governance evaluates (if configured):
- No violations → stays
completed - Advisory violations → stays
completedwith warnings - Mandatory violations → transitions to
rejected - Approval required → transitions to
pending_approval
- No violations → stays
Apply Run
- queued — Created from a completed plan (or manually)
- in_progress — Runner executes the plan
- completed — Changes applied, changeset stamped with
applied_at - Auto-promotion triggers downstream workspaces (if configured)
Terminal Statuses
Once a run reaches a terminal status (completed, failed, timed_out, rejected, aborted, unlocked), it cannot be changed. To re-run, create a new run.
Related API Endpoints
POST /workspaces/{id}/runs— Create a plan runGET /workspaces/{id}/runs— List runs with cursor paginationGET /runs— List runs across all workspaces (offset pagination)GET /workspaces/{workspaceId}/runs/{runId}— Get a single run with phases