Control plane and Run reconciliation

How the operator turns a declarative Run into an execution Job, and why the control plane stays separate from model work.

Why a Kubernetes control plane?

GitOps can review Agent, Tool, and Run definitions; namespaces and RBAC provide a known administrative surface. The operator owns reconciliation and scheduling rather than running inference inside the controller process. This keeps restarts and Job failures observable through standard Kubernetes resources. Kubernetes RBAC controls resource access but does not automatically implement application-level tenant isolation inside tools or model endpoints.

Reconciliation path

  • RunReconciler retrieves the Run and looks for a same-namespace execution Job named with the run name plus -exec.
  • When no Job exists, it checks concurrency in the namespace; pending work may be marked Queued.
  • For an Agent target it resolves Agent, ModelEndpoint, Tool, MCPServer, and optional Skill references; run-level model overrides take precedence over Agent defaults.
  • It serializes resolved input, model URL/name, prompt, selected tool details, and skill fields into an ExecutionContract passed to the Job via KAIGENTS_EXECUTION_CONTRACT.
  • It creates a runner Job with an owner reference, selected service account and node selector. Reconciliation reflects Job phase into Run status; a successful Job can write outputs via a same-namespace ConfigMap.

What to inspect when it stalls

A Queued Run indicates scheduling pressure, not necessarily a model error. A Job that cannot pull its runner image cannot contact a model. Check Job events and status before investigating inference, and keep execution-contract environment data out of public bug reports because it can contain prompts and inputs.

kubectl get run first-run -n kaigents -o yaml
kubectl get jobs -n kaigents -l core.kaigents.io/run=first-run
kubectl get pods -n kaigents -l core.kaigents.io/run=first-run
kubectl describe job first-run-exec -n kaigents

The schema is part of the contract

The source operator defines fields not shipped in the current Helm chart, including Skill references. The installed CRD controls what kubectl accepts. For example, source RunReconciler has a Process branch but the chart Run target enum allows only Agent and Team. Operator code existing does not make a resource shape deployable. Source: operator/internal/controllers/run_controller.go, operator/internal/controllers/execution_contract.go, charts/kaigents-operator/crds.

Operational trade-offs

One Job per Run gives Kubernetes-native isolation and lifecycle visibility, but increases pod startup overhead and depends on a working cluster and image registry. A Job can retry or be recreated while an external side effect has already happened; put idempotency and explicit authorization at each tool boundary.