Platform architecture
The system boundary is simple to state: a Python control plane orchestrates versioned agents; everything an agent touches — models, tools, data, side effects — passes through a governed seam. This page is the short version; the exhaustive reference lives in docs/PLATFORM-ARCHITECTURE.md.
Big picture
Components
| Component | Role |
|---|---|
| API control plane | FastAPI services for the ALM pipeline, webhooks, chat, sandboxes, evaluations, and registry publishing. A separate SRE server runs the monitoring loop. |
| LangGraph orchestration | The ALM pipeline is a 14-node graph (ingest → plan → implement → review ⇄ security gate → build → test → provision → release) with bounded loops, checkpointing, and per-node timeouts. The SRE loop is a 5-node graph on a cron schedule. |
| Temporal | Durable execution for the agent lifecycle: sandbox creation, evaluation runs, and gated publication run as workflows with encrypted payloads and worker-deployment versioning, so restarts and deploys don't strand work. |
| Agent Registry | The system of record for versioned artifacts: agents, blueprints, skills, datasets, evaluation suites. Publication goes through an evaluation gate; built-ins arrive via GitOps seeds. |
| AgentGateway | The mandatory LLM seam. Sandboxes and pipeline stages never hold provider credentials; the gateway enforces policy, attributes usage to the owning principal, and records cost per run. |
| MCP Hub | Resolves the MCP tool servers an agent's composition declares, so tool access is part of the reviewed record rather than ambient capability. |
| A2A bus | Agent-to-agent messaging (request/response, notification, handoff, escalation, broadcast) persisted to Redis and PostgreSQL, so multi-agent runs are auditable. |
| Dashboards | Next.js apps: ALM (runs, agents, approvals, evaluations, compare) and SRE (cluster overview, incidents, scan history), behind Keycloak session auth. |
Execution paths for an agent run
When something needs to invoke an agent, the runtime picks a path by what the record is:
| Path | When | What happens |
|---|---|---|
| Inline (draft) | An unpublished draft pinned to a sandbox | The draft envelope itself is the spec; it runs in-process inside the sandbox boundary. This is the author's fast feedback loop. |
| Governed Job | A published registry agent | The runner performs a fresh registry composition resolution, verifies gateway configuration, and dispatches an ephemeral Kubernetes Job with the sandbox boundary applied. Any resolution miss fails closed. |
| Substrate agent | A labelled long-lived agent | Reached over A2A through its own control plane instead of spawning a Job; opt-in per agent. |
Backing services
| Service | What it holds |
|---|---|
| PostgreSQL + pgvector | Pipeline runs, agent executions, A2A messages, evaluation results, traces, audit log, and semantic memory vectors. |
| Redis | Hot state, locks, sessions, pub/sub, and the memory cache. |
| NATS JetStream | Async event distribution. |
| Object storage | Evaluation artifacts and run evidence. |
The adapter rule
Every external system — database, cache, memory, vector store, queue, event bus, object store, secrets, telemetry, LLM provider, SCM, ticketing — is reached through an adapter family with one abstract interface, one file per backend, lazy SDK imports, and a mandatory no-op fallback. A configuration change swaps a backend; business logic never imports a vendor SDK. The factory never raises: an unknown or unconfigured provider degrades to the no-op instead of crashing the pod.
Security posture
- Owner scoping. Sandboxes, traces, evaluation runs, and connectors belong to the signed-in principal; a publication gate refuses evidence owned by anyone else.
- No credential mounting. Provider keys live in the control plane; sandboxes reach models only through AgentGateway.
- Side-effect boundaries. Tool calls default to mock or block in sandboxes; real calls are an explicit, recorded choice.
- Image allow-listing. Job images from authored records are validated against trusted prefixes; a rejected override downgrades to a safe default, never escalates.
- Fail-closed governance. If the registry, gateway, or composition can't be verified, dispatch fails rather than running ungoverned.