> ## Documentation Index
> Fetch the complete documentation index at: https://delivery.vexa.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Operations

> Day-2: how updates arrive, your production gate, rollback, break-glass.

**Your staging follows the channel pointer; your production does nothing until you move its pin.**

## Promote to production

```bash theme={null}
kubectl -n argocd patch applicationset vexa-channel-subscription --type=json \
  -p '[{"op":"replace","path":"/spec/generators/0/list/elements/1/position","value":"0.12.23"}]'
```

The pin is the release's chart version (`0.12.23`, no `v` prefix); staging holds `*`, the newest entry on your channel. That is the whole promotion ceremony — one change, in your cluster, in your window. Admission verification runs again in production regardless.

## Before an upgrade, on a deployment with history

Every estate that has been running has state an upgrade must survive — rows that predate a constraint, a model pinned to a device, a schema last converged three releases ago. Send us that state and the upgrade arrives on your channel already rehearsed against it: [Upgrade](upgrade). Read-only, one command, nothing transmits.

## Accept the upgrade

Same standard as a first install — a human watches it capture a real meeting. Run [`vexa_validate.py`](install#step-5-send-the-station-report-back) instead to also refresh the station bundle; an upgrade is when your station's shape is most likely to have moved.

<Note>
  **Rung.** The intended procedure, and the tool implements it — but **no audio has reached the pipeline in any delivery run yet** — [what's proven, and where](tested#the-delivered-software).
</Note>

```bash theme={null}
python3 kit/smoke/vexa_smoke.py --namespace vexa-staging \
  --customer-values my-values.yaml --flows
```

## Roll back

The same field, the same patch, the previous version:

```bash theme={null}
kubectl -n argocd patch applicationset vexa-channel-subscription --type=json \
  -p '[{"op":"replace","path":"/spec/generators/0/list/elements/1/position","value":"0.12.22"}]'
```

Entries never disappear and digests are immutable, so what you go back to is byte-identical to what you ran. **It rolls back code, not data** — one step back is safe because each release reads the previous release's schema; two steps back is a restore. **Check the migration notes** in the release's evidence bundle first.

## Break-glass in your cluster

Your cluster, your admin, your audit log — there is no path from Vexa into it. Staging syncs automatically and self-heals, so suspend that Application's automated sync before you touch anything; production has no automated sync at all. Declare it, suspend, act — then **reconverge through the gate**: resume the sync and let admission verify what is now running. A residue that violates your contract is refused, not quietly baked in; you clear it by redoing the change as a release, amending your values, or recording a waiver.

## Update the kit

```bash theme={null}
./vexa-kit/self-update.sh --check   # what would move
./vexa-kit/self-update.sh           # move it
```

Resolves `latest` to a digest, verifies it against your pinned key, swaps the tree atomically. On a signature failure nothing is written and the running tree is untouched.

**Self-update is the bootstrap layout only.** It reads the `.kit-source` record that [`bootstrap.sh`](install#step-1-get-the-kit) writes beside the tree it unpacks, and errors out without one — a tree you cloned with `git` has no such record, and updates with `git pull`.

## If the channel goes away

Your pinned release keeps running: Argo CD reconciles against digests it has already pulled, so an unreachable channel stops upgrades, not workloads. On our side the channel is a distribution copy — entries, charts and signatures are rebuilt from tagged releases, and the record of what was published is held in git, replicated, independent of the registry. A total loss costs us hours of republishing and costs you nothing: no re-install, no re-pinning, no re-verification.

Also worth knowing: an out-of-band change is **reverted** on the next sync, not merely reported — a permanent local difference belongs in your values. An entry with an incomplete evidence chain carries a `break_glass` record (person, reason, timestamp) your verifier sees before you decide, and refusing all break-glass entries is a supported policy — that, like revocation and freshness, is enforced by the PreSync verify gate, which runs only if you installed with [`--verifier-image`](install#step-3-install). A release found defective after publication is marked **withdrawn** and stops being promotable; your pinned release keeps running.

Next: [Verify](verify) · [Support](support)
