# Sveltos environment rollout

> This example now lives at
> [confighub/sveltos-confighub](https://github.com/confighub/sveltos-confighub).
> This copy is a frozen mirror; new work, live recordings, and issues belong
> in that repository.

One reviewed values change moves from pilot to staging to production, and
every wave is approved on its own before any cluster sees it. This chapter
is recorded live.

[Sveltos](https://projectsveltos.io) selects the clusters and installs the
add-on; ConfigHub holds the reviewed record, gates it, and publishes the
approved revision as an OCI image that Sveltos fetches. The run pinned
Sveltos v1.13.0 and used the addon controller build that decompresses
gzipped layers, which the ConfigHub gateway serves.

## Why this chapter exists

Promoting a change through environments is the operation every platform team
does and few can evidence. The claim here is not that configuration reached
the clusters. It is that nothing reached any cluster except a revision a
named person approved, and that the other environments held their state
while one moved.

## See the result

The [matrix](../../../data/sveltos-env-rollout/matrix.md) shows which cluster
ran which revision at four checkpoints: the baseline, then after each wave.
The [receipt](../../../runs/sveltos-env-rollout-proof/receipt.yaml) records
six approval brackets, the release digest per wave, the gateway reference
per environment, and the controller image that read them.

## How it works

The reviewed `ClusterProfile` for each environment lives in its own
ConfigHub Space with an approval gate. Approving a revision publishes it to
the ConfigHub OCI gateway. One bootstrap profile per environment points
Sveltos at that Space's gateway reference, and Sveltos fetches it and sends
the reviewed profile to the clusters matching that environment label.

Promotion never touches the bootstrap profile. Publishing the approved
release moves the tag, and the fleet follows on its interval.

## The design

The reference fleet is one management cluster and four workload clusters. The
[fleet design](fleet.yaml) labels one cluster `environment=pilot`, one
`environment=staging`, and two `environment=prod`.

Each environment keeps its own governed record: a `ClusterProfile` that selects
only its environment label, stored in its own ConfigHub Space with the same
approval policy the earlier chapters used. The three profiles start from one
shared baseline values document, so the only reviewed difference between
environments is the selector.

The [change candidate](change-candidate.yaml) is one values edit: it raises
`backgroundController.replicas` from 1 to 2 in the Kyverno 3.8.1 chart. The
change lands in the pilot record first. After the pilot converges, the same
reviewed content is promoted to the staging record, then to the production
record. Version bumps are deliberately out of scope here; they belong to the
CVE patching chapter.

## The matrix

The per-cluster matrix shows exactly which cluster runs which revision at four
checkpoints: the baseline and the state after each wave. It follows the Kubara
matrix discipline: expected evidence comes from the reviewed files, observed
evidence only ever comes from a live run, and empty cells stay empty until a
run earns them.

- [matrix.csv](../../../data/sveltos-env-rollout/matrix.csv)
- [matrix.md](../../../data/sveltos-env-rollout/matrix.md)
- [matrix.html](../../../data/sveltos-env-rollout/matrix.html)

## Current status

Recorded live. The receipt at
[runs/sveltos-env-rollout-proof/receipt.yaml](../../../runs/sveltos-env-rollout-proof/receipt.yaml)
holds six approval brackets across the three environments, a distinct
release digest per wave, the gateway reference per environment, and the
addon controller image the run used. The matrix generator fills the observed
columns from that receipt, so every cell in the matrix is an observation
rather than an expectation.

Before it builds anything the runner probes the approval gate on a throwaway
Space and Unit, so a wiring problem refuses in seconds instead of failing
after the fleet build. Its self-test proves the same governance walk offline
against fake ConfigHub and cluster surfaces, with no account or cluster.

## Chapter four

The [CVE patching example](../cve-patch/README.md) continues from this
chapter's outcome: one reviewed chart version bump with digest-bound
provenance, promoted through the same environment groups, closed by a
coverage audit that proves no cluster was missed.

## Repeat and verify

```bash
# Rebuild the matrix surfaces from the reviewed example files. A few seconds.
node scripts/generate-sveltos-env-rollout.mjs --generate

# Verify the committed surfaces and the example invariants.
npm run sveltos-env-rollout:verify

# Deterministic self-test: fixture compile, tamper refusals, and the
# self-contained HTML contract. No account, cluster, or network access.
npm run sveltos-env-rollout:self-test

# Deterministic self-test of the drafted live runner: the gate preflight,
# all six approval brackets, and the receipt tamper battery, against fake
# ConfigHub and OCI surfaces. A few seconds.
npm run sveltos-env-rollout-proof:self-test
```

The live proof follows the two-wave runner's discipline: a self-contained
kind fleet, one approval bracket per environment revision, each approved
revision published as an OCI image that Sveltos fetches itself, Sveltos
convergence per environment group, and a convergence audit at the end. Fleet
proofs run serially against the organization, never in parallel.

Confirm the approval wiring first. The probe wires one throwaway Space,
creates one probe Unit, watches for the approval gate, and cleans up after
itself:

```bash
CUB_CONTEXT=my-policy npm run sveltos-gate:probe
```

Then record the run. One authenticated context is enough, because no cluster
Spaces are created:

```bash
HELM_EXPT_ALLOW_LIVE_SVELTOS_ENV_ROLLOUT=1 \
CUB_CONTEXT=my-policy \
SVELTOS_ADDON_CONTROLLER_IMAGE=docker.io/projectsveltos/addon-controller:v1.13.0-ch \
npm run sveltos-env-rollout-proof:run

# Then refresh the summary and the observed matrix columns.
npm run sveltos-env-rollout-proof:generate
npm run sveltos-env-rollout:generate
```
