Sandbox/permission behaviour changes in patch releases aren't in the CHANGELOG — headless claude -p integrations must re-validate every update
Summary
Headless integrations that run claude -p under the Bash sandbox have no way to tell when sandbox or permission behaviour changes. Changes that are visible to the model ship in patch releases and are not in CHANGELOG.md, so the only safe approach is to re-validate on every version. On the default latest channel that can mean several times a day.
Context
We run claude -p --output-format stream-json --permission-mode dontAsk --restricted --safe-mode with a Bash sandbox passed via --settings. The settings are enabled, failIfUnavailable, allowUnsandboxedCommands: false, denyRead: ["~/"], allowRead: [<cwd>], and no network. Before the integration allows write tasks, a small suite of live probes checks that sandbox on the installed CLI version. Every check is paired with a positive control. The result is recorded per CLI version, so any update switches writes off until the suite is re-run. That part is by design, and we want the updates.
What happened
- The native install moved 2.1.289 → 2.1.290 → 2.1.291 → 2.1.292 within about 24 hours (2026-10-05/06).
- A probe that passed on 2.1.289–2.1.291 went INCONCLUSIVE twice on 2.1.292. The probe was a single prompt: edit inside the cwd,
touchinside the cwd, then attempt a write into the parent checkout and atouchof a git hook outside the cwd. Nothing escaped. On 2.1.292, though, the out-of-cwd Bashtouchwas denied at the permission layer with new text: "Permission to use Bash has been denied because Claude Code is running in don't ask mode … you should not attempt to work around this denial …". On 2.1.291 the sandbox blocked it instead. With the new denial text the model stopped, and never ran the remaining in-cwd step. We had to restructure the probe. - We found nothing about this denial path or wording change in the CHANGELOG entries for 2.1.290–2.1.292.
- Separately,
CLAUDE_CODE_DISABLE_GIT_INSTRUCTIONS=1removes the startupgit status/git log/git config user.name. With it set, the CLI still runsgit remote,git remote get-url originandgit ls-files --error-unmatch -- :(icase).claude/settings.local.jsonin the working directory (observed on 2.1.291 and 2.1.292). Each call carries its owncore.hooksPath=/dev/null/core.fsmonitor=hardening. Integrations that run in untrusted repositories have to re-check that set on every release, because nothing documents it.
Requests
- List any change to sandbox enforcement, permission decisions, or the denial text returned to the model in CHANGELOG.md, including patch releases.
- Publish a versioned statement of what headless
claude -pguarantees under--settingssandbox +dontAsk+--restricted. Integrations could then pin to a contract instead of a binary version. - Optionally: document, or allow disabling, every git command the CLI runs in the cwd at startup. One switch to turn off all startup git would be enough.
Related: #91646 (autoUpdates: false is ignored on native installs). We are not asking to stop updates. The stable channel slows the cadence but does not address the missing changelog coverage.
Environment
- Claude Code native install on Linux (Ubuntu), 2.1.289 → 2.1.292
- Max subscription, headless
claude -p
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗