Services & responsibilities
Kaizen runs as a set of cooperating processes. This page names each one, what it owns, and — just as importantly — what it deliberately does not.
The trusted core
api-backend
The core web and API process, and the only service that is fully trusted.
Owns: identity resolution from the platform envelope, permission enforcement, the retrieval pipeline (Search runs in-process), policy and budgets, the model gateway, the conversation journal, the audit trail, and the callbacks the agent runtime uses.
Does not own: the conversational loop. It never decides what the assistant should say next.
Serves HTTP on port 8000, with /healthz as the health contract. Depends on
PostgreSQL and the sandbox controller.
PostgreSQL
System of record. Conversations and journals, the search index and its vector columns, agents, prompts, Projects, documents metadata, tasks, occurrences, runs, traces, and audit records.
Also the schedule authority: database time selects due work, not a worker clock or a browser timer.
Runs a purpose-built image with text-search extensions. Port 5432.
Valkey
Ephemeral broker and lease store. Opaque Core run references, short-lived sandbox leases, presence and typing leases, queue state, and "the room head changed" hints.
Never carries schedules, definitions, member identity, workload assertions, proof keys, capabilities, one-use tokens, broker handles, or credentials. Losing Valkey degrades liveness; it does not lose durable truth. Configured without persistence for exactly that reason. Port 6379.
The loop
agent-runtime
The agent loop for Chat. Orchestrates a turn — calling tools, following up, compacting long context — and holds no secrets and no data of its own.
Everything consequential is a callback into the api-backend. Port 8090, depends on api-backend.
package-tool-runner
Runs packaged tools, which may include third-party code, in a separate, secretless environment — deliberately without the tokens or keys the trusted backend holds.
Same image as the runtime, different role. Port 8090 in its own network position.
Background work
background-worker
Runs ingestion plus fixed-cadence task due-claims, handoff repair, and opaque-ID task execution.
For delegated Tasks it holds the manifest's task-executor role. Before
entering the shared agent pipeline it presents a projected workload assertion
and fresh DPoP proof, atomically claims the Core run, and binds the returned
authority deadline and monotonic fence to the exact Kaizen occurrence/revision.
Every model, credential, or protected-resource operation then reserves and
consumes one exact Core effect. Sensitive authority remains non-serializable
process memory. Exposes metrics on port 9100. Depends on PostgreSQL and Valkey.
document-worker
The same worker image with a document-focused role, so a large ingestion batch cannot starve interactive task dispatch. Sized larger than the general worker (4 CPU / 4 GB versus 2 / 2) because extraction and embedding are the heaviest regular jobs.
The shared image dispatches both the general worker role and the dedicated
document_worker role through the headless worker entrypoint. Any unknown
process role fails at startup instead of silently becoming a web replica. The
document lane uses its separate queue where the deployment enables it.
Content handling
document-extractor
Turns uploaded documents — PDF, Office formats, and more — into text for indexing, including OCR for scanned pages. Port 9998.
Stateless and replaceable; a failure here delays indexing without affecting anything already indexed.
seaweedfs
The object store. Holds uploaded file bytes, exports, artifacts, and sandbox workspace snapshots. S3-compatible on port 8333.
Its availability matters at boot: the backend checks blob storage during startup, so a network policy that blocks it will hold the backend at not-ready rather than failing loudly.
Execution
sandbox-controller
Allocates and tracks sandbox instances, maintains the warm pool, and issues
leases. Port 8085, with /health as its contract. The api-backend depends on
it at startup.
sandbox-worker
Executes member code inside an isolated environment. Single-tenant while leased; wiped and returned to the pool afterwards, or discarded and replaced when the reset cannot be proven clean.
sandbox-egress-proxy
Mediates outbound network access from sandboxes. Egress is controlled rather than open and disabled by default. Read-only filesystem, minimal footprint (0.5 CPU / 128 MB). Port 8092 is declared as opaque TCP because it carries HTTP CONNECT tunnels; the service mesh must pass those tunnels to the proxy instead of applying its HTTP routing layer.
Presentation
frontend
Nginx serving the built Vite/React SPA. Read-only filesystem, its own healthcheck binary, and the smallest resource footprint in the topology (1 CPU / 512 MB limit).
Holds no state and no secrets. Every authorization decision it appears to make is re-made server-side.
What the split buys
| Concern | Where it lives | Why not elsewhere |
|---|---|---|
| Identity | api-backend | Single validation chokepoint; nothing else can mint a principal |
| Permissions | Inside the SQL query | Post-filtering in application code can leak through counts, facets, and errors |
| Policy & budgets | api-backend | Must apply regardless of how the loop behaves |
| Delegated workload consent and authority | Kamiwaza Core, enforced by api-backend and background-worker | Member and workload stay distinct; Kaizen stores only opaque correlation state |
| Conversational loop | agent-runtime | Needs to be flexible; must not be trusted |
| Third-party code | package-tool-runner | Must not be able to reach the trusted service's secrets |
| Member code | sandbox tier | Must not be able to reach anything |
| Schedule decisions | PostgreSQL | Worker clocks and browser timers drift and duplicate |
Resource shape
Every service declares limits and reservations. Defaults, per instance:
| Service | CPU limit | Memory limit |
|---|---|---|
| document-worker | 4 | 4 GB |
| postgres | 2 | 4 GB |
| api-backend, background-worker, agent-runtime, package-tool-runner, seaweedfs, document-extractor | 2 | 2 GB |
| sandbox-controller | 1 | 2 GB |
| valkey | 1 | 768 MB |
| sandbox-worker (live pods, sized by the sandbox controller) | 2 | 4 GiB |
| frontend | 1 | 512 MB |
| sandbox-egress-proxy | 0.5 | 128 MB |
See Requirements & capacity planning for sizing these against real member counts, and Scaling & performance for what to scale first.