Opt-in, per-project execution sandbox: when enabled, a project's sessions run
`claude` inside an isolated Linux VM (Apple `container`) with the worktree
bind-mounted, instead of directly on the host. Off by default — existing
behavior is unchanged.
- Domain: ProjectSandbox (enabled/image/idleTimeout) on Project; ContainerSpec
on RunSpec/ResumeSpec.
- Persistence: migration v7 adds project.sandbox_config (JSON).
- ContainerRuntime: thin `container` CLI wrapper (preflight, default-image build,
run/exec/stop/delete/list, host-gateway discovery).
- ContainerManager: app-level per-session lifecycle — ensureRunning, idle
auto-stop, teardown, orphan reconcile.
- ClaudeCodeBackend: wraps the claude invocation in `container exec` when a
ContainerSpec is present; binds the approval MCP server on 0.0.0.0 and rewrites
its URL to the VM gateway so the containerized child can reach it.
- Repo root + worktree base mounted at identical paths (git links + cwd-hash
resolve); host ~/.claude mounted read-only and seeded into a writable
claude-home so credentials are never mutated but native resume still works.
- UI: ProjectSettingsSheet (toggle/image/idle) + "Sandboxed" badge; AppStore
gains updateProject.
- Tests: 9 new (arg construction, mount formatting, name parsing/derivation,
sandbox JSON round-trip, MCP host rewrite). 112 pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>