--manifests. Without it there are no delivered workloads to check and P2/P3 see only the bot profile — the reason a 4Gi postgres limit cleared a 2560Mi ceiling on 2026-09-06 and was refused at admission after a green install. install.sh renders the chart itself; run standalone, hand it a render.
PASS, WARN, FAIL or NOT EVALUATED with a remedy line; --json emits the same report machine-readably.
Exit 4 is the third answer, and it is not a verdict on your cluster. A namespace-scoped account cannot list nodes or StorageClasses; reporting that as
PASS claims something was verified and reporting it as FAIL claims a defect nobody observed. So those checks say NOT EVALUATED, name the read that was refused, and get their own exit code — sharing 0 with a clean run is how “four of these were never looked at” used to read as “your cluster is fine”. Turn them into answers with the snapshot handoff below. install.sh names them and continues.
- P1 · Taints and tolerations — workloads that cannot schedule sit Pending forever. Covers the dynamically spawned bot pods, which appear in no manifest.
- P2 · Resources vs LimitRange — a LimitRange silently defaults undeclared containers to 64Mi. Compares every declared request and limit, memory and cpu, against
maxandmin— the four pairs admission itself checks — and names the object and the number it would be refused on. Prints the ceiling it compared against, so a pass says what was true when it was taken. - P3 · ResourceQuota headroom — quota that cannot fit the declared totals refuses pods at the margin. Memory and cpu.
- P4 · Pod security admission — reads the effective admission: the PSA enforce level and the SCC annotations the namespace actually carries. OpenShift SCC
restricted-v2rejects explicit UIDs outside the namespace range; PodSecurityrestrictedneedsrunAsNonRoot, seccomp, capability drops. Names the workload that would be refused. A namespace enforcing neither isNOT EVALUATED, never a pass — a green obtained from the enforcement being absent is the one answer this check must not give. - P5 · NetworkPolicy reachability — default-deny egress with no DNS allowance, or no route to the registry. Static by default, which cannot prove a route; the live probe needs
--live-probes --registry-host. - P6 · Shared-memory sizing — the bot’s memory-backed
/dev/shmcounts against its memory limit; checks your LimitRange max and node capacity hold it. - P7 · Image pull (opt-in) — pulls a release image by digest with this namespace’s secrets; warm node caches hide broken credentials until the first new release. It creates a pod and needs the namespace’s image-pull Secret, which the install writes, so it runs only with
--live-probes --pull-test-image <ref>and belongs after the install rather than before it. - P8 · Storage — a default StorageClass exists if the delivered set carries volume claims.
- P9 · Version floor — Kubernetes is at or above the tested floor.
restricted compliant, so preflight works inside hardened namespaces.
Air-gapped clusters: dump on a connected workstation with cluster access, then analyse anywhere with --snapshot cluster.json. Live probes need cluster access; everything else works from the snapshot.
vexa_validate.py runs both in order and packages the receipts together.
Next: Install · Operations