A checklist for running AI coding agents on code you did not write

Agents trust the directory you point them at. That is the whole problem — and the whole fix.

Decide what the directory is allowed to say before the agent reads it. None of this depends on a vendor patch, and none of it names an unpatched product.

Before you open the folder

  1. Run the scanner. pip install agent-boundary-scan && abs ./that-repo — git config sinks, filter drivers, repo-declared MCP servers, agent hooks, GIT_* env channels, devcontainer lifecycle commands, escaping symlinks.
  2. Read the local config yourself — the part git clone does not carry: git -C ./that-repo config --local --list. Anything under core.fsmonitor, core.hooksPath, core.pager, core.editor, core.sshCommand, diff.external, filter.*, protocol.* is a program the repository chose.
  3. Look at .gitattributes. filter=<name> and diff=<name> name drivers whose program comes from that config. It is content; it does not need to be committed to apply.
  4. Look in .git/hooks, and at core.hooksPath. Hooks inside the repository are ordinary files git will execute.

Before you mount an MCP server

  1. Read the config, then the source. mss ~/.config/claude and mss ./some-server --source-only.
  2. Change the parts you can change: pin the package version (drop npx -y), point path arguments at one project directory instead of /, drop --privileged and docker.sock, use https, keep credentials out of a file that syncs.

For a team

  1. Forbid repository-declared servers and hooks by policy: no .mcp.json in a repo, no .claude/settings.json with hooks, no .aider.conf.yml with lint-cmd, no unreviewed .devcontainer lifecycle command.
  2. Put both scanners in CI: abs . --fail-on high, mss . --fail-on high. Fast, offline, no credentials.
  3. Give the agent less: read-only checkout, its own git identity, no ambient cloud tokens, a directory it cannot escape. The interesting failures happen before the first prompt — containment has to be in place before it starts.
  4. Contain the first look. A container, a VM, or a throwaway clone is cheaper than the argument about what ran.

What this assumes

That you will sometimes be handed a repository you did not write: a template, an archive, a customer's tree, a shared folder, a PR checkout. In those cases the repository's configuration is input — and everything above is about not treating input as instruction.