Give Hermes a shell.
Keep everything else.
Hermes Agent, from Nous Research, writes code, runs it, and fixes what breaks. On Chalk it does that inside a sandbox that can reach only its model endpoint, using an API key it never sees. One Python file sets it up, runs the task, and hands you the diff.
One task, start to finish
The default prompt asks Hermes for a Roman numeral module and its tests, with no package index to lean on. In about a minute it writes both files, runs the tests, and reports back. Then the sandbox is gone, and what remains is the diff.
$ ./examples/hermes/hermes.py --model anthropic/claude-sonnet-4-6Starting sandbox (the first run builds the Hermes image)...Running Hermes with anthropic/claude-sonnet-4-6...Query: Create a small, standard-library-only Python module roman.py with to_roman(int) and from_roman(str) for 1-3999, and a test_roman.py that checks a round trip over the whole range plus invalid inputs…Initializing agent...┊ ✍️ write /root/project/roman.py 8.2s┊ review diff a/roman.py → b/roman.py +57┊ ✍️ write /root/project/test_roman.py 0.1s┊ review diff a/test_roman.py → b/test_roman.py┊ 💻 $ python test_roman.py 0.2s☤ HermesAll five tests pass, zero failures.roman.py converts with a greedy table of 13 value/symbol pairs and rejects malformed input like IIII or IM with a canonical round-trip check. test_roman.py covers 21 known values, all 3999 round trips, and 16 invalid inputs, with plain asserts.Duration: 1m 2s · Messages: 8 (1 user, 6 tool calls)--- Changes made by Hermes ---A roman.pyA test_roman.pyTerminated sandbox da132ad3-2fdf-4b75-b120-f2b0f9f6a6fa.
How it works
A coding agent is only useful with real tools, and only safe if those tools stay inside a boundary. The sandbox draws that boundary in three places.
A pinned image
Hermes' own installer runs once, at a pinned release, inside an image Chalk builds and caches. Every later sandbox starts from the same bytes in seconds.
An allowlisted network
The sandbox's network policy lists the model endpoint and, if you ask for one, the git host. Every other connection fails before it leaves the sandbox: no route, no DNS.
A key the agent never sees
Hermes' environment holds a random placeholder. The egress proxy replaces it with the real API key, and only on requests bound for the model host.
Run it with one command
Clone the SDK, log in, set a model key, and run the example. The first run builds the Hermes image, which takes a few minutes; after that a sandbox is ready in seconds and a typical task finishes in about a minute.
Pass --repo to work on your own code and --prompt to change the task. Swap the model endpoint without touching anything else.
chalk-sandbox-sdk/examples/hermesgit clone https://github.com/chalk-ai/chalk-sandbox-sdk
cd chalk-sandbox-sdk
# Or export CHALK_CLIENT_ID and CHALK_CLIENT_SECRET.
chalk login
export OPENROUTER_API_KEY=...
# Builds the image, starts a sandbox, runs one task, prints the diff.
./examples/hermes/hermes.pyWhat Chalk handles
Hermes brings the agent. Chalk brings the place it's safe to let it work.
A real shell, safely
Hermes runs with --yolo: no approval prompts for each command. The sandbox, not a human clicking yes, is what bounds what it can do.
Nothing to exfiltrate
A prompt-injected agent that dumps its environment finds a placeholder, and has nowhere to send it except your model provider.
Images from Python
Image.debian_slim().run_commands(...) builds the container. No Dockerfile, no registry, and the first build is the only slow one.
Bounded lifetimes
Each sandbox is terminated when the run ends and carries a server-side lifetime, so a killed laptop never leaves compute running.
Any OpenAI-compatible model
OpenRouter by default. Point --base-url at OpenAI, a gateway, or a vLLM server in your own cloud without touching the sandbox code.
Reviewable output
The project is a git repository, so every run ends with git status and a full diff of exactly what the agent changed.
Put your agents in a sandbox
Coding agents, evaluation harnesses, or anything that runs model-written code. Talk to an engineer about running them next to your data.