Sandbox auto write-protection of .claude/skills etc. is undocumented and cannot be lifted by allowWrite / Edit allow rules

Status Fixed / completed
Reported on v2.1.226
Maintainer reply None cached
Activity 1 comment · opened Aug 8, 2026 · closed Aug 11, 2026

Summary

The sandbox automatically write-denies <project>/.claude/{skills,agents,hooks,commands,workflows,...} and the corresponding ~/.claude/* paths, in addition to the documented protected set (settings.json at every scope, .mcp.json, symlink targets at protected settings paths). The documentation lists only the latter three. We found no documented mechanism can exempt specific paths from this auto-protection:

  1. sandbox.filesystem.allowWrite with an absolute path to <project>/.claude/skills does not lift it (the path stays read-only), while the same entry for a non-protected path works — the control was measured with the same config, so the mechanism itself is alive.
  2. A permissions.allow rule Edit(//abs/path/.claude/agents/**) does not lift it either, although the documented behavior ("Edit allow rules … grant write access to specific paths, the same way sandbox.filesystem.allowWrite does") demonstrably works for non-protected paths (control measured).
  3. Glob patterns in filesystem.allowWrite / denyWrite are skipped entirely on Linux/WSL (debug log: Skipping glob pattern on Linux/WSL), so extension-scoped grants (e.g. .../**/*.md) are impossible on this platform. A trailing /** is normalized away and behaves as a plain directory path.

Results were identical in-session (sandbox filesystem settings hot-reload — which also appears undocumented), in freshly rendered subagent policies, and in brand-new sessions.

Environment

  • Claude Code 2.1.226 (native build)
  • WSL2 (Ubuntu), bubblewrap sandbox, sandbox.enabled: true, failIfUnavailable: true

Repro

  1. In a project with the sandbox enabled, add to .claude/settings.local.json:

``json
{
"sandbox": { "filesystem": { "allowWrite": [
"/abs/path/to/project/.claude/skills",
"/abs/path/to/control-dir"
] } },
"permissions": { "allow": [
"Edit(//abs/path/to/project/.claude/agents/**)",
"Edit(//abs/path/to/control-dir2/**)"
] }
}
``

  1. From the Bash tool (same session — hot reload applies — or a new session):

``
touch .claude/skills/<existing>/SKILL.md # → Read-only file system
touch .claude/agents/<existing>.md # → Read-only file system
touch /abs/path/to/control-dir/x # → succeeds (allowWrite works)
touch /abs/path/to/control-dir2/x # → succeeds (Edit rule grants sandbox write)
``

  1. Add "/abs/path/to/control-dir3/**/*.txt" to allowWrite → the path gains nothing on Linux/WSL (inner glob silently skipped), while a trailing-/** entry behaves as a plain directory grant.

Impact

Whenever a merge touches these paths, git merge in the main working tree fails:

error: unable to unlink old '.claude/skills/...': Read-only file system

and after merges the local tree silently keeps stale copies of skills/agents/hooks. We work around this via git worktrees (the protection applies only to the project-dir literal path prefixes, so merges inside worktrees succeed) plus a SessionStart recovery hook — but that is reverse-engineered behavior, not documented contract.

Requests

  1. Document the actual protected set (it is much larger than the three documented items).
  2. Provide a supported way to exempt specific paths (e.g. .claude/skills) from the auto-protection without filesystem.disabled: true.
  3. Document that write-side glob patterns are unsupported on Linux/WSL (and the trailing-/** normalization).

Related

  • #56331 — same shape (config/ auto-added to denyWithinAllow, breaking git checkout across refs)
  • #40133 (closed/locked) — .claude/skills auto-add crashing bwrap on symlink layouts; filing a new issue per its lock notice
  • #84863 — adjacent: the agent editing its own sandbox settings; note that filesystem.allowWrite changes take effect mid-session (hot reload), which is relevant to that discussion

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗