Provenance & Lifecycle
The operator follows one decisive rule:
Never re-install what the user installed. Never uninstall what we don't own.
This page explains how that rule plays out for capability-operator installs and datastore instances, and how cleanup works on deletion and migration.
Two levels of provenance
1. Operator-install provenance
When a resource needs a capability operator (e.g. a managed PostgresCluster needs CloudNativePG), the operator's shared installer detects the current state before doing anything:
- Is there a Helm release with the expected name in the expected namespace?
- With the ownership label
app.kubernetes.io/managed-by=navique-ai-core-operatorand annotationcore.navique.com/provenance=owned→ Owned. - Without those labels → Adopted (you or another tool installed it).
- With the ownership label
- No release of ours, but the operator's CRDs exist and its controller is running anywhere in the cluster → Adopted.
- Nothing present → Absent.
The controller is matched by identity — its well-known labels, falling back to its container image repository — not by "is something running in the namespace we would have used". Two consequences worth knowing:
- An operator you installed in a different namespace (CNPG in
postgres-operatorrather thancnpg-system), or via OLM / raw manifests / a different release name, is adopted, not duplicated. These operators own cluster-scoped CRDs, so a second controller would fight the first over the same resources. - An unrelated workload that merely shares the expected namespace is not mistaken for the operator, so the operator still gets installed.
CRDs on their own are never enough: orphaned CRDs left by a previous uninstall count as Absent and are reinstalled.
The action follows from the state:
| State | Action |
|---|---|
| Absent | Install our standalone release, stamped with the ownership label/annotation |
| Adopted | Record the adoption; coexist; never manage its lifecycle |
| Owned | Already ours; optionally upgrade to the pinned version |
Because detection runs before any install, the operator never hits Helm's "CRD already owned by another release" conflict.
2. Datastore-instance provenance
The same principle one level down, via the mode field on datastore resources:
| Mode | Ownership |
|---|---|
managed | The operator creates, owns, and garbage-collects the datastore CR |
adopt | References a user-created datastore; never deleted or reconfigured |
external | A user-hosted datastore; only a connection secret is wired |
Lazy, ref-counted installs
Capability operators are installed lazily — a chart is installed only when a resource actually selects its managed mode. If every datastore is external or adopt, that operator is never installed.
Installs are ref-counted. The operator prefers to recompute the ref-count over persisting it: on each reconcile it lists the relevant resources and computes which still need a given dependency (any Gateway ⇒ litellm-operator; any managed PostgresCluster ⇒ cloudnative-pg; …). This survives operator restarts with no external bookkeeping.
Cleanup on deletion
Every resource has a finalizer. On delete, the controller:
- Deletes the emitted upstream CRs, or uninstalls the workload Helm release (for
ChatUI/MeilisearchInstance). - For each capability operator the resource required, decrements the ref-count and — only if the count reaches zero and the release is Owned — uninstalls it. Adopted and external releases are never touched.
- For managed datastores, deletes the operator-created datastore CR (not adopted ones).
- Removes the finalizer.
func Release(name, owner) error {
refcount.Remove(name, owner)
if refcount.Count(name) > 0 { return nil } // still needed
if detect(name) != Owned { return nil } // adopted/external — never touch
return helm.Uninstall(name) // only owned + unused
}Cleanup on migration
When a resource's mode, type, or references change, the operator diffs the old and new status and removes only the now-orphaned operator-owned resources. For example, switching a PostgresCluster from managed to external deletes the CNPG Cluster the operator created, then releases cloudnative-pg if no other consumer remains. Adopted and external resources are never deleted.
Install readiness — more than CRDs
"Ready" for a capability operator means its CRDs are Established AND all the chart's Deployments/StatefulSets are actually Ready — not just that the CRDs exist. An operator whose pod is wedged on a missing webhook certificate has established CRDs but cannot work, so the operator waits for real readiness.
Some charts have prerequisites. For instance the ClickHouse operator's webhook certificate is issued by cert-manager, so cert-manager is ensured to full readiness first. The operator treats cert-manager as a universal prerequisite and keeps webhooks and leader election enabled (production-faithful) rather than disabling them.
Auditability
Resource status surfaces the bundled chart versions and the provenance state (owned / adopted) so you can audit exactly what the operator installed versus adopted. The operator also records Events for adoptions, license-gated skips, instance-cap refusals, expiry downgrades, and garbage-collection actions. See Troubleshooting.