usage: vexa-validate [-h] [--namespace NAMESPACE] [--kubeconfig KUBECONFIG]
[--customer-values CUSTOMER_VALUES] [--contract CONTRACT]
[--provider PROVIDER] [--out OUT] [--manifests MANIFESTS] [--station STATION]
[--live-probes] [--install] [--registry REGISTRY] [--channel CHANNEL]
[--channel-pubkey CHANNEL_PUBKEY] [--install-arg INSTALL_ARG]
[--release-prefix RELEASE_PREFIX] [--flows] [--flows-key FLOWS_KEY]
[--admin-token ADMIN_TOKEN] [--meeting-url MEETING_URL]
[--operator-email OPERATOR_EMAIL] [--admit-timeout ADMIT_TIMEOUT]
[--min-segments MIN_SEGMENTS] [--non-interactive] [--verify-redaction]
[--no-verify-redaction] [--submit] [--submit-destination SUBMIT_DESTINATION]
[--submit-tag SUBMIT_TAG] [--submit-dry-run] [--submit-plain-http]
[--submit-insecure] [--continue-on-fail] [--report] [--export-diagnostics]
[--app APP] [--pin PIN] [--entry-seq ENTRY_SEQ] [--entry-digest ENTRY_DIGEST]
[--chart-version CHART_VERSION] [--chart-digest CHART_DIGEST]
[--window-hours WINDOW_HOURS] [--namespace-scoped]
vexa-validate — one command that takes an operator from "is this cluster ready"
to "here is my signed-off evidence, and here is my contribution back".
It chains the two tools that already exist and adds the thing neither produces:
a portable, secret-free record of the station as it actually stands.
preflight (will it run here) -> the preflight verdict, verbatim
install (optional, --install) -> the install log
smoke (did it work here) -> the smoke verdict and its console
report -> station-report.yaml
ONE FILE, AND THAT IS THE DESIGN. `station-report.yaml`. Not a directory, not
an archive, nothing to extract. The person who has to approve this before it
leaves their perimeter must read ALL of it, and six files in a tarball is a
review task where one commented document is a read. This one goes back on
every release rather than once, so the cost of a document nobody reads
compounds. YAML because the reader is a Kubernetes engineer who reads it all
day, and because it carries comments — so the explanation of each section sits
above the section instead of in a second document that can drift from it.
WHAT IS IN IT, and the list is complete:
1. PROFILE the provider profile this run used, verbatim — substrate
facts (k8s version, storage class, PSA mode, mirror host),
never credentials
2. VALUES the operator's own values file, structurally intact, with
every secret-looking value replaced by REDACTED. The SHAPE
is the contribution
3. CONTRACT the contract this environment verifies against, verbatim,
beside its id and sha256 — the document states the policy
it was produced under
4. PREFLIGHT the P-check receipt, verbatim
5. SMOKE the smoke receipt, and the raw console TAIL — evidence of a
crash is still evidence, and it is the half a receipt never
gets to write
6. THE MANIFEST station identity, section digests, kit revision, phase
verdicts and the redaction verdict, as top-level keys
It carries no credentials, and `--verify-redaction` (on by default) refuses to
finish if any plaintext value that redaction removed still appears anywhere in
the finished file — the check reads the bytes that would be sent, not the
values we believe we assembled.
ABSENT OVER ZERO. A section that could not be produced is recorded as absent
with a reason, never as an empty string: an empty receipt in a document whose
whole purpose is to say what happened is worse than a stated gap.
Naming note: the *station bundle* on the channel (ADR-0007) is the machinery
chart Vexa publishes INTO a cluster. `station-report.yaml` is the return leg —
the operator's station record travelling the other way. Different direction,
different artifact, and now different words for each.
Run on the operator's machine with kubectl access:
python3 kit/validate/vexa_validate.py --namespace vexa-staging --customer-values my-values.yaml --flows [--meeting-url URL | --non-interactive]
Exit codes: 0 all phases passed · 1 a phase failed · 2 usage · 3 redaction leak
(the file is kept so it can be inspected, and it must not be sent).
options:
-h, --help show this help message and exit
--namespace NAMESPACE
--kubeconfig KUBECONFIG
--customer-values CUSTOMER_VALUES
the values file you edit and keep; redacted into the report. Required for
a validation run; a --report or --export-diagnostics run carries no values
file and does not take one.
--contract CONTRACT contract this environment verifies against (default
kit/verify/policy.example.yaml)
--provider PROVIDER provider profile name under kit/providers/
--out OUT directory to write station-report.yaml into (default: here)
--manifests MANIFESTS
--station STATION station name recorded in station.json; the publisher's ingest --station
must match it (default: the namespace)
--live-probes
--install also run kit/install.sh between preflight and smoke
--registry REGISTRY
--channel CHANNEL
--channel-pubkey CHANNEL_PUBKEY
--install-arg INSTALL_ARG
extra argument passed verbatim to install.sh (repeatable)
--release-prefix RELEASE_PREFIX
--flows
--flows-key FLOWS_KEY
--admin-token ADMIN_TOKEN
--meeting-url MEETING_URL
--operator-email OPERATOR_EMAIL
--admit-timeout ADMIT_TIMEOUT
--min-segments MIN_SEGMENTS
--non-interactive
--verify-redaction refuse to finish if a redacted value survives (default)
--no-verify-redaction
--submit after bundling, validate the report against report.v1 and your contract's
report_scope, then push it to the channel host you already pull from.
Explicit command only: nothing sends on its own.
--submit-destination SUBMIT_DESTINATION
registry host; default report_scope.destination, then --registry
--submit-tag SUBMIT_TAG
the tag this report is pushed under; default today's UTC date
--submit-dry-run validate and print the payload; send nothing
--submit-plain-http
--submit-insecure
--continue-on-fail write the report even if a phase FAILs (a failing run is still evidence —
and often the most useful kind to send)
--report TELEMETRY MODE: skip the phases and emit a ladder submission at the tier
your contract's report_scope declares (T1 receipts / T2 health / T3
usage). Collectors above the declared tier are never called. Combine with
--submit to send it.
--export-diagnostics TIER 4: write a scrubbed diagnostics bundle to a local directory and stop.
Nothing is sent — there is no --submit path for tier 4; your admin reads
the bundle and shares it per incident.
--app APP the Argo CD Application name this station follows (T1)
--pin PIN the position that Application follows (T1); read from the Application when
it can be, this is the fallback
--entry-seq ENTRY_SEQ
channel entry sequence the pin resolves to (T1)
--entry-digest ENTRY_DIGEST
channel entry digest the pin resolves to (T1)
--chart-version CHART_VERSION
chart version running (T1)
--chart-digest CHART_DIGEST
chart digest running (T1)
--window-hours WINDOW_HOURS
how much time the T2/T3 counters cover (default 24)
--namespace-scoped this station has no cluster-scoped read; node counters are reported absent
rather than collected