Prevent cbox sandboxes from mutating host git common-dir
Problem
Sandbox containers currently mount the host repo common .git directory writable at /workspace/.repo-git. Diagnose and fix the isolation bug so sandbox git operations cannot corrupt the host checkout while still supporting task execution or failing safely when full git writes are unavailable.
Context
The container mounting logic lives in libs/cbox/cbox/container.py. The _build_base_command method constructs Docker volume mounts for all container types (sandboxes, reviews, tests). It calls _mount_worktree_git to mount the host's git common-dir inside the container.
The read_only flag passed to _mount_worktree_git was coupled to read_only_workspace — a flag that controls whether the workspace is mounted read-only. Review containers use read_only_workspace=True (so git common-dir was also :ro). Sandbox containers use read_only_workspace=False (writable workspace needed for code changes), which inadvertently made the git common-dir writable too.
This meant sandbox containers could mutate shared git state: refs, objects, packed-refs, hooks, config — potentially corrupting the host checkout or other worktrees.
Key files:
- libs/cbox/cbox/container.py:367-375 — the bug site
- libs/cbox/test_container_runtime.py — container mount tests
Prior work: M1-INFRA-014 fixed worktree gitdir path isolation (container-internal paths instead of host paths) but did not address the read/write permission on the mount itself.
Possible Solutions
Option A: Always mount git common-dir read-only
Decouple the git mount's read-only flag from the workspace read-only flag. Always pass read_only=True to _mount_worktree_git. One-line change. Git write operations inside the sandbox (commit, branch create, etc.) will fail with standard git "read-only filesystem" errors.
Trade-offs: Sandboxes can't create commits directly. This is acceptable because sandbox work is pushed via the host, and the task spec explicitly allows "failing safely when full git writes are unavailable."
Option B: Read-only mount + writable overlay for worktree-specific subdir
Mount git common-dir :ro but overlay a tmpfs or named volume at the worktree-specific subdirectory (.repo-git/worktrees/<name>/) so git add/git status work. More complex, more risk.
Option C: Copy-on-write / full git clone inside container
Give the sandbox its own independent .git directory. High isolation but significant startup cost and storage overhead.
Recommended: Option A — smallest reliable fix, zero risk of host mutation, clear failure mode. Option B can be layered on later if sandbox git writes are needed.
Plan
- Write a failing test that asserts sandbox git common-dir is mounted
:ro(TDD) - Change
_build_base_commandto always passread_only=Trueto_mount_worktree_git - Update existing test that expected writable mount to expect
:ro - Run full test suite to confirm no regressions
Files modified:
- libs/cbox/cbox/container.py — one-line fix at the _mount_worktree_git call site
- libs/cbox/test_container_runtime.py — new regression test + updated existing assertion
Implementation Progress
Fix applied (one-line change)
In _build_base_command, changed:
read_only=read_only_workspace,
to:
read_only=True,
This ensures the git common-dir volume mount always gets the :ro suffix, regardless of whether the workspace itself is writable.
Tests
- New test
test_sandbox_mounts_git_common_dir_read_only: creates a mock worktree, builds a sandbox command withread_only_workspace=False, and asserts the.repo-gitmount ends with:ro. - Updated
test_worktree_mount_uses_container_internal_paths: assertion updated from:/workspace/.repo-gitto:/workspace/.repo-git:ro. - All 27 container runtime tests pass.
- All 2604 main project tests pass (76 skipped, 3 xfailed).
- Pre-existing failures in
test_default_parent_branch.pyandtest_sandbox_start.pyare unrelated (fail on main too).
Review Feedback
- [ ] Review cleared