Two paths in this workflow wrote to zoo-k8s directly. `deploy-single` ran
kubectl apply -k over one namespace's overlay; `deploy-all` ran a script that
applied the CRDs, applied the whole overlay, and then hand-patched luxd flags
onto a StatefulSet the Rust operator renders -- a patch whose own comment
explains it persists because the operator does not re-render an existing pod
template.
That is a second writer for objects zoo-fleet declares from deploy/*/*.yaml,
and the disagreement is not quiet. Both stamp the pod template
(app.kubernetes.io/managed-by: hanzo-operator vs Helm), and a pod-template
label is not a field two controllers can differ about without a restart, so
each flip rolls the workload. It does not converge; it oscillates.
It also applied the WRONG THING. k8s/ is the hand-applied tree whose currency
deploy/README.md says outright is unknown -- some of it ahead of the cluster,
some behind, some describing objects that were deleted. A pipeline that applies
it on every push re-asserts that drift on a schedule.
What is left writes to git and tests: record the pin, open the PR, run E2E.
zoo-fleet reconciles from the merged file. The kubectl calls still in the E2E
job read pods, events and logs on failure, and write nothing.
The k8s/ tree stays, for what deploy/ deliberately does not cover -- CRDs,
namespaces, the operator's custom resources. `make k8s-apply env=<env>` is that
path, with a human behind it.
deploy-all and e2e-only meant the same thing once neither deployed, so the
modes are now the two acts that remain: pin and e2e.
Co-authored-by: Hanzo Dev <[email protected]>