diff --git a/README.md b/README.md
index 832a304..06eb466 100644
--- a/README.md
+++ b/README.md
@@ -1,87 +1,58 @@
-# Mudroom
-
-Run coding agents in a sandbox, then review their changes like a pull request
-before anything touches your project.
-
-Coding agents work best with permission prompts turned off, and that means
-they can delete files or reach any host while you aren't looking. Mudroom
-runs Claude Code, Codex, Gemini CLI, opencode, Aider (or any command) in a
-Linux micro-VM, on a copy-on-write clone of your project, with network access
-limited to the hosts you allow. Your real folder is never mounted. When the
-agent is done you read the diff, apply all of it, some files, some hunks or
-none, and undo any apply later.
-
-macOS app and CLI on Apple-silicon Macs. CLI only (with Docker or Podman) on
-Linux, Windows and Intel Macs.
-
-> Status: early prototype. Expect rough edges and breaking changes.
-
-
+
+
+
+
+
+
+
+**Mudroom** runs coding agents like Claude Code, Codex, Gemini CLI, opencode
+and Aider (or any command) on a clone of your project, inside a Linux
+micro-VM, with network access limited to the hosts you allow. When the agent
+is done, you review its changes like a pull request, apply all of it, some
+files, some hunks or none, and undo any apply later. It's a free, local
+alternative to cloud agent sandboxes, and your real folder is never mounted.
https://github.com/user-attachments/assets/ff599cbc-fbd9-4c8f-801d-fd2e52ccb0c6
-## Quick start
-
-1. Install (Apple-silicon Mac, macOS 26 or later):
+
33 seconds, with sound: the agent edits a clone in a VM, reaches only the hosts you allow, and you apply what you pick.
- ```sh
- curl -fsSL https://raw.githubusercontent.com/Kernel-Hunter/mudroom/main/install.sh | sh
- ```
+> **Status:** early prototype. Expect rough edges and breaking changes.
- Or with Homebrew: `brew install --cask kernel-hunter/tap/mudroom`
+## Install
- On Windows (CLI only), see [Install on Windows](#install-on-windows).
+The Mac app and CLI run on Apple-silicon Macs with macOS 26 or later. On
+Linux, Windows and Intel Macs, Mudroom is a CLI that uses Docker or Podman.
-2. Open Mudroom and work through the Setup window: install and start the VM
- runtime, build the agent image (a few minutes, once), and sign in an
- agent. `mudroom setup` does the same in a terminal.
-
-3. Click New Session, pick a folder and an agent, and start. When the agent
- finishes, review the diff in Mudroom and apply what you want.
-
-## Contents
-
-- [Requirements](#requirements)
-- [Install](#install)
-- [Setup](#setup)
-- [The app](#the-app)
-- [Command line](#command-line)
-- [Agents, sign-in and API keys](#agents-sign-in-and-api-keys)
-- [Keep files out of the sandbox](#keep-files-out-of-the-sandbox)
-- [Network](#network)
-- [Review and apply](#review-and-apply)
-- [Docker and Podman](#docker-and-podman)
-- [How it works](#how-it-works)
-- [How it compares](#how-it-compares)
-- [Limitations](#limitations)
-- [Development](#development)
+### macOS
-## Requirements
+With Homebrew, which also installs Apple's `container` CLI:
-| Platform | What you get | Sandbox backend |
-|---|---|---|
-| macOS 26+, Apple silicon | App and CLI | `apple` (Apple's `container`, one VM per session), or `docker`/`podman` |
-| macOS 26+, Intel | CLI only (build from source) | `docker` or `podman` |
-| Linux x86_64 and arm64 | CLI only (build from source) | `docker` or `podman` |
-| Windows 10/11, x86_64 and arm64 | CLI only ([release zip](#install-on-windows) or build from source) | `docker` (Docker Desktop) or `podman` (Podman machine) |
-
-The `apple` backend needs Apple's [`container`](https://github.com/apple/container)
-CLI, version 1.5 or later. Setup installs it with Homebrew if you don't have
-it.
-
-The CLI picks a backend with `--backend apple|docker|podman|auto` (or
-`MUDROOM_BACKEND`). `auto`, the default, uses Apple's `container` on an
-Apple-silicon Mac with macOS 26+ where it is installed, otherwise Docker,
-otherwise Podman. A session remembers its backend, so `mudroom start` uses
-the same one again. See [Docker and Podman](#docker-and-podman) for how
-isolation differs from the VM backend.
+```sh
+brew install --cask kernel-hunter/tap/mudroom
+```
-## Install
+Or with the install script:
```sh
curl -fsSL https://raw.githubusercontent.com/Kernel-Hunter/mudroom/main/install.sh | sh
```
+
+What the install script does, and how to uninstall
+
+
+
The script needs macOS 26 or later on Apple silicon. It downloads the latest
release, checks its SHA-256 when the release publishes one, puts Mudroom.app
in /Applications (or ~/Applications if /Applications isn't writable) and
@@ -93,27 +64,52 @@ version. To remove Mudroom (your sessions and settings stay):
curl -fsSL https://raw.githubusercontent.com/Kernel-Hunter/mudroom/main/install.sh | sh -s -- --uninstall
```
-Or with Homebrew, which also installs Apple's `container` CLI:
+
-```sh
-brew install --cask kernel-hunter/tap/mudroom
-```
+
+About signing and Gatekeeper
+
+
Mudroom is ad-hoc signed, not notarized. The install script and the Homebrew
cask remove the quarantine flag, so macOS opens it. If you download the zip
in a browser, use System Settings > Privacy & Security > Open Anyway, or run
`xattr -dr com.apple.quarantine /Applications/Mudroom.app`.
+
+
+On an Intel Mac, the CLI works with Docker or Podman; [build it from
+source](#build-from-source).
+
### Install on Windows
-With [Scoop](https://scoop.sh):
+CLI only, Windows 10/11 on x86_64 or arm64. With [Scoop](https://scoop.sh):
```powershell
scoop bucket add kernel-hunter https://github.com/Kernel-Hunter/scoop-bucket
scoop install mudroom
```
-Without Scoop: each release has a zip for x86_64 and one for arm64:
+Then install a container runtime: [Docker Desktop](https://docs.docker.com/desktop/setup/install/windows-install/)
+with the WSL 2 backend (Linux containers, the default), or
+[Podman](https://podman.io/docs/installation#windows) with a Podman machine
+(`podman machine init`, then `podman machine start`). Build the agent image
+once and check the network:
+
+```powershell
+mudroom image build --backend docker # or --backend podman
+mudroom network check --backend docker
+```
+
+Run `mudroom` from Windows Terminal or any console with VT support. See
+[Windows](#windows-1) for what is different from macOS and Linux.
+
+
+Without Scoop: install from the release zip
+
+
+
+Each release has a zip for x86_64 and one for arm64:
`mudroom--windows-x86_64.zip` and `mudroom--windows-arm64.zip`
on the [Releases](https://github.com/Kernel-Hunter/mudroom/releases/latest)
page, each with a `.sha256`. The zip holds a folder with `mudroom.exe` and
@@ -139,21 +135,295 @@ line. `mudroom.exe` isn't code-signed; if Windows blocks it after you unzip
with Explorer, run `Get-ChildItem $dir | Unblock-File`.
The Scoop and winget manifests are in [packaging/scoop](packaging/scoop)
-and [packaging/winget](packaging/winget).
+and [packaging/winget](packaging/winget). The winget package is waiting for
+review in the winget repository, so `winget install` doesn't find it yet.
-Then install a container runtime: [Docker Desktop](https://docs.docker.com/desktop/setup/install/windows-install/)
-with the WSL 2 backend (Linux containers, the default), or
-[Podman](https://podman.io/docs/installation#windows) with a Podman machine
-(`podman machine init`, then `podman machine start`). Build the agent image
-once and check the network:
+
-```powershell
-mudroom image build --backend docker # or --backend podman
-mudroom network check --backend docker
+### Linux
+
+CLI only, x86_64 and arm64, built from source. You need Swift 6.2 or later
+([swift.org/install](https://www.swift.org/install/)) and Docker Engine or
+Podman.
+
+
+Build and install the CLI
+
+
+
+```sh
+git clone https://github.com/Kernel-Hunter/mudroom
+cd mudroom
+swift build -c release
+cp .build/release/mudroom /usr/local/bin/ # or anywhere on your PATH
+mudroom image build --backend docker # or --backend podman, once
+mudroom network check --backend docker # see what the sandbox can reach
```
-Run `mudroom` from Windows Terminal or any console with VT support. See
-[Windows](#windows-1) for what is different from macOS and Linux.
+
+
+## Quick start
+
+In the app:
+
+1. Open Mudroom and work through the Setup window: install and start the VM
+ runtime, build the agent image (a few minutes, once), and sign in an
+ agent.
+2. Click New Session, pick a folder and an agent, and start.
+3. When the agent finishes, review the diff in Mudroom and apply what you
+ want.
+
+From a terminal. On Linux and Windows the same commands use Docker, or
+Podman when Docker isn't there; `--backend` picks one.
+
+```sh
+# Once: start the VM runtime, build the agent image, sign in an agent
+mudroom setup
+
+# Run an agent on a clone of your project
+mudroom run ~/code/myapp -- claude --dangerously-skip-permissions
+
+# Read the diff, pick files or hunks, press x to apply
+mudroom review last
+
+# See what the agent connected to, and what was blocked
+mudroom network log last
+
+# Changed your mind
+mudroom undo last
+```
+
+## Features
+
+Coding agents work best with permission prompts turned off, and that means
+they can delete files or reach any host while you aren't looking. Mudroom
+puts a sandbox and a review step between the agent and your project.
+
+- **Your folder stays untouched.** The agent edits a copy-on-write clone
+ (APFS, or a reflink on btrfs and XFS), untracked and ignored files
+ included, minus `.env` files and keys. Your project is never mounted.
+- **A VM per session.** Apple's `container` boots one lightweight Linux VM
+ for each session. Docker and Podman work too, with gVisor or Kata if you
+ have them.
+- **Network allowlist.** Locked by default: no DNS and no route out. The
+ only exit is a proxy on your machine that lets through the agent's API
+ hosts plus the ones you add.
+- **A log of every connection.** In locked mode: host, port, bytes, allowed
+ or blocked, and which program in the sandbox opened it
+ (`git-remote-https`, `node`, `python3`).
+- **Keys stay out.** `.env` files, `*.pem`, SSH keys and `.netrc` are left
+ out of the agent's copy by default. Edit the list per project or with a
+ `.mudroomignore`.
+- **Review like a pull request.** Files grouped by change, unified or
+ side-by-side diffs, a checkbox per file and per hunk. Your own edits since
+ the start are flagged, never overwritten.
+- **Undo and snapshots.** Any apply can be undone in one step, even one
+ killed halfway. Snapshots taken every 5 minutes show what changed after
+ any point.
+- **Any agent, your sign-in.** Five agents set up for you, or any command.
+ Sign in with your Claude account, the ChatGPT and Google logins you
+ already have, API keys, or local models.
+
+### Pick what to keep, file by file or hunk by hunk
+
+Changed files are grouped into Added, Modified, Deleted and Mode & Type,
+each with a checkbox, next to a unified or side-by-side diff. Modified text
+files have a checkbox per hunk, so you can take some edits and leave others.
+
+
+
+
+
+
+### See every host the agent tried to reach
+
+The Network tab lists blocked hosts first, with bytes and connection
+counts. Allow adds a blocked host to the project's allowlist for the next
+session.
+
+
+
+
+
+
+### Your own edits are never overwritten
+
+Files you changed yourself since the session started are flagged in the
+list and above the diff. Apply leaves them alone and takes the rest.
+
+
+
+### Look back at any point in the run
+
+Snapshots are taken while the agent works. Move the timeline slider and the
+file list shows only what changed after that point.
+
+
+
+## How it compares
+
+How the usual ways of running an agent differ, in their default setup:
+
+| | Edits reach your folder | Network |
+|---|---|---|
+| Agent on your machine | Right away | Anything your machine reaches |
+| Dev container | Right away | Open by default |
+| Cloud sandbox | When you pull them | Depends on the provider |
+| **Mudroom** | **When you apply them** | **Allowlist, each connection logged** |
+
+
+The full comparison
+
+
+
+**Agent on your machine**
+
+- Where it edits: your real folder, and edits land right away.
+- Boundary: your user account, plus the agent's own prompts or sandbox.
+- Network: anything your machine reaches, unless the agent's own sandbox
+ limits it.
+- Review: `git diff`, or per-edit prompts.
+- Your code leaves your machine: only what the agent sends.
+- Account or bill for the sandbox: none.
+
+**Dev container**
+
+- Where it edits: your folder, usually bind-mounted, and edits land right
+ away.
+- Boundary: a container (the host's kernel on Linux).
+- Network: open by default.
+- Review: `git diff`.
+- Your code leaves your machine: only what the agent sends.
+- Account or bill for the sandbox: none.
+
+**Cloud sandbox**
+
+- Where it edits: a copy on the provider's servers. Edits reach your folder
+ when you pull or download them.
+- Boundary: the provider's VM or container.
+- Network: depends on the provider.
+- Review: through git or the provider's tools.
+- Your code leaves your machine: yes, it runs remotely.
+- Account or bill for the sandbox: a provider account, usually paid by
+ usage.
+
+**Mudroom**
+
+- Where it edits: a clone; your folder is never mounted. Edits reach your
+ folder when you apply them.
+- Boundary: one micro-VM per session, or a container with Docker or Podman.
+- Network: allowlist through a proxy (locked mode, the default), each
+ connection logged with the command that opened it.
+- Review: review app or terminal screen, per file and per hunk, with undo.
+- Your code leaves your machine: only what the agent sends to allowed
+ hosts.
+- Account or bill for the sandbox: none, MIT.
+
+
+
+A dev container gives you a reproducible toolchain, and a cloud sandbox runs
+many agents in parallel without using your machine. Mudroom does neither: it
+runs on your own computer, the review app needs a Mac with macOS 26, and the
+agent image is one general-purpose image unless you pass your own with
+`--image`.
+
+### Other agent sandboxes
+
+Checked against each project's docs on 2026-09-30. Corrections welcome.
+
+- **Mudroom.** Linux micro-VM, on an APFS clone; your folder is never
+ mounted. The agent's writes reach your folder when you apply them, after
+ a diff review per file and per hunk, with undo.
+- **[Docker Sandboxes](https://docs.docker.com/ai/sandboxes/security/).**
+ A microVM, with your folder mounted read-write by default, or a private
+ git clone with `--clone`. Writes reach your folder right away by default;
+ with `--clone`, when you fetch. Review goes through git, in clone mode.
+- **[Apple's `sandboxy` example](https://github.com/apple/containerization/tree/main/examples/sandboxy).**
+ A Linux VM with your folder shared in. Writes land right away, with no
+ review step.
+- **[ArcBox](https://github.com/arcboxlabs/arcbox/blob/master/docs/agent-sandbox.md).**
+ A microVM with nothing mounted. Only what you copy out reaches your
+ folder, with no review step.
+- **[Claude Code sandboxing](https://code.claude.com/docs/en/sandboxing).**
+ Your real folder, with OS-level limits (no VM). Writes land right away,
+ with per-edit prompts unless you skip permissions.
+
+If your project is a git repo and you're happy reviewing with git, Docker
+Sandboxes' `--clone` mode gets you close. Mudroom also covers untracked and
+ignored files and folders that aren't repos, and gives you a review screen
+and per-apply undo.
+
+## How it works
+
+```mermaid
+flowchart TD
+ P["Your project"] -->|"copy-on-write clone"| W["Session copy"]
+ W -->|"mounted at /workspace"| A
+ subgraph VM["Linux micro-VM or container"]
+ A["Coding agent"]
+ end
+ A -->|"only way out"| X["Allowlist proxy"]
+ X -->|"allowed hosts"| N(("Internet"))
+ W --> R["Diff review"]
+ R -->|"apply what you pick"| P
+ R -.->|"undo"| P
+```
+
+1. Mudroom clones the project twice: `base/` is the starting point and `work/`
+ is what the agent edits. On APFS the clones take no extra disk until files
+ change.
+2. The agent runs in its own VM (or container) with only `work/` inside. In
+ locked mode its one way out is the proxy, which checks every host against
+ the project's allowlist and logs the connection.
+3. You review `base/` against `work/` in the app or the terminal and apply
+ what you pick. Mudroom checks that each file in your project still matches
+ `base/`, so your own edits are never overwritten. Any apply can be undone.
+
+More detail in [Under the hood](#under-the-hood), [Network](#network) and
+[Review and apply](#review-and-apply).
+
+
+
+## Documentation
+
+The rest of this page is the full reference:
+[Requirements](#requirements) ·
+[Build from source](#build-from-source) ·
+[Setup](#setup) ·
+[The app](#the-app) ·
+[Command line](#command-line) ·
+[Agents, sign-in and API keys](#agents-sign-in-and-api-keys) ·
+[Keep files out of the sandbox](#keep-files-out-of-the-sandbox) ·
+[Network](#network) ·
+[Review and apply](#review-and-apply) ·
+[Docker and Podman](#docker-and-podman) ·
+[Under the hood](#under-the-hood) ·
+[Limitations](#limitations) ·
+[FAQ](#faq) ·
+[Development](#development)
+
+## Requirements
+
+- **macOS 26+, Apple silicon:** app and CLI. Sandbox backend `apple`
+ (Apple's `container`, one VM per session), or `docker`/`podman`.
+- **macOS 26+, Intel:** CLI only (build from source), with `docker` or
+ `podman`.
+- **Linux x86_64 and arm64:** CLI only (build from source), with `docker`
+ or `podman`.
+- **Windows 10/11, x86_64 and arm64:** CLI only ([release
+ zip](#install-on-windows) or build from source), with `docker` (Docker
+ Desktop) or `podman` (Podman machine).
+
+The `apple` backend needs Apple's [`container`](https://github.com/apple/container)
+CLI, version 1.5 or later. Setup installs it with Homebrew if you don't have
+it.
+
+The CLI picks a backend with `--backend apple|docker|podman|auto` (or
+`MUDROOM_BACKEND`). `auto`, the default, uses Apple's `container` on an
+Apple-silicon Mac with macOS 26+ where it is installed, otherwise Docker,
+otherwise Podman. A session remembers its backend, so `mudroom start` uses
+the same one again. See [Docker and Podman](#docker-and-podman) for how
+isolation differs from the VM backend.
### Build from source
@@ -173,13 +443,8 @@ swift build -c release
cp .build/release/mudroom /usr/local/bin/ # or anywhere on your PATH
```
-On Linux you need Swift 6.2 or later ([swift.org/install](https://www.swift.org/install/))
-and Docker Engine or Podman. Then build the agent image once:
-
-```sh
-mudroom image build --backend docker # or --backend podman
-mudroom network check --backend docker # see what the sandbox can reach
-```
+On Linux you also need Docker Engine or Podman and the agent image; see
+[Linux](#linux).
#### Windows
@@ -223,7 +488,7 @@ Mudroom > Setup, and the sidebar tells you when a step needs attention. If
the VM runtime stops later (after a reboot, say), starting a session starts
it again.
-
+
In a terminal:
@@ -262,11 +527,27 @@ claude`.
**Discard** (⌘⌫). Each apply can be undone in one step. Space toggles the
selected file.
-| | |
-|---|---|
-|  |  |
-|  |  |
-|  |  |
+The Network tab, the timeline and conflicts are shown under
+[Features](#features).
+
+
+More screenshots
+
+
+
+Dark mode, split diff:
+
+
+
+After a partial apply:
+
+
+
+New session:
+
+
+
+
Agents are interactive terminal programs, and you often need to answer them,
so sessions run in Terminal.app instead of a terminal built into Mudroom. The
@@ -277,7 +558,12 @@ to date.
The review app is macOS only. Elsewhere, `mudroom review ` is a
terminal review screen: toggle files, read diffs, pick single hunks and apply
-the selection. Its keys:
+the selection.
+
+
+Keys in mudroom review
+
+
- File list: up/down or j/k move, space toggles a file, a toggles all, enter
opens the file, x applies the selection after a y/N prompt, q quits.
@@ -290,6 +576,8 @@ the selection. Its keys:
4 MB) open as a plain diff and are applied whole: up/down scroll, space/b
page, q back.
+
+
Whole files and selected hunks go into the project in one apply, so one
`mudroom undo` takes all of it back. `mudroom diff`, `hunks` and `apply` do
the same from scripts.
@@ -370,12 +658,16 @@ instead). Aider needs either a provider key or a model named with `--model`;
without one, the session stops right away with a message instead of waiting
for a sign-in that can't finish inside the VM.
-| Agent | Ways to sign in |
-|---|---|
-| Claude Code | Your Claude account (`claude setup-token` on the Mac), a sign-in inside the VM, or `ANTHROPIC_API_KEY` |
-| Codex | Your existing ChatGPT login (`~/.codex/auth.json`), a device code, or an OpenAI API key |
-| Gemini CLI | Your existing Google login (`~/.gemini/oauth_creds.json`), a sign-in inside the VM, or `GEMINI_API_KEY` |
-| opencode, Aider, custom commands | Any provider API key, or local models |
+Ways to sign in, per agent:
+
+- **Claude Code:** your Claude account (`claude setup-token` on the Mac), a
+ sign-in inside the VM, or `ANTHROPIC_API_KEY`.
+- **Codex:** your existing ChatGPT login (`~/.codex/auth.json`), a device
+ code, or an OpenAI API key.
+- **Gemini CLI:** your existing Google login (`~/.gemini/oauth_creds.json`),
+ a sign-in inside the VM, or `GEMINI_API_KEY`.
+- **opencode, Aider, custom commands:** any provider API key, or local
+ models.
### Claude Code: your Claude account
@@ -432,6 +724,11 @@ mudroom agent login gemini # Gemini CLI's own sign-in screen
mudroom agent status # signed in or not, per agent
```
+
+How the sign-in link gets out of the sandbox
+
+
+
Copying a sign-in link out of a terminal is fragile: it wraps over several
lines, and losing the end gives errors such as "Invalid
code_challenge_method". So each run sets `BROWSER` in the sandbox to a small
@@ -446,6 +743,8 @@ the rest of the request (PKCE challenge, state) unchanged. After signing in,
paste the code back: in Setup into the code field, in a terminal where the
prompt is (the agent's prompt doesn't echo it).
+
+
### Agent config directories
Each agent gets its own config directory,
@@ -591,6 +890,11 @@ Like the network commands, these work on the current directory, or take
of the sandbox" section that shows what the chosen folder would leave out
and lets you add and remove patterns.
+
+Pattern syntax
+
+
+
Patterns use `.gitignore` syntax, relative to the project root:
- `name` matches a file or folder with that name at any depth. `/name` and
@@ -609,6 +913,8 @@ Patterns use `.gitignore` syntax, relative to the project root:
`.ENV` is caught too: on a default APFS or NTFS disk it is the same file as
`.env`. On Windows, trailing dots and spaces are ignored as well.
+
+
A `.mudroomignore` file at the project root, in the same syntax, adds
patterns for everyone who uses the project, and can be committed. It can only
add: a `!` line in it takes back a pattern from the same file, never one from
@@ -670,14 +976,17 @@ Each project has a mode:
The allowlist is the agent's own hosts plus whatever you add:
-| Agent | Default hosts |
-|---|---|
-| Claude Code | api.anthropic.com, console.anthropic.com, platform.claude.com, claude.ai |
-| Codex | api.openai.com, chatgpt.com, auth.openai.com |
-| Gemini CLI | generativelanguage.googleapis.com, cloudcode-pa.googleapis.com, oauth2.googleapis.com, www.googleapis.com |
-| opencode | models.opencode.ai, models.dev (its model catalog), plus the API host of each key you set |
-| Aider, custom commands | the API host of each key you set |
-| Package registries (off by default) | registry.npmjs.org, pypi.org, files.pythonhosted.org, github.com, codeload.github.com, *.githubusercontent.com |
+- **Claude Code:** api.anthropic.com, console.anthropic.com,
+ platform.claude.com, claude.ai
+- **Codex:** api.openai.com, chatgpt.com, auth.openai.com
+- **Gemini CLI:** generativelanguage.googleapis.com,
+ cloudcode-pa.googleapis.com, oauth2.googleapis.com, www.googleapis.com
+- **opencode:** models.opencode.ai, models.dev (its model catalog), plus the
+ API host of each key you set
+- **Aider, custom commands:** the API host of each key you set
+- **Package registries (off by default):** registry.npmjs.org, pypi.org,
+ files.pythonhosted.org, github.com, codeload.github.com,
+ `*.githubusercontent.com`
Telemetry and error-reporting hosts are left out; Claude Code runs with
`CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1` so it doesn't try them. Patterns
@@ -720,7 +1029,12 @@ the pid (`pid`) and the command lines of its parents up to the agent
(`parents`, nearest first). The app shows the command in the connection list,
with the parents in its tooltip, and the programs under each host.
-How it works: a small bash script, the watcher, runs inside the VM next to
+
+How the connection watcher works
+
+
+
+A small bash script, the watcher, runs inside the VM next to
the agent. It reads TCP's connection counter in `/proc/net/snmp` every 100 ms
(every 20 ms for a second after a connection opens), and when it changed,
looks in `/proc/net/tcp` and `tcp6` for new connections to the proxy. It finds
@@ -741,6 +1055,8 @@ user, and the forwarder container passes each client's source port to the
proxy in a PROXY protocol line. The image needs bash (Mudroom's has it);
without it the log simply has no commands.
+
+
Limits:
- It is informational, not a security boundary. The allowlist is decided on
@@ -956,6 +1272,11 @@ Networks:
listens on 127.0.0.1, which Docker Desktop forwards `host.docker.internal`
to.
+
+Network check output with Docker
+
+
+
`mudroom network check --backend docker`, locked mode, gave this on Docker
Desktop (engine 29.8) on macOS 27, and the same apart from addresses on
Docker Engine 29.1 on Ubuntu 24.04 arm64 (run nested in a privileged
@@ -978,6 +1299,8 @@ has no host address, so services on the host aren't reachable, and no
firewall inside the container is needed. (This output is from before the
check opened a port of its own; it now probes that port instead of 7000.)
+
+
### How strong is the isolation
A container is not a VM. On Linux, Docker and Podman containers share the
@@ -1069,7 +1392,7 @@ on it. What is different from macOS and Linux:
`host.containers.internal` doesn't lead to Windows, and locked mode
can't work.
-## How it works
+## Under the hood
```
~/Library/Application Support/Mudroom/ (Linux: ~/.local/share/mudroom/, Windows: %LOCALAPPDATA%\Mudroom\)
@@ -1123,20 +1446,6 @@ container in its own lightweight VM, and one to `docker` or `podman`. The
proxy is plain BSD sockets (Winsock on Windows), so it runs the same on
macOS, Linux and Windows.
-## How it compares
-
-Checked against each project's docs on 2026-09-30. Corrections welcome.
-
-| | Where the agent works | When its writes reach your folder | Review before they land |
-|---|---|---|---|
-| Mudroom | Linux micro-VM, on an APFS clone; your folder is never mounted | When you apply | Diff app, per file and per hunk, with undo |
-| [Docker Sandboxes](https://docs.docker.com/ai/sandboxes/security/) | microVM; your folder mounted read-write by default, or a private git clone with `--clone` | Right away by default; with `--clone`, when you fetch | Through git, in clone mode |
-| [Apple's `sandboxy` example](https://github.com/apple/containerization/tree/main/examples/sandboxy) | Linux VM with your folder shared in | Right away | No |
-| [ArcBox](https://github.com/arcboxlabs/arcbox/blob/master/docs/agent-sandbox.md) | microVM with nothing mounted | Only what you copy out | No |
-| [Claude Code sandboxing](https://code.claude.com/docs/en/sandboxing) | Your real folder, with OS-level limits (no VM) | Right away | Per-edit prompts, unless you skip permissions |
-
-If your project is a git repo and you're happy reviewing with git, Docker Sandboxes' `--clone` mode gets you close. Mudroom also covers untracked and ignored files and folders that aren't repos, and gives you a review screen and per-apply undo.
-
## Limitations
- **With the apple backend, the Mac's own services are blocked by a firewall
@@ -1182,6 +1491,115 @@ If your project is a git repo and you're happy reviewing with git, Docker Sandbo
- The app is ad-hoc signed, not notarized. See [Install](#install) for what
that means when you download it.
+## FAQ
+
+
+Does the agent ever touch my real project folder?
+
+
+
+No. The agent edits `work/`, a clone in Mudroom's own data folder, and your
+project is never mounted into the sandbox. Files change in your project only
+when you apply them, and each apply can be undone. See [How apply stays
+safe](#how-apply-stays-safe).
+
+
+
+
+What if I edit a file while the agent is working?
+
+
+
+Apply checks each file in your project against the session's starting copy.
+A file you changed is reported as a conflict and left alone; the rest still
+applies.
+
+
+
+
+Can the agent read my .env or SSH keys?
+
+
+
+Not by default. `.env` files, `*.pem`, `*.key`, SSH private keys and `.netrc`
+are left out of the agent's copy. The list matches names, not contents, so a
+key pasted into another file is still copied. See [Keep files out of the
+sandbox](#keep-files-out-of-the-sandbox).
+
+
+
+
+Do I need an API key?
+
+
+
+Not for Claude Code, Codex or Gemini CLI: Mudroom can use your Claude
+account, or the ChatGPT and Google logins you already have. opencode, Aider
+and custom commands need a provider key (OpenRouter works for most models)
+or local models through Ollama or LM Studio. See [Agents, sign-in and API
+keys](#agents-sign-in-and-api-keys).
+
+
+
+
+Can I use it on Linux or Windows?
+
+
+
+Yes, as a CLI with Docker or Podman. There is no review app there:
+`mudroom review` is a terminal review screen with per-file and per-hunk
+selection. On Linux a container shares the host's kernel, so the isolation
+is weaker than the VM backend on a Mac. See [How strong is the
+isolation](#how-strong-is-the-isolation).
+
+
+
+
+Why does the agent run in Terminal and not inside the app?
+
+
+
+Agents are interactive terminal programs and you often need to answer them,
+so the app opens each session in Terminal.app and follows its progress
+through `session.json`.
+
+
+
+
+How much disk does a session use?
+
+
+
+On APFS the clones take no extra disk until files change. The agent image
+is about 1.5 GB, built once. If the project is on a disk that can't clone,
+Mudroom falls back to plain copies.
+
+
+
+
+Is the network log a security boundary?
+
+
+
+No. The allowlist is enforced by the proxy on your machine. The note about
+which command opened each connection comes from a watcher inside the VM, and
+a hostile agent can mislead it. See [Which process made each
+connection](#which-process-made-each-connection).
+
+
+
+
+macOS says Mudroom can't be opened. What now?
+
+
+
+Mudroom is ad-hoc signed, not notarized. The Homebrew cask and the install
+script remove the quarantine flag for you. For a zip downloaded in a browser,
+use System Settings > Privacy & Security > Open Anyway, or run
+`xattr -dr com.apple.quarantine /Applications/Mudroom.app`.
+
+
+
## Development
```sh
@@ -1212,8 +1630,19 @@ The proxy tests run it against a loopback test server. The app target is
platforms). `MudroomCore` has no UI code; the app and the CLI both sit on
top of it.
+## Contributing
+
+Bug reports, corrections to the comparison tables and pull requests are
+welcome. Open an [issue](https://github.com/Kernel-Hunter/mudroom/issues) for
+a bug or an idea. For code, `swift build` and `swift test` run without a VM on
+macOS, Linux and Windows (see [Development](#development)), and
+`mudroom network check` tests isolation on a real sandbox.
+
+If Mudroom is useful to you, a star helps other people find it.
+
## License
MIT. See [LICENSE](LICENSE).
Built by [Karim Masmoudi](https://github.com/Kernel-Hunter). My other projects are at [karimmasmoudi.vercel.app](https://karimmasmoudi.vercel.app/projects/).
+
diff --git a/docs/assets/mudroom-banner-dark.png b/docs/assets/mudroom-banner-dark.png
new file mode 100644
index 0000000..db6fb5e
Binary files /dev/null and b/docs/assets/mudroom-banner-dark.png differ
diff --git a/docs/assets/mudroom-banner-light.png b/docs/assets/mudroom-banner-light.png
new file mode 100644
index 0000000..4e92664
Binary files /dev/null and b/docs/assets/mudroom-banner-light.png differ