Operator
A deployment is a custom resource; one operator reconciles it into the running workload. Developers edit the CR, not the cluster — and the same reconcile path renders deterministically for review before it ever applies.
Abstract
Lux deploys itself the way it finalizes blocks: a desired state is declared,
and a deterministic process makes the running state equal it. The desired
state is a custom resource — a LuxNetwork. The process is one operator.
Nobody hand-edits StatefulSets, Services, or Jobs; they edit the CR, and the
operator reconciles the rest.
Invariant
A deployment is a CR. One operator reconciles the CR into the full workload by one code path. A human changes the CR — never the reconciled objects — and the same path renders the result for review before it applies.
Why (first principles)
A cluster edited by hand has no source of truth. Two operators, or one
operator plus a human with kubectl, race: each overwrites the other and
the live state stops matching anything written down. The fix is the same one
consensus uses — make the result a value every party derives, not a place
anyone pokes. The CR is that value; the operator is the only writer.
One reconcile path is what makes "review then apply" honest. If the dry-run used a second renderer, the preview could differ from what ships — the review would be of a fiction. So the render command runs the real builder against a client that records instead of writes: the diff a reviewer sees is byte-identical to what the operator will apply.
Developers do not touch k8s directly because they do not need to and must
not. They state intent in the CR (and secrets via LP-7326, never inline);
the operator owns the namespace. The same binary reconciles under different
api-groups — lux.cloud, hanzo.ai, zoo.cloud — so one deployment
discipline serves every brand without per-cluster snowflakes.
Enforcement
One operator, one way. The command "reconciles the canonical lux.cloud/v1
Kinds directly … no compat shim, no child-CR materialization indirection";
the canonical Kind is LuxNetwork, "its reconciler turns the CR spec into
the full working resource set" — the validator StatefulSet, its Services,
the startup/genesis/staking wiring, and the platform Kinds
(operator/cmd/operator/main.go:1-19).
The reconcile is a single function. LuxNetworkReconciler.Reconcile loads
the CR and calls ReconcileLuxNetworkSpec — the one builder that turns spec
into objects (operator/internal/controller/network_lux.go:43-54).
Review reuses that exact path. operator render <ns> <name> runs
"the REAL reconcile builder (ReconcileLuxNetworkSpec) against a capturing
client that records the would-be server-side applies instead of writing
them," piped to kubectl diff "with ZERO cluster mutation … the safety gate
that runs before the operator is ever deployed to own the namespace." It
"deliberately reuses ReconcileLuxNetworkSpec … so the rendered objects are
byte-identical to what the live reconcile would apply. No second renderer to
drift out of sync" (operator/cmd/operator/render.go:17-39).
The same binary serves every brand: --api-group / OPERATOR_API_GROUP
deploys it under hanzo.ai, zoo.cloud, osage.cloud; --namespace
scopes reconciliation so a network is rolled out and validated in isolation
(devnet) before the identical path is staged to testnet and mainnet
(operator/cmd/operator/main.go:11-19).
Copyright
Copyright and related rights waived via CC0.