-
Notifications
You must be signed in to change notification settings - Fork 3.5k
cloud agent: product-owned Daytona snapshot + two fixes found by running agents inside a Computer #5745
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
cloud agent: product-owned Daytona snapshot + two fixes found by running agents inside a Computer #5745
Changes from all commits
34efe8c
5180cfb
0d1c2e3
454f772
a93c976
dade8ea
48b74d0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| # syntax=docker/dockerfile:1 | ||
| # codewhale-cloud-agent — Daytona snapshot image for Codewhale cloud agents. | ||
| # | ||
| # Product truth first: this image installs the RELEASED v0.9.11 Linux x86_64 | ||
| # binary (static musl, no glibc floor) from the GitHub release by exact URL, | ||
| # verifies its sha256 against codewhale-artifacts-sha256.txt, and records the | ||
| # commit + digest as OCI labels (PRD 4.5: commit- and digest-pinned Linux | ||
| # binary inside the Computer). No secrets are baked in. Daytona create-time | ||
| # environment is server-visible, so a provider key must never be injected at | ||
| # create time. A future dispatcher must deliver provider secrets only after | ||
| # creation, over a post-create execution channel from stdin (never argv), and | ||
| # remove them during teardown. `CODEWHALE_API_KEY` is an account/machine token, | ||
| # not an inference-provider credential; current cloud dispatch has no | ||
| # server-side account-token-to-provider-key resolution. | ||
| # | ||
| # Build (Daytona, amd64 only; daytona snapshot create has no --build-arg, so | ||
| # every pin is inline): | ||
| # daytona snapshot create codewhale-cloud-agent \ | ||
| # -f Dockerfile --cpu 4 --memory 8 --disk 10 (plan max; resources bind to the snapshot) | ||
| # | ||
| # Current dispatcher boundary: this is an image definition, not a wired cloud | ||
| # execution path. `crates/tui/src/cloud_dispatch.rs` currently creates a | ||
| # Daytona sandbox with a name and labels only; it does not select this snapshot, | ||
| # clone a repository, inject any sandbox environment, or execute `codewhale`. | ||
| # A manual image build or Daytona probe is therefore not Cloud Agent launch | ||
| # evidence. Do not add a create-time provider-key shortcut while that product | ||
| # wiring is built. | ||
|
|
||
| FROM debian:bookworm-slim | ||
|
|
||
| ARG DEBIAN_FRONTEND=noninteractive | ||
|
|
||
| # ---- pins (release v0.9.11, tag commit 96d13a0bc3f40280ea3865280ad5ccf0e2845e6f) | ||
| ENV CODEWHALE_VERSION=0.9.11 \ | ||
| CODEWHALE_COMMIT=96d13a0bc3f40280ea3865280ad5ccf0e2845e6f \ | ||
| CODEWHALE_ASSET_URL=https://github.com/Hmbown/CodeWhale/releases/download/v0.9.11/codewhale-linux-x64 \ | ||
| CODEWHALE_ASSET_SHA256=c02969556e51e138afa3fe9c97a1359878cd3d1986b1ce1f5fa96c93c6909416 \ | ||
|
Comment on lines
+33
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When this snapshot is built and used, it always installs commit Useful? React with 👍 / 👎. |
||
| NODE_MAJOR=22 | ||
|
|
||
| # Base toolchain for an agent doing code work: git, curl, TLS roots, ripgrep, | ||
| # python3, node LTS (22), build-essential. procps for `ps`/`pkill` used by the | ||
| # engine's process tooling; sudo is deliberately NOT installed. | ||
| RUN apt-get update \ | ||
| && apt-get install -y --no-install-recommends \ | ||
| ca-certificates curl git gnupg ripgrep procps \ | ||
| python3 python3-pip python3-venv \ | ||
| build-essential pkg-config \ | ||
| jq unzip xz-utils less \ | ||
| && mkdir -p /etc/apt/keyrings \ | ||
| && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \ | ||
| | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ | ||
| && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_MAJOR}.x nodistro main" \ | ||
| > /etc/apt/sources.list.d/nodesource.list \ | ||
| && apt-get update \ | ||
| && apt-get install -y --no-install-recommends nodejs \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| # Download the released binary by exact URL and refuse anything whose sha256 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [INFO] Dockerfile version assertion is brittle The build hard-fails unless |
||
| # does not match the release checksum. Static musl: no interpreter, no glibc. | ||
| RUN set -eu; \ | ||
| curl -fsSL --retry 3 -o /tmp/codewhale "${CODEWHALE_ASSET_URL}"; \ | ||
| echo "${CODEWHALE_ASSET_SHA256} /tmp/codewhale" | sha256sum -c -; \ | ||
| install -m 0755 -o root -g root /tmp/codewhale /usr/local/bin/codewhale; \ | ||
| ln -s /usr/local/bin/codewhale /usr/local/bin/codew; \ | ||
| rm -f /tmp/codewhale; \ | ||
| codewhale --version | tee /etc/codewhale-version; \ | ||
| grep -qx "codewhale 0.9.11 (96d13a0bc3f4)" /etc/codewhale-version | ||
|
|
||
| # Non-root agent user. /work is the generic Computer mount; /workspace is the | ||
| # path #5712's runner clones into and runs the harness from — both owned by | ||
| # the agent so a non-root toolbox user can write them. | ||
| RUN groupadd --gid 1000 agent \ | ||
| && useradd --uid 1000 --gid 1000 --create-home --home-dir /home/agent --shell /bin/bash agent \ | ||
| && mkdir -p /work /workspace /home/agent/.codewhale \ | ||
| && chown -R agent:agent /work /workspace /home/agent | ||
|
|
||
| ENV HOME=/home/agent \ | ||
| CODEWHALE_HOME=/home/agent/.codewhale \ | ||
| PATH=/home/agent/.local/bin:/usr/local/bin:/usr/bin:/bin \ | ||
| GIT_TERMINAL_PROMPT=0 \ | ||
| CI=1 \ | ||
| TERM=xterm-256color | ||
|
|
||
| LABEL org.opencontainers.image.title="codewhale-cloud-agent" \ | ||
| org.opencontainers.image.description="Codewhale cloud agent Computer: released codewhale CLI preinstalled for dispatched turns" \ | ||
| org.opencontainers.image.version="0.9.11" \ | ||
| org.opencontainers.image.revision="96d13a0bc3f40280ea3865280ad5ccf0e2845e6f" \ | ||
| org.opencontainers.image.source="https://github.com/Hmbown/CodeWhale" \ | ||
| net.codewhale.binary.asset="codewhale-linux-x64" \ | ||
| net.codewhale.binary.sha256="c02969556e51e138afa3fe9c97a1359878cd3d1986b1ce1f5fa96c93c6909416" \ | ||
| net.codewhale.binary.commit="96d13a0bc3f40280ea3865280ad5ccf0e2845e6f" \ | ||
| net.codewhale.binary.version="0.9.11" \ | ||
| net.codewhale.release.image="ghcr.io/hmbown/codewhale:0.9.11@sha256:6de13fe5e62fb3cb815c423bcb17455bef4d9f7db2107888beb88fe4b7c9ac14" | ||
|
|
||
| USER agent | ||
| WORKDIR /work | ||
|
|
||
| # Daytona injects its own toolbox daemon; keep the container alive for it. | ||
| ENTRYPOINT ["sleep", "infinity"] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,135 @@ | ||
| # `codewhale-cloud-agent` — Daytona Computer snapshot | ||
|
|
||
| This directory is the product-owned definition of the Daytona snapshot that a | ||
| Cloud Agent acquires as its Computer (PRODUCT_PRD §4.5). The Codewhale Engine | ||
| is the sole runtime inside the Computer and is installed as a commit- and | ||
| digest-pinned Linux binary; nothing else in the image runs agent logic. | ||
|
|
||
| ## What the image is | ||
|
|
||
| - Base: `debian:bookworm-slim` (linux/amd64 — Daytona builds amd64 only). | ||
| - Engine: released `codewhale-linux-x64` from GitHub release `v0.9.11`, | ||
| fetched by exact URL and verified against the release checksum before | ||
| install: | ||
| - commit `96d13a0bc3f40280ea3865280ad5ccf0e2845e6f` (tag `v0.9.11`) | ||
| - sha256 `c02969556e51e138afa3fe9c97a1359878cd3d1986b1ce1f5fa96c93c6909416` | ||
| - static musl build (no glibc floor), installed at `/usr/local/bin/codewhale` | ||
| with a `codew` symlink; the build fails if `codewhale --version` does not | ||
| print `codewhale 0.9.11 (96d13a0bc3f4)`. | ||
| - Toolchain for agent work: git, curl, CA roots, ripgrep, procps, python3 | ||
| (+pip, venv), build-essential, pkg-config, jq, unzip, xz-utils, less, | ||
| Node.js 22 (NodeSource). No sudo. | ||
| - User: non-root `agent` (uid/gid 1000), `HOME=/home/agent`, | ||
| `CODEWHALE_HOME=/home/agent/.codewhale`. `/work` and `/workspace` exist and | ||
| are owned by `agent`. | ||
| - Entrypoint: `sleep infinity` (Daytona injects its own toolbox daemon). | ||
| - No provider credentials are baked in or supplied at sandbox create time. | ||
| Daytona create-time environment is server-visible, so a provider secret | ||
| must never appear in `daytona create -e …` or an SDK `envVars` payload. | ||
|
|
||
| The pins are recorded as OCI labels (`org.opencontainers.image.revision`, | ||
| `net.codewhale.binary.sha256`, ...) so a running Computer can be audited | ||
| against the release it claims to run. | ||
|
|
||
| ## Current dispatcher state — not a runtime contract | ||
|
|
||
| The current product dispatcher wiring for this snapshot is absent. | ||
| `crates/tui/src/cloud_dispatch.rs` creates a Daytona sandbox with a generated | ||
| name and labels, then records its ID. It does **not** select | ||
| `codewhale-cloud-agent`, clone into `/workspace`, inject sandbox environment, | ||
| call the Daytona toolbox execution endpoint, or run `codewhale`. It also does | ||
| not contain a server-side account-token-to-provider-credential resolution path. | ||
|
|
||
| This directory is consequently an image definition and a bounded manual | ||
| inspection aid, not an end-to-end Cloud Agent implementation. A snapshot build, | ||
| manual `daytona create`, or manual `codewhale exec` proves only the specific | ||
| image/operator step observed; none is launch proof for dispatcher, entitlement, | ||
| credential custody, Engine execution, lifecycle, metering, or customer use. | ||
|
|
||
| ## Provider credentials inside the Computer | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [WARNING] Provider credential injection remains unimplemented The PR description and README both state that credentials fail as shipped: only CODEWHALE_API_KEY is injected, and nothing consumes it as an inference-provider credential. The Dockerfile explicitly forbids create-time environment and documents a future post-create stdin bridge, but no code implements that bridge. As a result the snapshot cannot run a provider-backed Engine turn in the current product path. |
||
|
|
||
| > **Credential exposure note (verified 2026-08-30).** Daytona persists | ||
| > `daytona create -e KEY=VALUE` / SDK `envVars` server-side and returns the | ||
| > environment through its API (`GET /sandbox/{id}`). Create-time environment is | ||
| > therefore server-visible. Provider secrets must be injected only after the | ||
| > Computer is created, through a post-create execution channel from stdin | ||
| > (never argv and never create-time environment), then removed at teardown. | ||
| > This image and the current dispatcher do not implement that bridge. | ||
| > | ||
| > `api_key_env` accepts the **name of an environment variable**, not a file | ||
| > path or file contents. Do not point it at a `0600` secret file. If a future | ||
| > product-owned bridge uses a temporary file, it must separately and explicitly | ||
| > map the stdin-delivered secret into the engine process without placing the | ||
| > secret in Daytona create-time environment. | ||
| > | ||
| > The #5712 `CODEWHALE_API_KEY` account/machine-token caveat remains: it is not | ||
| > an inference-provider credential and current cloud dispatch does not resolve | ||
| > it server-side into one. A machine token alone cannot make this image run a | ||
| > provider-backed Engine turn. | ||
|
|
||
| The following are configuration references for a future supported post-create | ||
| bridge, not current dispatcher wiring and not permission to use create-time | ||
| environment: | ||
|
|
||
| | Provider (config name) | Env var | Example model identifiers | | ||
| |----------------------------|----------------------------------------|------------------------------| | ||
| | `modelstudio-token-plan` | `MODELSTUDIO_API_KEY` (or `DASHSCOPE_API_KEY`) | `qwen3.8-flash`, `deepseek-v4-pro` | | ||
| | `deepseek` | `DEEPSEEK_API_KEY` | `deepseek-v4-pro` | | ||
|
|
||
| `CODEWHALE_PROVIDER` / `CODEWHALE_MODEL` select an Engine route when the Engine | ||
| is launched; they do not make the current dispatcher launch this snapshot or | ||
| deliver a provider credential. | ||
|
|
||
| ## Build | ||
|
|
||
| `daytona snapshot create` (CLI v0.205.x) has no `--build-arg`, so every pin is | ||
| inline in the Dockerfile. Resources are set at snapshot creation and are the | ||
| plan maximum: | ||
|
|
||
| ```sh | ||
| cd computer/snapshots/cloud-agent | ||
| daytona snapshot create codewhale-cloud-agent -f Dockerfile --cpu 4 --memory 8 --disk 10 | ||
| ``` | ||
|
|
||
| To roll the engine forward: bump `CODEWHALE_VERSION`, `CODEWHALE_COMMIT`, | ||
| `CODEWHALE_ASSET_URL`, `CODEWHALE_ASSET_SHA256`, the `grep -qx` version | ||
| assertion, and the OCI labels together, then rebuild under a new snapshot | ||
| name (snapshots are immutable once active). | ||
|
|
||
| ## Probe a Computer (manual image evidence only) | ||
|
|
||
| ```sh | ||
| daytona create --snapshot codewhale-cloud-agent \ | ||
| -l owner=cw-integrator -l lane=cloud-agent-e2e --ttl 30 --auto-delete 0 --name cw-probe | ||
| daytona exec cw-probe -- sh -c 'id -u; codewhale --version; git --version; node --version; df -h /; sha256sum /usr/local/bin/codewhale' | ||
| daytona delete cw-probe | ||
| ``` | ||
|
|
||
| The sha256 printed by the probe must equal the pinned | ||
| `c02969556e51e138afa3fe9c97a1359878cd3d1986b1ce1f5fa96c93c6909416`. This is | ||
| not product-dispatch or launch acceptance evidence. | ||
|
|
||
| ## Image build and manual probe receipt (2026-08-30; not launch proof) | ||
|
|
||
| Built with the command above; snapshot id `b9275f82-0ead-4855-9707-21859aa186b4`, | ||
| state ACTIVE, 0.70 GB, cpu 4 / memory 8 / disk 10. Probe sandbox | ||
| (`daytona create --snapshot codewhale-cloud-agent`, labels | ||
| `owner=cw-integrator,lane=cloud-agent-e2e`, ttl 30, auto-delete 0) reported: | ||
|
|
||
| ``` | ||
| uid=1000 user=agent HOME=/home/agent CODEWHALE_HOME=/home/agent/.codewhale PWD=/work | ||
| codewhale 0.9.11 (96d13a0bc3f4) | ||
| git version 2.39.5 | ||
| v22.23.2 (node) | ||
| Python 3.11.2 | ||
| ripgrep 13.0.0 | ||
| overlay 10G used 24K avail 10G (/ , /work, /workspace) | ||
| cpu.max 400000 100000 ; memory.max 8589934592 | ||
| c02969556e51e138afa3fe9c97a1359878cd3d1986b1ce1f5fa96c93c6909416 /usr/local/bin/codewhale | ||
| /workspace writable ; /work writable | ||
| ``` | ||
|
|
||
| This shows only that the Daytona toolbox executed the listed manual commands | ||
| as the image `USER` (uid 1000) with the image `ENV` honored. It does not prove | ||
| current product dispatcher wiring, provider-secret custody, Engine execution, | ||
| or any launch acceptance condition. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[WARNING] Cloud agent snapshot is not connected to any runtime path
The new Dockerfile defines a codewhale-cloud-agent snapshot, but crates/tui/src/cloud_dispatch.rs still only creates a named/labelled Daytona sandbox and does not select this snapshot, clone a repository, inject sandbox environment, call the toolbox execution endpoint, or run codewhale. The README disclaims this, but the snapshot should not be presented as product-owned launch evidence until that wiring exists.