Architecture
ai-agent-subsystem is built as a single dub monorepo: reusable code lives in a shared library and
the executables are thin layers on top, all under packages/. It produces three binaries and
one shared library.
flowchart TB
subgraph MONO["D monorepo (dub)"]
direction TB
CORE[["agentcore<br/>shared library"]]
CTRL["controller<br/>binary"]
INIT["initializer<br/>binary"]
SUP["supervisor<br/>binary"]
CORE --> CTRL
CORE --> INIT
CORE --> SUP
end
CTRL <-->|watch / create / patch| K8S[("Kubernetes API")]
INIT -->|init container, prepares| POD["Agent Pod"]
SUP -->|runs as PID 1 inside| POD
STATIC["statically linked with LDC, no runtime deps"] -.-> CTRL
STATIC -.-> INIT
STATIC -.-> SUP
Components
Section titled “Components”agentcore: shared library
Section titled “agentcore: shared library”The pure core, with no process of its own:
- CRD type definitions (
AgentDefinition,Station,Agent). - A Kubernetes REST + watch client.
- The pure reconcile state machine (I/O injected, so it is unit-testable).
- Prompt templating.
- The Job builder.
controller: binary 1
Section titled “controller: binary 1”The operator. It watches Agent resources, resolves each one’s Station and AgentDefinition,
builds and creates a Job, polls the Job’s outcome, and patches the Agent’s status. It also
prunes old runs beyond the Station’s history limits, and exposes /healthz (liveness), /readyz
(readiness), plus a Prometheus /metrics endpoint (reconcile counts and latency, agents by phase,
watch reconnects, Kubernetes API latency, and leader status).
It combines a low-latency watch with a ~15s poll over one shared in-memory cache, so reconcile work is O(changed) and a dropped watch event is still caught by the next poll. Two replicas run with Lease-based leader election, so only the leader reconciles. See Watch + poll + cache and leader election for the mechanics.
initializer: binary 2
Section titled “initializer: binary 2”Runs as the Pod’s init container, before the supervisor. It provisions the agent’s environment
from what the recipe declares: cloning the resources.repos into the workspace and installing the
agent CLI (e.g. Claude via the official installer), self-bootstrapping any missing prerequisites
(git, curl, sha256sum) through the distro’s package manager first, and reporting its lifecycle to the
same output sinks as the agent. New provisioning tools and distros are added behind the Tool and
PackageManager interfaces. See Agent runtime for the full model.
supervisor: binary 3
Section titled “supervisor: binary 3”Runs inside the Job Pod as the entrypoint. It launches the agent process, streams its stream-json
output line by line to the configured sinks, forwards termination signals for graceful shutdown,
and exits with the agent’s exit code.
Static linking
Section titled “Static linking”All three binaries are compiled with LDC with the D runtime linked statically, so they ship as self-contained executables with no language runtime to install. The initializer and supervisor can be injected into any glibc-based Station image, and run unchanged across the common Kubernetes base distros (Debian, Ubuntu, RHEL-family, Amazon Linux, Alpine). See Building for the dub configuration and link flags.
Kubernetes as the control plane
Section titled “Kubernetes as the control plane”There is no external database. The controller’s entire state is the set of Agent resources and
their status. This keeps the system observable with plain kubectl and recoverable after a
restart: on startup the controller simply lists Agents and reconciles whatever it finds.