Skip to content

Intent, truth and reconciliation

This is the single most important idea in zone9. Almost every “why is the panel showing that?” question resolves here.

Intent is what you asked for. It lives in the control plane database and nowhere else: “this server should have 4 vCPU”, “this listener should serve app.example.com on port 443”, “this storage should have three nodes”.

Truth is what exists. It lives in the infrastructure: the VM configuration Proxmox actually has, the certificate the load balancer actually loaded, the nodes Kubernetes actually considers ready.

The panel is authoritative for intent. It is never authoritative for truth. It reads truth and reconciles toward intent.

Because a write that returns success is not a fact about the world. The hypervisor may have accepted a task that later failed. The VM may have been changed by an operator outside the panel — which is explicitly allowed, since one of the product’s promises is that a Proxmox operator can always take over. A network may have partitioned between the call and the effect.

A control plane that assumes its writes landed drifts silently. The drift is discovered by a customer, months later, as an outage.

So the rule is: write, then read back, then report what you read.

Resources carry two numbers rather than one flag:

  • an intent version, incremented every time you change something;
  • an applied version, reported by whatever actually did the work.

Equal means converged. Different means in flight. The panel says uygulanıyor (applying) versus uygulandı (applied) precisely because it knows the difference and declines to guess.

The same pattern appears with different words per product:

ProductIntentObserved
Serverdesired power state, planProxmox VM configuration and status
Load balancerlisteners, certificatesthe version each VM reports having loaded
Object storagebuckets, keys, layoutthe version each storage node reports
Kubernetesnode count, versionsnode readiness read from the cluster’s own API

Reconciliation is not continuous everywhere

Section titled “Reconciliation is not continuous everywhere”

An honest limitation, because it explains a class of stale readings.

Appliances reconcile continuously: a load balancer or storage node polls for its configuration every few seconds, so its reported state is at most seconds old.

Some resources are only measured when a job runs. Managed Kubernetes was the clearest example: cluster health was written at the end of the creation job and never revisited. If a precondition was broken during creation and you fixed it afterwards, the cluster worked but the panel kept showing the old verdict. The fix was to make measurement its own job — one that creates nothing, changes nothing, and only looks — triggered when you open the cluster page and by an explicit Yeniden doğrula (Re-verify) button.

The general shape to expect: if a status looks stale, there is a way to ask for a fresh measurement, and it is a separate action from repairing anything.

You can point zone9 at a Proxmox cluster that already has virtual machines. They appear as adopted resources — visible, attributable, but not fully managed, because the panel did not create them and does not know what they were supposed to be.

Adoption is the clearest demonstration of the principle: truth existed before intent, and the panel’s job is to describe it accurately rather than to pretend it created it.

If you are a user: a status that is not green is usually not an error. Read the state name. Applying means a job is running. Degraded means something was measured and found wanting, and the message says what.

If you are writing automation: never assume 202 Accepted changed the world, and never poll the resource when you can poll the job. See Asynchronous operations.

If you are an operator: you may change things in Proxmox directly. The panel will notice. Where your change conflicts with recorded intent, intent wins on the next reconciliation — so if you want a change to stick, make it through the panel.