Codewhale cloud-agent snapshot
The sandbox a /dispatch run launches from is a Daytona snapshot
built from this directory's Dockerfile, with the codewhale CLI
preinstalled. Daytona's create-sandbox API launches from snapshots — a
raw image is only ever a snapshot-build input — so "snapshot" is the
correct and only restorable artifact class here.
Why this exists (founder decision, 2026-08-29): the created sandbox must
run codewhale exec --auto itself, authenticated as the dispatching
account, resolving the account's configured model — dispatch → sandbox
(own codewhale) → account identity → forge PR. The account identity is
injected at create time as the CODEWHALE_API_KEY env var (a
cwc_key_… machine token); no provider API key ever widens into the
sandbox (BYOK stays local).
Build the snapshot (operator, once per codewhale rev)
daytona snapshot create codewhale-cloud-agent \
--dockerfile ./Dockerfile \
--cpu 2 --memory 4
- The default name
codewhale-cloud-agentmatchesDEFAULT_CLOUD_AGENT_SNAPSHOTincrates/tui/src/cloud_dispatch.rs; a different name is set per host withCODEWHALE_DISPATCH_SNAPSHOT(slug charset, ≤64 chars — an invalid override falls back to the default). - Pin a rev with
--build-arg CODEWHALE_GIT_REV=<sha>when the default moves past the rev you verified. - Daytona snapshots deactivate after two weeks of disuse; reactivate before reuse or create fails.
- Resource sizing: the harness declares a one-hour turn budget; 2 vCPU / 4 GB is the floor the offline tests assume.
What the create call sends
LiveDaytonaLauncher::create_sandbox POSTs to the provider's sandbox
endpoint with:
{
"name": "cw-<job-id>",
"snapshot": "codewhale-cloud-agent",
"env": { "CODEWHALE_API_KEY": "<account machine token>" },
"labels": { "codewhale.job": "<id>", "codewhale.forge": "<forge>", "codewhale.product": "dispatch" }
}
Labels are applied via the provider's dedicated labels endpoint right after create (Daytona does not apply create-body labels); a labels failure tears the fresh sandbox down and fails the create truthfully — an unlabeled sandbox is spend the orphan reconciler can never find.
Machine tokens
Minted from the web app (Account → API keys) or the CLI's cloud
api-key surface; cwc_key_-prefixed, read-mostly scopes, revocable
server-side. A confirmed dispatch without one refuses before any spend:
the sandbox's codewhale would have no identity to run as.