返回 CodeWhale
README.md
1 # `codewhale-cloud-agent` — Daytona Computer snapshot
2
3 This directory is the product-owned definition of the Daytona snapshot that a
4 Cloud Agent acquires as its Computer (PRODUCT_PRD §4.5). The Codewhale Engine
5 is the sole runtime inside the Computer and is installed as a commit- and
6 digest-pinned Linux binary; nothing else in the image runs agent logic.
7
8 ## What the image is
9
10 - Base: `debian:bookworm-slim` (linux/amd64 — Daytona builds amd64 only).
11 - Engine: released `codewhale-linux-x64` from GitHub release `v0.9.11`,
12 fetched by exact URL and verified against the release checksum before
13 install:
14 - commit `96d13a0bc3f40280ea3865280ad5ccf0e2845e6f` (tag `v0.9.11`)
15 - sha256 `c02969556e51e138afa3fe9c97a1359878cd3d1986b1ce1f5fa96c93c6909416`
16 - static musl build (no glibc floor), installed at `/usr/local/bin/codewhale`
17 with a `codew` symlink; the build fails if `codewhale --version` does not
18 print `codewhale 0.9.11 (96d13a0bc3f4)`.
19 - Toolchain for agent work: git, curl, CA roots, ripgrep, procps, python3
20 (+pip, venv), build-essential, pkg-config, jq, unzip, xz-utils, less,
21 Node.js 22 (NodeSource). No sudo.
22 - User: non-root `agent` (uid/gid 1000), `HOME=/home/agent`,
23 `CODEWHALE_HOME=/home/agent/.codewhale`. `/work` and `/workspace` exist and
24 are owned by `agent`.
25 - Entrypoint: `sleep infinity` (Daytona injects its own toolbox daemon).
26 - No provider credentials are baked in. Provider credentials must not be
27 supplied at sandbox create time.
28 Daytona create-time environment is server-visible, so a provider secret
29 must never appear in `daytona create -e …` or an SDK `envVars` payload.
30
31 The pins are recorded as OCI labels (`org.opencontainers.image.revision`,
32 `net.codewhale.binary.sha256`, ...) so a running Computer can be audited
33 against the release it claims to run.
34
35 ## Dispatcher wiring and acceptance limits
36
37 The image definition lives only in this directory. The launcher in
38 `crates/tui/src/cloud_dispatch.rs` selects `codewhale-cloud-agent` (or
39 `CODEWHALE_DISPATCH_SNAPSHOT`), sends the account machine token in
40 `CODEWHALE_API_KEY`, applies job labels, and uses the Daytona toolbox to clone
41 and execute commands. `crates/tui/src/dispatch_runner.rs` drives that lifecycle.
42 See the [dispatch guide](../../../docs/DAYTONA_CLOUD_DISPATCH.md) for the
43 command surface.
44
45 This describes source wiring. The image remains pinned to the Engine version
46 listed above, and this repository does not establish a server-side
47 account-token-to-provider-credential resolution path. A snapshot build or
48 manual `codewhale exec` is evidence for that specific operation; it does not
49 qualify account entitlement, provider credential custody, dispatcher execution,
50 metering or customer use. The historical manual image receipt below is not
51 acceptance of the current dispatcher.
52
53 ## Provider credentials inside the Computer
54
55 > **Credential exposure note (verified 2026-08-30).** Daytona persists
56 > `daytona create -e KEY=VALUE` / SDK `envVars` server-side and returns the
57 > environment through its API (`GET /sandbox/{id}`). Create-time environment is
58 > therefore server-visible. Provider secrets must be injected only after the
59 > Computer is created, through a post-create execution channel from stdin
60 > (never argv and never create-time environment), then removed at teardown.
61 > This image and the current dispatcher do not implement that bridge.
62 >
63 > `api_key_env` accepts the **name of an environment variable**, not a file
64 > path or file contents. Do not point it at a `0600` secret file. If a future
65 > product-owned bridge uses a temporary file, it must separately and explicitly
66 > map the stdin-delivered secret into the engine process without placing the
67 > secret in Daytona create-time environment.
68 >
69 > The #5712 `CODEWHALE_API_KEY` account/machine-token caveat remains: it is not
70 > an inference-provider credential and current cloud dispatch does not resolve
71 > it server-side into one. A machine token alone cannot make this image run a
72 > provider-backed Engine turn.
73
74 The following are configuration references for a future supported post-create
75 bridge, not current dispatcher wiring and not permission to use create-time
76 environment:
77
78 | Provider (config name) | Env var | Example model identifiers |
79 |----------------------------|----------------------------------------|------------------------------|
80 | `modelstudio-token-plan` | `MODELSTUDIO_API_KEY` (or `DASHSCOPE_API_KEY`) | `qwen3.8-flash`, `deepseek-v4-pro` |
81 | `deepseek` | `DEEPSEEK_API_KEY` | `deepseek-v4-pro` |
82
83 `CODEWHALE_PROVIDER` / `CODEWHALE_MODEL` select an Engine route when the Engine
84 is launched; they do not make the current dispatcher launch this snapshot or
85 deliver a provider credential.
86
87 ## Build
88
89 `daytona snapshot create` (CLI v0.205.x) has no `--build-arg`, so every pin is
90 inline in the Dockerfile. Resources are set at snapshot creation and are the
91 plan maximum:
92
93 ```sh
94 cd computer/snapshots/cloud-agent
95 daytona snapshot create codewhale-cloud-agent -f Dockerfile --cpu 4 --memory 8 --disk 10
96 ```
97
98 To roll the engine forward: bump `CODEWHALE_VERSION`, `CODEWHALE_COMMIT`,
99 `CODEWHALE_ASSET_URL`, `CODEWHALE_ASSET_SHA256`, the `grep -qx` version
100 assertion, and the OCI labels together, then rebuild under a new snapshot
101 name (snapshots are immutable once active).
102
103 ## Probe a Computer (manual image evidence only)
104
105 ```sh
106 daytona create --snapshot codewhale-cloud-agent \
107 -l owner=cw-integrator -l lane=cloud-agent-e2e --ttl 30 --auto-delete 0 --name cw-probe
108 daytona exec cw-probe -- sh -c 'id -u; codewhale --version; git --version; node --version; df -h /; sha256sum /usr/local/bin/codewhale'
109 daytona delete cw-probe
110 ```
111
112 The sha256 printed by the probe must equal the pinned
113 `c02969556e51e138afa3fe9c97a1359878cd3d1986b1ce1f5fa96c93c6909416`. This is
114 not product-dispatch or launch acceptance evidence.
115
116 ## Image build and manual probe receipt (2026-08-30; not launch proof)
117
118 Built with the command above; snapshot id `b9275f82-0ead-4855-9707-21859aa186b4`,
119 state ACTIVE, 0.70 GB, cpu 4 / memory 8 / disk 10. Probe sandbox
120 (`daytona create --snapshot codewhale-cloud-agent`, labels
121 `owner=cw-integrator,lane=cloud-agent-e2e`, ttl 30, auto-delete 0) reported:
122
123 ```
124 uid=1000 user=agent HOME=/home/agent CODEWHALE_HOME=/home/agent/.codewhale PWD=/work
125 codewhale 0.9.11 (96d13a0bc3f4)
126 git version 2.39.5
127 v22.23.2 (node)
128 Python 3.11.2
129 ripgrep 13.0.0
130 overlay 10G used 24K avail 10G (/ , /work, /workspace)
131 cpu.max 400000 100000 ; memory.max 8589934592
132 c02969556e51e138afa3fe9c97a1359878cd3d1986b1ce1f5fa96c93c6909416 /usr/local/bin/codewhale
133 /workspace writable ; /work writable
134 ```
135
136 This shows only that the Daytona toolbox executed the listed manual commands
137 as the image `USER` (uid 1000) with the image `ENV` honored. It does not prove
138 current product dispatcher wiring, provider-secret custody, Engine execution,
139 or any launch acceptance condition.
140
140 lines MARKDOWN