Concepts
The mental model behind pond. Five minutes here makes every guide easier.
The shape
- Pond is the trusted control plane + engine. It decides what work exists and hands it out; it never executes untrusted agent code itself.
- Your app is a consumer. It submits runs and reads status over
/v1. Pond is product-neutral — it doesn’t know what a “project” means to you. - Workers actually run the agents, in a sandbox, on whatever machines you attach. They poll pond for work (pond never dials out to them).
What you deploy
Three kinds of process. You always run the first; you add a pool only for agent
(swarm) stages.
| # | Process | Command | Where | How many |
|---|---|---|---|---|
| 1 | Control plane + Postgres | uvicorn app.main:app (+ a Postgres) | your trusted infra | one deployment (scale the API horizontally; one database) |
| 2 | Orchestrator | swarm.py serve | your infra, or a tenant’s | one per worker pool |
| 3 | Worker | swarm.py worker | anywhere — your infra, a tenant’s, BYO | as many as you want per pool |
One rule makes the topology easy: every connection dials inward. The consumer calls pond; the orchestrator polls pond; workers poll their orchestrator. Pond never opens a connection outward to a pool, and the orchestrator never dials a worker. So a pool can sit behind NAT, in another VPC, or on a machine you don’t own — it just needs outbound HTTPS to the thing above it. (A worker also runs a tiny broker sidecar in-process for secrets — not a separate deployment; see secrets.)
Smallest useful deployment is just #1 — control plane + Postgres. noop,
builtin, and shell stages run in-process, so you can do real work with no
pool at all. Add an orchestrator + workers (#2, #3) the moment you want swarm
(AI-agent) stages. You can run several pools at once (e.g. a trusted in-house
pool plus per-tenant BYO pools) — each is one orchestrator and its workers.
Runs, stages, workflows
- A workflow is a list of stages — the steps an agent run walks (fetch the source, map the repo, run an agent over each area, …). You pass the workflow definition inline when you submit; pond doesn’t store your workflows, so a run is fully reproducible from its own snapshot.
- A run is one execution of a workflow. It has stages with status + logs, an optional source bundle, usage/cost, and (for pooled runs) a signed result attestation.
Executors — where a stage runs
Each stage names an executor. Two families:
| Executor | Runs | Needs a worker pool? |
|---|---|---|
noop | nothing (a placeholder / delay) | no |
builtin | in-process Python in pond (e.g. file inventory, TODO scan) | no |
shell | a subprocess on the pond host | no |
swarm | an AI agent (claude/codex/…) in a sandbox | yes |
So you can run useful workflows (builtins, shell tools) with no pool at all.
You only need workers for swarm (agent) stages — that’s where untrusted code +
the model + real isolation come in.
Workers & the pool
A worker is a process that claims agent jobs and runs them in a sandbox. An orchestrator fronts a set of workers and polls pond on their behalf. Workers can live anywhere — pond’s own pool, or a third party’s machine.
Two routing axes decide which worker gets a job:
- tags (subset match) — where a job may run:
pool:trusted,pool:byo,tenant:<id>,repo:acme. - capabilities (glob match) — what a worker can do:
harness.codex,sandbox.firecracker.
See worker-pool.
Sandbox profiles — how a run is contained
An agent stage declares a profile that fixes its isolation posture:
| Profile | Filesystem | Network | For |
|---|---|---|---|
none | host | open | local dev only |
untrusted-code-read | read-only checkout | model API only | analysis |
untrusted-code-write | throwaway writable copy | default-deny allowlist | the full harness: edit, build, test, pip/npm install |
The confined profiles drop privileges, cap resources, and route the agent’s egress through a proxy that allows only the model API + package registries + the repo’s git remote. The isolation backend is swappable — a container, gVisor, or a Firecracker microVM — without changing the image. See sandboxing.
Trust tiers — running on machines you don’t own
A stage can require a tier: trusted (pond’s pool, the default for untrusted
code) or byo (bring-your-own / untrusted host, single-tenant only). Pond
fail-closes: untrusted code never lands on an unpinned pool by accident, and a
byo run only reaches a worker tagged for its tenant. Results from a worker come
back signed so pond can verify the worker actually produced them. See
trust-and-byo.
How secrets stay safe
The model API key never reaches the agent. Pond seals each credential to the specific claiming worker’s key, and the worker runs a broker sidecar that holds the real key and injects it on the way to the model — the agent’s environment only ever has a dummy + a broker URL. Source code travels as an encrypted bundle decryptable only by the claiming worker. See model-credentials and worker-source-delivery.
Ready: Quickstart →