6.1 KiB
| phase | plan | subsystem | tags | dependency-graph | tech-stack | key-files | decisions | metrics | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 05-per-project-instance-isolation | 01 | sandbox-mount-architecture |
|
|
|
|
|
|
Phase 05 Plan 01: Mount Architecture Rewrite and Per-Project Instance Isolation Summary
Direct bind of ~/.claude into sandbox with SHA-256-keyed per-project overlay mounts, replacing the old ~/.claudebox symlink approach that hid all plugins, skills, hooks, and MCP configs from Claude Code.
What Was Built
Mount Architecture Rewrite (claudebox.sh)
Replaced the old mount approach (--bind ~/.claudebox ~/.claudebox + --symlink ~/.claudebox ~/.claude) with a new architecture:
--bind "$HOME/.claude" "$HOME/.claude"— direct bind, makes all Claude Code config (plugins, skills, hooks, MCP, commands, settings) visible inside the sandbox (D-01)--bind "$INSTANCE_DIR" "$HOME/.claude/projects"— per-project overlay; each project gets its own isolated directory mounted over the real~/.claude/projects/(D-02, INST-01)--bind "$HOME/.claudebox/history.jsonl" "$HOME/.claude/history.jsonl"— history overlay; conversation history stored sandbox-side (D-03)--bind "$HOME/.claudebox/SANDBOX.md" "$HOME/.claude/SANDBOX.md"— SANDBOX.md injected as file overlay (D-06)--bind "$CREDS_FILE" "$HOME/.claude/.credentials.json"— credential mount updated to new target path
Per-Project Instance Isolation
Added compute_canonical_root() function using git -C "$cwd" rev-parse --git-common-dir to resolve worktree-aware canonical repo root. Git worktrees return a path pointing to the main worktree's .git/, so dirname(readlink -f(git_common)) gives the main worktree root for any worktree.
Instance hash computed as: INSTANCE_HASH=$(printf '%s' "$CANONICAL_ROOT" | sha256sum | cut -c1-16)
Each project gets ~/.claudebox/projects/$INSTANCE_HASH/ with a project-root file recording the canonical path. Directory created at startup with mkdir -p.
Removed
- Old
--symlink "$HOME/.claudebox" "$HOME/.claude"(D-01 replacement) - Old
--bind "$HOME/.claudebox" "$HOME/.claudebox"(D-01 replacement) - CLAUDE.md injection block (
CLAUDEMD="$HOME/.claudebox/CLAUDE.md") — user's real~/.claude/CLAUDE.mdalready has@SANDBOX.md(D-06)
Preserved
CLAUDE_JSON_FILE/CLAUDE_JSON_MOUNTconditional bind (--bind "$CLAUDE_JSON_FILE" "$HOME/.claude.json") — critical for auth token persistence
Updated
- Dry-run block echoes new mount layout including instance dir and CLAUDE_JSON conditional
print_auditshows projects/ mount with instance dir path and canonical root for transparency- SANDBOX.md heredoc updated to remove
~/.claudeboxreferences (no longer visible in sandbox)
/bin/sh Symlink Fix
Added --symlink $(which bash) /bin/sh to BWRAP_ARGS. Without it, git hooks and other scripts that use /bin/sh fail with posix_spawn '/bin/sh': ENOENT inside the sandbox. Not in original plan scope — auto-fixed per deviation Rule 1 (bug) and confirmed approved by user at checkpoint.
Requirements Registration
Added INST-01 through INST-04 to .planning/REQUIREMENTS.md under new ### Instance Isolation section, with traceability table entries mapping all four to Phase 5.
Verification Results
bash -n claudebox.shpasses (syntax clean)compute_canonical_rootpresent in claudebox.shINSTANCE_HASHcomputation present in claudebox.sh- New mount lines confirmed present via search
- Old symlink/claudebox bind lines confirmed absent
- Human checkpoint approved by user
Deviations from Plan
Auto-fixed Issues
1. [Rule 1 - Bug] Added /bin/sh symlink so hooks can exec sh
- Found during: Task 1 (anticipated based on bwrap behavior + user confirmation at checkpoint)
- Issue: Sandbox has no
/bin/sh— git hooks and POSIX scripts that call/bin/shfail withposix_spawn '/bin/sh': ENOENT - Fix: Added
--symlink $(which bash) /bin/shto BWRAP_ARGS - Files modified: claudebox.sh
- Commit:
4baf576
Known Stubs
None. All mount architecture changes are fully wired. Per-project instance dirs are created and used at runtime. No placeholder data flows to any UI or output.
Threat Flags
None. No new network endpoints, auth paths, or unplanned trust boundary crossings introduced. The STRIDE mitigations in the plan's threat model (T-05-01 through T-05-04) were all implemented: readlink -f for symlink resolution, correct overlay mount order, hex-only INSTANCE_HASH path construction, and per-project isolation of ~/.claude/projects/.
Self-Check: PASSED
- FOUND: claudebox.sh (syntax check passed, compute_canonical_root present, INSTANCE_HASH present)
- FOUND: .planning/REQUIREMENTS.md (INST-01 through INST-04 present)
- FOUND: commit
c5e8cca(mount architecture rewrite) - FOUND: commit
6eb3b46(INST-01 through INST-04 registration) - FOUND: commit
4baf576(/bin/sh symlink fix)