DocsWhat may it doUntrusted repositories and new agents

Untrusted repositories and new agents

Rules are written about actions. Some of the risk is about where the agent is standing: a checkout somebody else wrote, an agent installed this morning, an MCP server nobody here has watched work. None of those is covered by a rule anybody thought to write, so the runtime keeps a layer under the rules that needs no writing. It only ever turns an allow into an ask, so a deny stays a deny, and like every ask it bites in enforce and is recorded in observe.

Writes stay in the repository

A write or a delete outside the repository a session started in asks first, whatever the rules allow, and so does one outside the paths the session declared with memnox run --paths. The system temp directory is exempt. Reads outside the repository are governed by your rules as before.

The same boundary holds for an agent that was only hooked by setup rather than started with memnox run. Claude Code asks in its own prompt, where its person sees it. Cursor, Codex, Gemini CLI and Windsurf cannot ask from a hook, so they refuse with the reason instead. A hooked agent's shell commands meet the boundary when they run inside a checkout; one that has changed directory out of every repository has no repository to be kept in.

The network goes through the egress proxy

The daemon runs an egress proxy on 127.0.0.1:8888, or on any free port when that one is taken. memnox run starts the agent with HTTP_PROXY, HTTPS_PROXY and ALL_PROXY pointing at it and NODE_USE_ENV_PROXY=1, so Node's own fetch obeys too. When no daemon is running, the run starts a proxy of its own. Every request is ruled on by its host and written to the ledger with the host only.

A repository nobody here vouched for

A freshly cloned repository can carry instructions aimed at the agent reading it. memnox run --untrusted is the preset for that case:

bash
memnox run --untrusted -- claude

Inside the wall

Writes

Only the repository, temp and the agent's own state. The Memnox rules, the trust already given and the answers to held calls stay unwritable from inside.

Reads

Credentials and the dotfiles in your home directory are unreadable.

Network

TCP reaches only this session's own egress proxy. Package registries and the agent's model provider go through, and every other host asks.

Actions

Every outward or destructive action asks.

A held call is answered from files the agent must not be able to write, so a shell command inside the wall that would ask is refused with its reason instead. A request the proxy asks about is raised outside the wall and answered with memnox approvals, and a file edit asks in the agent's own prompt.

The kernel holds the wall, and where no kernel can, the run does not start. On macOS seatbelt holds all of it. On Linux Landlock holds the files, and holds TCP from ABI 4 (Linux 6.7); a small python3 helper applies the ruleset, and the start screen says plainly when the kernel, the helper or the ABI is missing. --no-guard runs the agent with only the seams asking, which is a choice you make out loud rather than one made for you.

When a run starts in a repository nobody here has worked in, with no commit of yours, not one the seams have seen and no matching origin, it prints one line suggesting --untrusted. It suggests; it never switches the preset on for you.

Probation for what just arrived

An agent the daemon adopted, or an MCP server it wrapped, starts on probation for seven days. Its writes, outward and destructive actions ask whatever the rules allow, and its reads do not. The notice that announced it says so, and memnox status lists what is on probation and until when:

│   probation   Cursor until 2026-10-01
$memnox agents trust <agent>

End an agent's probation now, on the record, so only your rules decide what it does.

$memnox mcp trust <server>

The same for an MCP server.

A probation that was served or ended is never started again because a config file was rewritten. After the seven days only the rules decide, which is why the runtime's own threat model calls this partly covered rather than covered.