How it works

Control-plane architecture

A central server describes the desired state; agents bring hosts to it. Between them sits an honest reconcile loop and a single transport that works in both pull and push.

Operatorweb UI · soulctl · MCP · OpenAPI
KEEPERstateless clusterrenders Destiny · RBAC · audit · registries · web UI
soulagent on the hoststatic Go binary · applies the Destiny
PostgreSQLdurable state
Redishot: presence · lease · heartbeat
Vaultsecrets (masked on output)

Keeper — a brain with no state on disk

Keeper holds the registries (services, coven labels, RBAC), renders Destiny from Essence, plans incarnations and keeps the audit trail. All state lives in shared PostgreSQL and Redis, not on the instance disk, so any Keeper can serve any request: the cluster scales horizontally and survives a lost node with no shared storage.

Soul — an agent you barely notice

A managed host runs a single static Go binary. It receives the rendered Destiny, compares the host’s current state with the desired one and changes only what drifted. No interpreter alongside it: core modules are compiled in, custom ones attach as plugin processes over gRPC-stdio.

Reconcile — not “run”, but “converge to a state”

Every Destiny step is idempotent: the module first reads the fact, then changes the host only if the state differs. The step yields changed=true (changed) or changed=false (already so). That signal wires steps together: “restart the service only if the config changed”.

One transport, two delivery models

The Keeper↔Soul channel is gRPC over mTLS. In the pull model an agent daemon holds the connection and applies the Destiny itself. In the push model the same binary runs one-shot over SSH — with no resident agent on the host. One module set, one reconcile implementation.

Data — hot and cold kept apart

PostgreSQL keeps durable state (incarnations, runs, RBAC snapshots). Redis holds the volatile and hot: presence, heartbeat, leases, pub/sub. Secrets live in Vault and resolve at render time, masked on output. Splitting hot from cold is what keeps the 100k+ host target within reach.

Three layers: Service → Incarnation → Destiny

ServiceWhat the service is and what it is built from — versions, modules, the parameter contract.
IncarnationA concrete embodiment of a service across hosts — the thing that gets provisioned and reconciled.
DestinyA host’s desired state: module steps rendered from Essence in strict mode.