# Changes: simulation and confirmation

> How every CLI change is simulated, shown as a diff, confirmed against the zone version and optionally followed to the edge.

Every command that changes something follows the same flow, the one described in [Simulate, then confirm](https://developers.openwaf.dev/change-control/simulate-and-confirm/):

1. It reads the zone's current version.
2. It asks the API for a **simulation** of the change with that version and prints the plan: `Simulación sobre zona example.com: versión 7 → 8` followed by one line per change and any warnings (`aviso:`).
3. If the change would modify nothing, it prints `Sin cambios: no hay nada que aplicar.` ("no changes: nothing to apply") and stops with exit code 0.
4. It asks `¿Aplicar? [s/N]` ("apply?"). `s`, `sí`, `y` or `yes` apply; anything else cancels.
5. It sends the change with **the same** expected version and prints `Aplicado: zona example.com, versión 8.` ("applied").
6. With `--wait`, it follows propagation until every edge node has the new version.


If the zone changed between steps 1 and 5, the API refuses the change, nothing is applied and the CLI exits with code 3.

## Diff lines

| Line | Meaning |
|---|---|
| `+ path: value` | Added. |
| `- path: value` | Removed. |
| `~ path: before → after` | Replaced. |

Long values are cut at 160 characters. Certificate changes are listed apart under `Certificados (informativo…)`: their material is not versioned and a revert does not restore them.

## Options of every change

| Option | Meaning |
|---|---|
| `--reason "…"` | **Required.** 1–500 characters, no line breaks. Stored in the version and in the audit log. |
| `--dry-run` | Only simulate, with the same validation as the real change. Nothing is applied. |
| `--yes` | Apply without asking. Required when standard input is not a terminal (CI, cron, pipes); without it the CLI stops with `sin terminal para confirmar` and applies nothing. |
| `--wait[=120s]` | After applying, wait until every edge node has applied the new version. `--wait` waits up to 120 seconds; `--wait=90s` or `--wait=90` sets another limit. Available on zone changes. |

## Waiting for the edge

With `--wait`, the CLI prints `Esperando a que los nodos apliquen la versión 8 (plazo 2m0s)…` and then one line per node as it confirms (`aplicado … en 41.3s`). It ends with `Propagado a N nodos en …` ("propagated to N nodes in …").

Each node applies a change within one polling interval and confirms it on its next poll, so the time measured is about twice the interval. If some node has not confirmed in time, the CLI lists the pending ones and exits with code 4; the change stays applied. Temporary API errors while waiting are retried until the time is up.

## Changes that are not zone versions

| Commands | Simulation | `--wait` |
|---|---|---|
| `cache purge`, `origin-certs create`, `origin-certs revoke` | Simulated by the API; not versioned. | No |
| `zones merge`, `zones unmerge` | Simulated; they create versions in both zones. | No |
| `zones add`, `zones rm` | Simulated; versioned. | No |
| `clients add/set/rm`, `brand set`, `whitelabel domain`, `whitelabel nameservers` | Not simulated: `--dry-run` prints what would be sent and sends nothing. | No |

## Scripts and CI

```sh
openwaf-cloud ctl records set example.com www/A content=203.0.113.20 \
  --reason "Deploy 42: move www" --yes --wait=180s
case $? in
  0) echo "applied and propagated" ;;
  3) echo "someone changed the zone: review and retry" ;;
  4) echo "applied, but some edge node is late" ;;
  *) exit 1 ;;
esac
```

Use a token with the narrowest scope that works, such as one limited to the zone.
