[cage-pod] cage-pod — running · up 122h 52m ▪NOT LOGGED IN — send /auth ◦0 active sessions · 10 processes ◆last command ran as the executor 8d ago — host — ▫RAM: 5.7G free of 11.7G · CPU 25% now, 27% 5min1:43 PM
Message agent-cage…
agent-cage · relay
/upgrade cage-pod1:43 PM ✓✓
[cage-pod]cage-pod is on 6697…384 (cage-1.0.0)
9b91…347 → 6697…384
nix: fleet store at /srv/cage-store/nix, read-only executor reads the shared store through a database pod cage-pod started executor broker injected as uid 60000
this is a container, so its credential did not survive the restart: send /auth again1:43 PM
AC
[cage-pod] cage-pod — running · up 0h 0m ▪NOT LOGGED IN — send /auth ◦0 active sessions · 6 processes ◆last command ran as the executor 8d ago — host — ▫RAM: 6.5G free of 11.7G (44% used) · CPU 33% now, 28% 5min (6 cores)1:43 PM
The whole fleet is driven from one chat: list agents, read their state, send a file, upgrade a pod. Each agent also has its own group where you talk to the model directly, and agents attach to the Claude app over MCP, where they appear beside your own conversations.
The design: Linux does the isolating
Every component is a separate Unix account, and the direction of trust between them is deliberate. The relay holds the chat identity and routes messages — nothing else. The manager holds bucket credentials and the authority to perform signed upgrades, and passes commands to exactly one agent. The agent holds one thing: the model credential. The executor, where every model-issued shell command runs, holds nothing at all and has no route back.
Commands flow one way — manager → agent, never the reverse — so a compromised agent cannot reach up into the privileged manager, and a prompt-injected model acting as the executor cannot escalate beyond the account it was given. Nothing here is a novel security mechanism, and nothing is a virtual machine: it is the operating system’s own permission model, applied with care, so the agents can still do real work — build, test, even run their own VMs — on hardware you never have to touch from your laptop.
Commands flow one way
Untrusted model commands run in a locked-down container, with no path back to your systems.
commands flow one way
chatTelegram
relaychat identity
managerbucket credentialsupgrade signing
pod — podman: own filesystem, read-only root, no capabilities
agentmodel credentialone thing, nothing else
executornothingmodel commands run here
bare — same accounts, directly on the host
no route back — a prompt-injected model stays where it was put
Isolated execution
Model commands run in a restricted container with no capabilities.
No return path
A prompt-injected model stays where it was put.
Same accounts
bare mode runs the same accounts directly on the host.
Commands flow one way
A simple, isolated architecture for running model commands safely, with no route back.
chatTelegram
relaychat identity
managerbucket credentialsupgrade signing
agentmodel credentialone thing, nothing else
executornothingmodel commands run here
pod — a podman container: own filesystem, read-only root, no capabilities
bare — same accounts, directly on the host
no route back — a prompt-injected model stays where it was put
One-way by design.Useful work, with strong boundaries.
Two modes
bareTwo ordinary accounts on the host. The agent sees the real hardware — a GPU, the disks — but only as far as its Linux user is allowed to. The credential boundary is identical to pod mode; the sandbox and egress control are given up, and the trade is stated plainly.
podAgent and executor inside a podman container: its own filesystem and nothing of the host's, read-only root, every capability dropped, dangerous syscalls unavailable. Outbound network is open today; restricting which internet resources an agent may reach is in progress.
Native harnesses, kept current
agent-cage does not replace a vendor's agent with its own: Anthropic models run in Claude Code, OpenAI in Codex, Z.AI in theirs — and one harness can call another as a tool. Harnesses change several times a month and must be updated the day a new model ships, so an upgrade is one command from the chat: a signed release into a shared read-only Nix store, a pod restart, a report of what changed.
agent-cage · relayrelay
/get shared/dictate/diane-ux.tgz12:52 PM ✓✓
get shared/dictate/diane-ux.tgz — which agent?12:52 PM
The old agent process was still running after the deploy, so I sent /stop to clear the stale executor and restarted a fresh pod. The new pod is up and healthy, all services are reachable, and the tests are green. The commit has landed on main and the deployment finished ~75 seconds after the fix.
[cage-pod] pod restarted executor broker injected as uid 60000 tests: 342 passed, 0 failed deploy: complete (75s)
2. Root cause and what we fixed
The agent returned to camping right after the deploy because the tool hit TaskOutput and saw the same session context, which it should have ignored for at least TASK_BLOCK_LIMIT_MS. I updated the bridging logic to treat an identical session as still active, added a guard to cancel stray background tasks when a new deploy starts, and improved logging so this is visible next time.
3. Prevention and next steps
A short integration test reproduces the timing and verifies the agent now waits, resumes, and posts the follow-up. The runbook has a quick /stop recovery procedure.
◷ 25m12s · 10685.0k tok · 15 tool calls10:01 PM
A per-agent group — here GLM-5.3-Flash in the zcode harness, reached from Telegram: a pinned budget strip, tool-run strips as the model works, and its written report when it is done.
How it is built
One statically-linked Go binary is every daemon, every installer step and the shell shim, with no third-party Go dependencies — nothing has to be vendored, audited or trusted with credentials sight unseen. Nix pins the sandbox image, the toolchain and the signed-upgrade path to one closure.
git clone https://github.com/georgeee/agent-cage /opt/agent-cage
cd /opt/agent-cage/deploy
sudo ./01-store.sh && sudo ./02-hub.sh && sudo ./03-agent.sh my-agent pod
Where this stands
Four-account privilege model, bare and pod modes, Telegram relay, per-agent groups, file transfer, signed upgrades from the chatin active use
Claude Code, Codex and Z.AI harnesses; one harness calling anotherin active use
A Claude agent using zcode (Z.AI, GLM-5.3-Flash) and Codex (OpenAI) as sub-agents over MCPin active use
Egress allow-lists for podsin progress
Security review and public release1 October 2026
agent-cage is released on 1 October. Before then, it is available on request.Ask for access