Skip to main content
Version: v5.7.0

Change

Included from Basic tier

A change is one execution of an action against a node (a project, environment or asset): the run record, its step tree, its approval/pause/cancel audit trail, and the git commit it ran from. JSON:API type: change.

The v2 OpenAPI document declares this resource's schema; the resource-field coverage gate holds this page to it.

Endpoints​

RouteServes
GET /api/changesList, created_at desc then id desc. Default limit 100, max 10,000; a page trimmed at the limit answers 206 with meta.partial_response: true.
GET /api/projects/{project}/…/changesThe same list scoped to a node subtree (the node-path router).
GET /api/changes/{id}Show. Default include=steps. Changes of a soft-deleted subtree are hidden from lists but still served by id.
POST /api/changes (and the node-path variant)Create — or retry, when attributes.retry is true and the body carries a change relationship naming the original. The body may carry an inputs object, validated against the action's declarations before the run exists; a named 422 points at inputs on a violation, and inputs are refused for actions with no declarative action file. 201 with the show document, steps included.
POST /api/changes/plan (and the node-path …/changes/plan)Plan without creating: the create body compiled and evaluated with no run row; 200 with a plan document — the step tree with tier-1 will_run/will_skip verdicts and tier-2 symbolic spans. Advisory: the run re-evaluates at step entry.
DELETE /api/changes/{id}Cancel: 204, or 422 Change cannot be cancelled because it is already finalised.
POST /api/changes/{id}/pause / /resumePause/resume; 200 with the updated change, 422 named errors (already finalised, already paused, not paused).
GET /api/changes/{id}/log_linesThe change's log surface.
GET /api/changes/{id}/artefacts (alias /artifacts)Artefacts published by the change's steps.
GET /api/changes/{id}/converged_properties / /converged_settingsThe converged documents the change ran with (see opschain docs resources/properties and opschain docs resources/settings).

List filtering is filter[<attribute>_eq]=<value> over the serialized attributes (any attribute below), plus two ransackable-scope predicates the GUI's "Search by step" page sends: filter[step_action_or_name_in][]=<term> (repeatable — keeps changes where ANY step of the change's whole tree has that action or step name, exact but case-insensitive; the upstream Change.step_action_or_name_in scope) and filter[created_at_lt]=<ts> (the page's keyset bound, strict < over creation time). Any other predicate is a 400 unsupported filter. List meta carries authorisations (update/delete/execute on the request path), has_any and partial_response.

The activity feed (GET /api/activities)​

The GUI's Activity screens and the CLI's changes list read changes and workflow runs through the merged activity feed, which carries its own filter vocabulary (each key the upstream Ransack predicate over the activity views' columns; a key outside it is a 400 Unpermitted parameters):

FilterMeaning
filter[action_present]=1Keeps rows whose action is not null.
filter[g][][m]=or with filter[g][][parent_path_eq] / filter[g][][parent_path_start]The grouped node-subtree scope: the node itself OR anything under it (_start carries the trailing /).
filter[sorts][]=created_at descOverrides the default updated_at desc order.
filter[activity_type_eq]change or workflow_run — restricts the union to one arm.
filter[id_eq] / filter[id_in][]Exact id lookup / id set (text comparison over the canonical uuid).
filter[free_text_cont_any]Case-insensitive contains over each arm's free-text fields (id, project code, action, creator, status, metadata text; plus git remote/rev/sha on changes, workflow name/code and project name on runs). LIKE metacharacters in the term match literally.
filter[created_at_gt/lt/gteq/lteq]Creation-time bounds (also the GUI's keyset pagination).
filter[updated_at_gt/lt], filter[started_at_gt/lt], filter[finished_at_gt/lt]Root-step timestamp windows; a null timestamp matches no bound.
filter[created_by_in][]Creator usernames, case-insensitive, every provider's account of each name.
filter[status_code_in][]Serialized status codes (the vocabulary below).
filter[scheduled_eq] / filter[paused_eq]Boolean flags (paused is paused_at IS NOT NULL).
filter[git_remote_name_cont] / filter[git_rev_cont]Case-insensitive contains over the change's commit details; never matches a workflow run.
filter[metadata_text_cont]Case-insensitive contains over the row's metadata rendered as text.
filter[workflow_code_eq] / filter[version_in][]Workflow-run-only keys (never match a change): the workflow's code, the run's version set.
filter[action_eq]Exact, case-sensitive action match.
filter[scheduled_activity_id_eq]The owning scheduled activity (uuid, case-insensitive; an unparseable value matches nothing).
filter[project_code_eq] / filter[project_code_in][]The owning project's code (exact).

A blank value is ignored rather than matched against (filter[action_eq]= is a no-op), as upstream Ransack drops blank conditions. Sparse fieldsets (fields[activity]=…) and limit (default 100, max 1000; a trimmed page answers 206) apply as elsewhere.

Attributes​

Timestamps are ISO8601 strings with six fractional digits. Many change attributes are delegated from the root step (started_at, finished_at, updated_at, state_timing, the approval/cancel audit attributes), and the action/step_name pair comes from the change's action step (the root step on a pre-approval schema).

AttributeTypeMeaning / origin / null semantics
created_bystringUsername of the creator (the authenticated actor at POST). Never null.
step_namestringThe action step's step name.
actionstringThe action the change runs (the action step's action). Set at create; immutable.
build_without_cachebooleanRequest attribute frozen at create. DEPRECATED architecture-wide (owner 2026-10-18: no step-image builds) — accepted as a documented no-op for upstream payload parity.
auto_continue_wait_stepsbooleanRequest attribute frozen at create; wait steps continue without a user gate.
initial_step_treeobject/nullThe step tree known at creation; null until/unless discovery supplies one.
metadataobjectCaller-supplied metadata, stored at create, plus the server-owned opschain namespace the create lane stamps: opschain.requester_kind (user | agent), opschain.rationale (the create request's stated reason), opschain.recommendation_id (the recommendation the change implements), and on an agent-originated change opschain.agent_id (the fleet member id), opschain.instance_id (the acting instance — the change's initiator), opschain.agent_code, opschain.agent_project, opschain.tier_at_creation and opschain.correlation_id — the provenance the approvals inbox reads back as the approval context. A plain human create that states neither a rationale nor a recommendation keeps its metadata byte-for-byte; the provenance keys are server-written and overwrite any caller-supplied twin.
rationalestringCreate attribute (POST /api/changes): why the change is raised, stored as opschain.rationale and shown to approvers. Optional for a person; mandatory for an agent principal — an agent-originated create without one answers 422 (Rationale can't be blank). At most 4000 characters.
recommendation_idstringCreate attribute: the recommendation this change implements, stored as opschain.recommendation_id and resolved into the approval context.
scheduledbooleanTrue when a scheduled activity created the change.
approved_byarrayAudited approve transitions of the root step ({username, message, date}, date at second precision), from the audit:steps:approve events. [] when none.
rejected_byarrayAs approved_by, for audit:steps:reject. [] when none.
cancelled_byarray/nullAudited cancel transitions (audit:steps:cancel); null when the change was never cancelled.
state_timingobjectThe root step's per-state timing ranges.
state_timing_summaryobjectThe change's stored timing summary column.
notifyobjectThe create request's notification routing, stored verbatim (notification dispatch is an unported subsystem — recorded gap).
skip_stepsarray of stringsThe create/retry request's skip mask (exact, glob or path-prefix matches against step full_paths).
starting_stepstring/nullThe create request's starting step, or null.
cluster_namestringThe stored cluster name; "" when unset.
pause_statestring"none", "pausing" (paused with an active leaf-or-wait step still running down) or "paused".
status_codestringThe serialized run status — see the vocabulary below. Computed by the upstream SQL function public.change_serialized_status_code over the root step.
pausedbooleanTrue while paused_at is set.
paused_byarrayOrdered pause/resume audit trail ({username, action, message, date}) from the audit:changes:pause/audit:changes:resume events. [] when never paused.
created_atstringRow creation time.
started_atstring/nullRoot step start; null until the run starts.
finished_atstring/nullRoot step finish; null until finalised.
updated_atstringRoot step's last update.
paused_atstring/nullWhen the current pause began; null while not paused.
asset_namestring/nullTarget asset's display name; null when the target is not under an asset.
environment_namestring/nullTarget environment's display name; null for project-targeted changes.
project_namestringTarget project's display name.
git_remote_namestring/nullThe commit's git remote name.
git_revstring/nullThe requested git revision.
commit_shastring/nullThe resolved commit SHA.
requires_approval_fromarray/nullThe stored approval requirements, each merged with its first matching approve (approved_by, always present once requirements exist — null until someone matching approves) and, when matched, rejected_by response. null when the change requires no approval. Username matching is case-insensitive; live LDAP group resolution is a recorded gap.
correlation_idstringThe chain handle; defaults to the change's own id when nothing caused it. An agent-originated change joins the chain of the agent's SDK-managed correlation scope (the invocation that triggered the agent), so the chain reads incident → the agent's reads → recommendation → this change.
caused_by_event_idstring/nullThe event that triggered this change (trigger firings), else null.
initiated_by_type / initiated_by_idstring/nullThe polymorphic initiator (e.g. a trigger, or agent + the agent instance's id for a change an agent raised inside a correlation scope — the member id and agent code are in metadata.opschain); null for user-created changes.
chain_depthintegerHops from the chain's origin (0 for an origin run).
maintenance_stampstring/nullPresent only on changes created under a maintenance override; absent otherwise.
inputsobjectThe change's recorded typed inputs, resolved at creation against the action's inputs: declarations — supplied values and evaluated defaults (run.*, the target node.*) alike. Secret-typed values serialize as ****** everywhere. Absent when the change carries no inputs.
error_handledbooleantrue once a failure-path step (when: error()/always()) executed on this change's failed scope — the change still finalises error; compensation never masks it. Absent otherwise.

Status vocabulary​

Raw step states (mirroring the upstream StateMachine::AvailableStates):

pending, queued, running, waiting, success, skipped, error, cancelled, aborted, system_error

Display pseudo-statuses layered on top (display.go): a running change whose every blocking leaf-or-wait step is waiting reports waiting, or waiting_for_approval when a blocking step requires approval; a rejected approval root reports rejected; a retried root awaiting its re-run reports pending. Wait steps count as blockers even though they carry children — a waiting wait step acquires its children on entry to waiting, so "leaf" alone never identifies it. Upstream change roots that still need commit resolution can additionally report initializing; runs created by this server resolve the commit at creation and never enter it.

pause_state vocabulary: none, pausing, paused.

What affects approval, pause, cancel and retry​

  • Approval: requires_approval_from (resolved from settings at create) gates the root/wait steps; the gates themselves are step endpoints (POST /api/steps/{id}/approve|continue|reject — see opschain docs resources/step). approved_by/rejected_by record the outcomes.
  • Pause: POST …/pause with {"data":{"attributes":{"reason":""}}}; paused, paused_at, paused_by and pause_state reflect it. Authorised by execute on the change's action path. Availability is advertised on the document itself: links.pause appears while the change is pausable (not finalised, not paused) and links.resume while it is paused (the upstream serializer's shape). The v2 change view carries the same signal as the typed pausable field, and the GUI's Pause verb follows that flag — Resume while the change is paused.
  • Cancel: DELETE /api/changes/{id} (execute or delete on the action path); records cancelled_by and drives the steps to cancelled/aborted.
  • Retry: POST /api/changes with attributes.retry: true, a change relationship, and optional skip_steps/metadata/override_maintenance. Successful/skipped steps keep their state; the rest re-run (retried steps read pending until re-driven).
  • Maintenance: a create targeting a node under an active maintenance window is refused unless override_maintenance: true and the caller holds the window's override right; the override stamps maintenance_stamp.

Relationships and includes​

RelationshipTarget typeNotes
propertiespropertiesThe action step's properties document.
parentsnode typesThe target node's ancestry, root project first.
root_stepstepThe run's root step.
stepsstepEvery step, ordered (parent, step_sequence). The show default include.
template_versiontemplate_versionOnly on templated (asset) changes.
workflow_run / workflowworkflow_run / workflowOnly when a workflow change step spawned the change.
override_properties / override_settingsproperties / settingsOnly when the create carried overrides.

Any relationship is includable via include= (dotted paths supported, e.g. include=steps.properties). Links: self (node-path form), parent (the target node), project, log_lines, git_remote. Show-only meta: wait_queue and blocking_queue (both [] unless the composition supplies them — see opschain docs fleet-queue for the dispatch-side queue view).

  • opschain docs resources/step — the step family this change is made of.
  • opschain docs resources/workflow_run — the workflow-run sibling.
  • opschain docs resources/event — the audit events behind the *_by attributes.
  • opschain docs cli/runs-create, opschain docs cli/runs-show.