These docs follow the main branch. The latest release is v0.1.0.
Acceptance of v0.1
This page checks v0.1 against the criteria of the framing letter of the
project (November 2026): its objectives, its use cases, the scope of the MVP,
its rules of good practice, and the gate of the release. Each criterion is
marked:
✅ met, with the proof;
⚠️ met differently, with the reason;
⏳ not met yet, with the issue that follows it.
Release checked:v0.1.0-rc.3 (commit 4192480), the release that
v0.1.0 is cut from. Date: 2026-11-10.
The script creates a fresh kind cluster (Kubernetes 1.37), installs the
release from its install.yaml, downloads and checks vesperctl, then runs
each check below and prints what it sees. It uses a kubeconfig of its own and
deletes the cluster at the end. It needs kind, kubectl, curl, jq, Docker and
the GitHub CLI. The public address over HTTPS needs a real server, and follows
Try Vesper on a server.
⚠️ image, port, replicas, env and TTL are fields; resource limits are set by the administrator with operator flags (--quota-*, --default-*), not per preview, so that a user cannot raise their own budget. Limits per team are planned with the policies of v0.4.
Controller: a namespace per environment, with a Deployment, a Service, HTTP access and a ResourceQuota
✅ plus a LimitRange and a NetworkPolicy; HTTP access through an Ingress with --preview-domain
⚠️ finalizer and TTL ✅; the objects of a preview are tracked by labels instead of owner references, because an owner reference cannot point to another namespace (ADR-0002); deleting the preview namespace deletes them
Readable status: conditions and Kubernetes events
✅ conditions Ready, Available, Expired with reasons, and events at each change
CLI vesperctl: create, list, get, extend, delete
✅ all five, with table, JSON and YAML output and documented exit codes (1 for a missing preview, 2 for a usage error)
Basic metrics exposed by the controller
✅ vesper_previews_active per phase and vesper_previews_expired_total; 401 without a token
Unit tests, envtest and an end-to-end test on kind
kubectl apply -f install.yaml rolls the operator out; it logs Starting Vesper {"version": "v0.1.0-rc.3"}; its image is pinned by digest
Release artifacts
the vesperctl archive passes its checksum and its attestation; the image passes its attestation, for linux/amd64 and linux/arm64, user 65532:65532
Create
Ready; the namespace holds the Deployment, Service, ResourceQuota, LimitRange and NetworkPolicy; the page answers through a port-forward
Validation
latest, a TTL of 30s and 6 replicas are refused by the API server, exit code 2, with a message naming the field
Pod Security
a privileged pod is refused: violates PodSecurity "restricted:latest"
Quota
a pod asking for 5Gi is refused: exceeded quota: preview
Network
from a preview: another preview blocked, the API server blocked, the internet reached
Update
a new image rolls out, the preview is Ready again
Extend
extended by 2h0m0s: ttl 3h0m0s
Expiry
a 1-minute preview and its namespace are gone
Delete
the preview and its namespace are gone
Status
vesperctl get shows the conditions and the events (NamespaceCreated, Provisioning, DeploymentAvailable)
CLI
list and get in table, JSON and YAML; exit 1 for a missing preview, 2 for an unknown output format
Metrics
401 without a token; with one, every phase and vesper_previews_expired_total 1 after the expiry
Cleanup
0 Vesper namespaces left
On a real server (#96,
with v0.1.0-rc.2, which differs from rc.3 by the events of vesperctl get
and docs): k3s on a VPS, a preview opened from a browser and a phone at its
public address, over HTTPS with a Let’s Encrypt wildcard certificate, and no
Secret in the preview namespace. That run found an isolation gap, fixed in
rc.2 (GHSA-m437-fj8p-6x8h).