Skip to content

kew sandbox

Tooling for the sandboxed-dispatch container path.

kew sandbox smoke

Launch one container end-to-end and report the first failing layer. This proves the LIVE sandbox path that unit tests can't: runtime resolution, image presence (built locally from docker/agent.Dockerfile if the configured tag is absent — no registry pull), container launch through kew's own launch helpers, and the prompt-file handoff, plus a probe that the agent user's HOME is writable (the tmpfs mount that keeps Claude Code's Bash tool and git working under the read-only root, #742). The container only echoes the mounted prompt file and touches its own HOME, so no API key is required for those layers. A final env-only auth layer then checks that a real dispatch could authenticate: containers cannot inherit CLI login, so either ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN (from claude setup-token) must be exported.

Usage: kew sandbox smoke [OPTIONS]

Options:
  --runner TEXT  Runner whose containment to prove; its image comes from
                 [sandbox] images.<runner> (default: claude-code).
  --no-build     Fail (don't build) if the configured image tag is absent locally.

Exit code 0 on success; 1 with the failing layer named — one of runtime, image, launch, execution, or auth.

The image is resolved through the same runner-aware resolver dispatch uses ([sandbox] images.<runner>, falling back to [sandbox] image for claude-code), so the smoke always proves the image that a dispatch of that runner would actually launch. A runner with no mapped image fails at the image layer naming the key to set, and the auth layer checks the credential that runner needs in-container. Only the stock claude-code image is built locally from docker/agent.Dockerfile; a mapped non-default image is yours to build or pull.

Example:

# Build the agent image locally if needed, then smoke-test the container path
kew sandbox smoke

# Require the image to already be present (no local build)
kew sandbox smoke --no-build

# Prove the image a non-claude route will run, before routing work at it
kew sandbox smoke --runner opencode

Prompt handoff

The prompt reaches the agent through a mounted prompt file, not argv: the host writes it to <checkout>/.kew-prompt.txt (mounted at /work/.kew-prompt.txt), and the image entrypoint feeds it to claude --print on stdin. See kew/src/kew/sandbox.py and docker/agent-entrypoint.sh for the full contract.