Architecture
Updated 2026-08-29
Holodeck is a pool of pre-provisioned slots plus a control plane that resolves a source into a concrete set of service commits, renders Argo CD ApplicationSets, and applies them into per-slot namespaces.
Provisioning flow
You pick a source (branch, PR, commit SHA, or ticket pattern). Holodeck resolves the services, generates an ApplicationSet, and hands it to Argo CD, which reconciles the slot's namespaces to the desired state.
flowchart LR U["Engineer or Agent"] -->|"reserve PR / branch / SHA"| API["holo-api"] API --> J["Provisioning job"] J --> R["resolve_commits"] R --> I["inspect_commits"] I --> G["generate_applicationset"] G --> AP["apply_applicationset"] AP --> ARGO["Argo CD"] ARGO --> NS["Slot namespaces holodeck-1..N"] NS --> SVC["Services, DB, Firestore, Temporal, DNS"] SVC -->|"per-service URLs"| U
The provisioning job runs the four stages you can watch in the UI:
resolve_commits → inspect_commits → generate_applicationset → apply_applicationset.
Slot model
- Each slot maps to a pool identity (
holodeck-1…holodeck-N) with its own workload namespaces, databases/Firestore, Temporal namespaces, and identities. - Slots are pool-only: omit the slot to auto-pick a free one, or pass a specific slot number.
- 8 dev slots provide headroom; 2 staging slots cover QA handoff. Slots can be added by extending the pool.
Reservation lifecycle
A reservation moves through provisioning to healthy, and can be re-pointed at a new commit in place before it's released or its TTL expires.
stateDiagram-v2 [*] --> Reserved Reserved --> Provisioning: apply ApplicationSet Provisioning --> Healthy: all services green Provisioning --> Errored: job failed Errored --> Provisioning: diagnose + force cleanup + redeploy Healthy --> Provisioning: change version (replace) Healthy --> Released: release or TTL expires Errored --> Released: release Released --> [*]
When a slot is stuck
Don't start with kubectl. Open the slot's Argo tab and click
Diagnose — Holodeck reads the Argo deployment, warning events, and logs of
anything not coming up, and asks an LLM for a plain-language root cause and a
recommended fix. Re-clicking the same failure is served from cache (fast, no
extra cost).
If the diagnosis says something is wedged (e.g. an Application stuck
mid-delete), use Force cleanup in the same tab (tick force), then
deploy again. This Diagnose → Force cleanup → redeploy loop fixes the vast
majority of stuck slots.
Access & security
- UI is behind Google IAP; API is internal-only, reached via Teleport (
tsh vnet) or VPN. - Read tools (list/status/jobs/registry) are available to all builders.
- Write tools (reserve/replace/extend/release) require the SWAT Teleport role where
mcp.writeToolsis enabled. - Recovery (recycle/reset/cleanup) and registry writes are on the HTTP API, not MCP.