Every command runs the same ordered pipeline. The difference between a dry run and a live change is a single flag deep inside it, not a different code path — so what you preview is what you get.
Partial YAML → Validate → Closure → Reconcile → Plan → Execute (with late-bound IDs)

The stages

1

Validate

Parse every YAML source, expand any OpenAPI-backed resources, check each resource against its schema, and extract the ${kind.ref_name} references that define dependencies.
2

Closure

Topologically sort the resources from their references, so every dependency is created before the resource that needs it.
3

Reconcile

Diff your desired resources against what already exists remotely. Discovery decides, per resource, whether it must be created, updated, or left unchanged.
4

Plan

Compile the reconciliation result into a concrete set of create / update / delete operations in dependency order.
5

Execute

Run the planned operations concurrently, respecting the dependency order, resolving each ${kind.ref_name} into the target API’s identifier at call time.

plan vs apply

plan and apply run the same pipeline through the Plan stage. The only difference is whether the Execute stage performs side effects:
CommandRuns validate → planExecutes operationsSide effects
wxctl planyesnonone — a dry run
wxctl applyyesyescreates / updates resources remotely
wxctl plan -f config.yaml      # preview what would change
wxctl apply -f config.yaml     # validate, plan, and execute
Because both share the planning path, a clean plan is a faithful preview of what apply will do. destroy runs the same pipeline in reverse-dependency order to tear resources down leaves-first.

Late-bound identifier resolution

A reference like ${tool.calculator} is not resolved when the file is parsed — the resource may not exist yet. It is resolved during Execute, once the referenced resource has been created and its real identifier is known. wxctl then substitutes that identifier in whatever shape the consuming API requires: a bare UUID or GUID, an href, a CRN, or a nested object. This late binding is what lets one configuration work across environments. Nothing in the YAML is pinned to a specific instance — the identifiers are discovered or created fresh each run.

Next steps

Declarative model

Resources, references, and how YAML sources combine.

Profiles & credentials

How wxctl authenticates to each service.