Boundaries, Not Instructions: How to Stay in Control of Autonomous AI Agents
Why prompt rules are not control: five incidents from one session, and how to replace instructions with technical boundaries.
This image could not be loaded.The more autonomous AI agents get, the more we try to manage them the familiar way — by writing rules into the prompt: "don't touch this," "work only there," "never do that." While running an experiment with three parallel agents, I collected, in two days, a living catalogue of cases where that approach breaks — and where a different one holds. The thesis is simple: an instruction is a request the agent honors with some probability; a boundary is a property of the system that doesn't depend on obedience. While I had one agent working under supervision, the difference felt stylistic. Once there were many, it turned out to be architectural.
Five incidents from one session
Everything below happened in a single working session on this blog. Each case is documented, and each illustrates its own way in which text-based control fails.
No instruction existed — so the accident happened. Preparing for its task, an agent ran git stash in the shared folder and swept my uncommitted files into it — files that had nothing to do with its job. Nobody "violated" anything: the prohibition simply didn't exist. That is a fundamental property of instructions — they get written after accidents. A complete list of what an agent must never do cannot be written.
The instruction existed — and didn't hold. After the first crash I gave the agents an explicit rule: "work strictly inside your own working directory." One of them ran a git command in the main checkout anyway — it simply addressed it by absolute path. Not out of malice or stupidity: a model is probabilistic, and compliance with a written rule is a probability too, multiplied by context length and the number of runs.
The technical boundary held silently. In the same experiment, the most expected accident — "one agent switches the branch for everybody" — never happened. Not because the agents were careful, but because git worktree physically refuses to check out one branch into two working copies. The protection is built into the tool. Nobody has to remember it; nobody has to follow it — it is simply there.
An instruction stood where a boundary belonged. The most uncomfortable discovery: this blog's production was guarded by a line of prompt text. A push to master triggers auto-deploy, and the only thing standing between each agent and production was the sentence "no git push." It held — but that's luck, not control. The real boundary here is access rights: a protected branch, a token without write permission. A request was standing in for a lock.
A boundary above the agent itself. Twice in that session, the runtime stopped not my test subjects but my main assistant: a permission classifier blocked SSH access to the production server, and a bulk discard of uncommitted edits — actions that formally followed from the task but required an explicit human "yes." Both blocks were right. And both fired above the "discipline" of an agent that sincerely believed it was following the plan.
The principle isn't new — only the subject is
Engineering learned this lesson long before LLMs. In the Toyota Production System the principle is called poka-yoke: errors are prevented by the design of the process, not the vigilance of the worker. A part that only fits the right way around beats a poster saying "insert correctly." Platform engineering calls the same thing guardrails; security calls it defense in depth. One idea everywhere: don't rely on the operator having read, understood, and remembered — make the wrong action impossible or expensive.
“An instruction is a request. A boundary is a property of the system. Control that rests on requests isn't control — it's luck with compound interest.”
– the main takeaway of two days with parallel agents
With AI agents this old principle gets sharper for three reasons. Agents are many — the probability of an instruction failing multiplies across every run of every agent. Agents are fast — seconds pass between "started going wrong" and "finished the damage," too fast for a human to intervene. And agents are literal but not reliable: they follow prompt text more diligently than any junior engineer, yet still probabilistically — and probabilistic compliance, at scale, guarantees violations.
What boundaries look like in practice
The layers I put in place after that session, from the file system up to verification:
- File system: each agent gets its own working copy (git worktree, which Anthropic recommends for parallel sessions and Claude Code supports natively), and beneath that an OS-level sandbox: Claude Code's sandboxing isolates the file system and network with standard OS primitives — by Anthropic's own account it cut their internal permission prompts by 84%, and a successful prompt injection stays locked inside.
- Write permissions: production and master are protected by rights, not prompts — protected branches, tokens without push permission, separate identities for agents. Keep the requests in the prompt too, but as the second layer.
- Runtime: worktree does not isolate databases, ports, or containers — those are shared across all copies. Agents that run tests and dev servers need disposable resources: a temporary database, their own port, a container per agent.
- Action permissions: irreversible operations pass through confirmation or a classifier — like Claude Code's auto mode, which evaluates each action instead of either asking about everything or asking about nothing. It's a boundary that moves only by an explicit human decision.
- Verification by artifacts: trust what's on disk, not what the agent reports. My hung agent looked perfectly busy in the UI; the diagnosis came from the absence of new files in its copy over twenty minutes. Commits into the agent's own branch are the same idea: a result that survives both a crash and the agent's optimism.
Instructions don't disappear from this scheme — they become the last layer instead of the first. "Work inside your own directory" is still worth writing: it lowers the rate of attempts. But between the attempt and the accident there should stand a boundary, not hope.
The honest caveats
A boundary is not an absolute: sandboxes get escaped, classifiers make mistakes, and published bypass write-ups demonstrate it regularly. That's why boundaries are layered — like everything in security. A boundary also costs more than an instruction upfront: configuring worktrees, permissions, and a sandbox takes hours; typing a line into a prompt takes seconds. The asymmetry is elsewhere: a boundary is paid for once, an instruction is paid for with a failure probability on every run. My isolation setup paid for itself on the very first rerun of the experiment, which finished without a single conflict.
Conclusion
This series asks how to bring AI agents into real engineering work without losing control. This article's answer: control is not what you write to the agent — it's what you build around it. Before adding another "never do X" to a prompt, ask yourself: can X be made technically impossible? If yes, that's where the effort belongs. Let the prompt ask; let the system forbid.
Sources and reference points
- Making Claude Code more secure and autonomous with sandboxing (Anthropic Engineering) — OS-level file system and network isolation; the source of the 84% figure.
- How we contain Claude across products (Anthropic Engineering, 2026) — how execution boundaries are built across agentic products end to end.
- How we built Claude Code auto mode (Anthropic Engineering) — a permission classifier as the boundary between "ask about everything" and "ask about nothing."
- Poka-Yoke (Lean Enterprise Institute) — the classic principle of preventing errors through process design.
- git-worktree and git-stash — official Git documentation: the mechanics of working copies and the shared stash.
- Claude Code: Best practices for agentic coding (Anthropic Engineering) — the recommendation of worktrees for parallel sessions.
- How to Fairly Compare LLMs on Your Own Code: An Experiment with Three Claude Models — the previous article in this series: the experiment where these incidents were collected.
