# Stop your AI agent from touching files outside your project — in three steps

Cursor and GitHub Copilot agents have wandered into Documents folders, root drives, and home directories — deleting files that had nothing to do with the project they were working on. The control-plane fix is workspace-scoping at the hook layer.

A developer posted on the [Cursor forum](https://forum.cursor.com/t/critical-incident-cursor-agent-left-repository-and-deleted-local-documents-folder/158991) that the Cursor agent's working directory escaped its repository, walked into `~/Documents`, and recursively deleted the contents. A separate [GitHub community discussion](https://github.com/orgs/community/discussions/166370) documented Copilot's agent autocompleting a destructive command that wiped a user's `D:` drive — ten years of personal photos and videos, gone. The agent didn't choose either drive maliciously. It chose them because the command-construction prompt landed there.

Modern AI agents have access to your entire filesystem. The "project" you've opened in Cursor is a notional boundary — to the agent, it's just one directory in a tree it can navigate freely. If your agent can `cd ~/`, it can `rm -rf ~/`. If your agent can `cat /etc/passwd`, it can `rm /etc/passwd`. The IDE's project sidebar is a UX concept; the OS doesn't enforce it.

This is one of the most common documented incident classes in the AI-agent forums right now, and one of the easiest to gate.

## What "agent escaped the repository" actually means

The agent didn't break out. It walked through an unlocked door. A few common ways this happens:

- The user asked the agent to "back up some files" — agent guessed `~/Documents` was the target
- The agent's path-construction prompt produced an absolute path instead of a relative one (e.g., `/Users/dev/...` instead of `./...`)
- The agent ran `cd` to look at something, then forgot to `cd` back, then ran a destructive command from the new working directory
- A shell variable expanded unexpectedly (the [Claude Code `rm -rf ~/` tilde-expansion bug](https://byteiota.com/claude-codes-rm-rf-bug-deleted-my-home-directory/) is the canonical example)

In each case the model believed it was operating inside the project. The shell — which has no concept of "the project" — happily executed somewhere else.

## Irreversible actions live one tool call away

The home-directory case is uniquely painful because it tends to contain things that don't exist anywhere else: uncommitted experiments, downloaded artifacts, configurations, personal files, the only copy of something you didn't think to back up. *Most* code is reproducible from source control. *Most* of `~/Documents` is not.

The probability of an agent in your environment doing this in the next 60 days is not low. It happens enough that there are dedicated GitHub issue threads tracking variants by month.

## Three steps that pin your agent inside the project

### Step 1 — Install the hook

For Cursor, Claude Code, or Codex CLI:

```bash
curl -sf https://agenticcontrolplane.com/install.sh | bash
```

Every file operation the agent attempts — `Read`, `Write`, `Edit`, and Bash commands that touch files (`rm`, `mv`, `cp`, `dd`, `find -delete`) — goes through ACP's hook before execution. The hook receives the *resolved* absolute path (after tilde expansion, after working-directory composition), so policy can match against where the agent actually wants to write, not where the agent thinks it's writing.

### Step 2 — Deny file operations outside the project root

ACP classifies file operations by path — `Read.env`, `Write.src`, `Bash.rm`, etc. For workspace-scoping, you set policy on the *path* of the resolved target:

```json
{
  "mode": "enforce",
  "workspace": {
    "allowedRoots": [
      "${project.root}",
      "/tmp/${project.id}"
    ],
    "deniedPaths": [
      "$HOME/Documents",
      "$HOME/Desktop",
      "$HOME/.ssh",
      "$HOME/.aws",
      "$HOME/.config",
      "/Volumes",
      "/etc",
      "/usr"
    ]
  },
  "tools": {
    "Write.*": {
      "background":  { "permission": "deny", "if": "path NOT IN workspace.allowedRoots" },
      "interactive": { "permission": "ask",  "if": "path NOT IN workspace.allowedRoots" }
    },
    "Bash.rm": {
      "background":  { "permission": "deny", "if": "path NOT IN workspace.allowedRoots" }
    }
  }
}
```

The semantic: any file operation whose resolved path lands outside the project root (or an explicit allow-listed scratch directory like `/tmp`) is denied in background tier and asked-about in interactive tier. The agent can do anything inside the project; outside the project, it can't.

This catches the tilde-expansion bug, the wandering-cd bug, the absolute-path mistake, and the wrong-drive completion all in one rule.

### Step 3 — Bind end-user identity, per request

For server-side agents, the user's IdP role can additionally restrict which projects the agent can even access:

```python
from acp_governance import set_context

set_context(
    user_token=jwt,
    agent_name="repo-maintenance",
    agent_tier="background",
    workspace_id="acme-payments-service",  # which project this run is allowed in
)
```

If a different project's agent run somehow gets scheduled with this user's token, the workspace mismatch denies the call. It's a belt-and-suspenders defense — the path policy already catches "outside the project," but `workspace_id` adds "this is the WRONG project entirely."

### (Free fourth step) — Audit log

Every denied path is logged with the *resolved* absolute path, not the agent's original command string. So when you see *"agent attempted Write to `/Users/dev/Documents/family-photos/2024.zip`"* in the dashboard, you know exactly which boundary it tried to cross — useful for tightening rules, useful for understanding why the agent ended up there.

## The total time investment

- One `curl` command (Step 1): ~30 seconds
- Workspace-root + denied-paths config in the dashboard (Step 2): ~3 minutes
- Optional `workspace_id` for server-side agents (Step 3): ~30 seconds per handler

Three to four minutes from blank slate to "an autonomous agent in this environment cannot write or delete files outside the project root, regardless of what path the model decided to construct."

If you've ever had a moment where you watched the agent type a path and thought *"wait, that's not where I think we are,"* three minutes of work makes that thought retroactive instead of urgent.

Workspace scoping is one rule in a wider posture. The [Tool Surface Index](/tool-surfaces) shows the full declared surface of Claude Code and Codex — every tool that can read, write, or reach outward — and [getting started](/getting-started) walks the install.

[AgenticControlPlane.com](https://agenticcontrolplane.com)
