Replies: 1 comment
-
Remediation
|
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
On July 6, 2026 at ~06:57 UTC, a routine renovate bot dependency
update — PR #2998 —
triggered a Docker layer cache bust in the sandbox image build. The
fresh
curl | bashinstall baked a post-enforcement Claude Codeversion into the image, activating a latent
disallowedToolsparsingbug that had been dormant since April 23. Every Code and Fix agent
run since Jul 6 08:52 UTC is affected.
Timeline
Phase 1: Bug introduced (April 20–23)
disallowedTools: ["Bash(sed *)"]disallowedTools: ["Bash(sed *)"]disallowedToolswas inert--printmode now honorsdisallowedToolsv2.1.119 is the enforcement change. Before this version,
disallowedToolsin agent frontmatter was silently ignored in--print/--agentsessions. After, it's enforced — but scopedpatterns like
Bash(sed *)are parsed incorrectly, stripping theentire Bash tool instead of only blocking the scoped command.
Phase 2: Bug latent (April 23 – July 6)
The sandbox image installs Claude Code at build time via
RUN curl -fsSL https://claude.ai/install.sh | bashin theContainerfile. Docker layer caching preserves the installed version
across rebuilds as long as preceding layers (FROM, apt-get) don't
change.
All sandbox image builds from v0.13.0 (Jun 1) through v0.27.0
(Jul 2) had the
curl | bashstep CACHED, preserving v2.1.91(a pre-enforcement version from April 2).
Verified via CI build logs — every build shows
#N CACHEDfor theClaude Code install step:
During this period, 100+ Code/Fix runs executed without issue
(all using v2.1.91 —
disallowedToolswas not enforced).Artifact sampling confirms v2.1.91 throughout:
Phase 3: Cache bust (July 6)
images/sandbox/Containerfilemainpushbuild-basejob:RUN curl ... | bash→ NOT CACHED —Setting up Claude Code...→ installed v2.1.201#11 6.276 Version: 2.1.201build-basejob completed,fullsend-sandbox:latestpushedbuild-codejob completed,fullsend-code:latestpushedThe changed FROM digest (
sha256:11c73b5a...→sha256:aeef1c63...)invalidated all downstream Docker layers, forcing a fresh Claude Code
install. The build logs show the exact transition:
Phase 4: First affected run (July 6 08:52 UTC)
fullsend-code:latestpushed (post-enforcement)The transition is sharp. Every Code/Fix run since 08:52 UTC is
affected.
Note on version discrepancy: Build logs show v2.1.201 was
installed, but the runtime init event reports
claude_code_version: 2.1.156. Both are post-v2.1.119 (the enforcement change), so thebug is active regardless. The discrepancy may be due to an
intermediate version resolution mechanism between image build and
sandbox execution.
What happens in affected runs
The parsing bug
disallowedTools: ["Bash(sed *)"]is parsed as "this mentions Bash"and the entire Bash tool is removed from the agent's tool list. The
(sed *)scope is ignored. Instead of 23 tools (including Bash),the agent starts with 26 tools (different tool composition, no Bash).
The scope leak via subagent delegation
After Bash is removed, the agent adapts by spawning subagents via the
Agent tool. Subagents do NOT inherit the parent's
disallowedToolsrestriction — they have unrestricted Bash access.
First affected run (Jul 6 08:52) pattern:
"Error: No such tool available: Bash"This makes
disallowedToolstrivially bypassable. The modellearns after one failed Bash call and exclusively delegates via
subagents for all subsequent Bash work.
Upstream issues filed
disallowedToolsnot inherited by subagents (scope leak)disallowedTools: Bash(git *)strips entire BashEvidence: claude-replay sessions
Interactive HTML replays generated from production JSONL artifacts.
Open in a browser.
1. Last clean run —
disallowedToolsignored (v2.1.91)File:
rca-replays/1-last-clean-jul6-0405.html(in project workspace)Bash. Agent frontmatter has
disallowedTools: ["Bash(sed *)"]butthe restriction is silently ignored. The agent calls Bash 17 times
directly — no errors, no subagent delegation.
docs/artifacts/code-jul6-last-clean/(in project workspace)2. First affected run — Bash error, pivot to Agent (v2.1.156)
File:
rca-replays/2-first-affected-jul6-0852.html(in project workspace)At line 17, the parent attempts
Bash→ gets"Error: No such tool available: Bash". From line 30 onward, itexclusively uses the Agent tool to spawn subagents.
docs/artifacts/code-jul6-first-affected/(in project workspace)Root cause chain
Contributing factors
Unpinned Claude Code install.
RUN curl | bashinstallswhatever is latest at build time. No version pin, no checksum.
Behavioral changes in Claude Code land silently on the next cache
bust.
Docker layer caching masked the change for 74 days. The FROM
digest hadn't changed since the image was first built with v2.1.91.
All 20+ sandbox image builds between Jun 1 and Jul 2 reused the
cached Claude Code binary.
Scoped pattern parser is broken.
disallowedTools: Bash(sed *)should block only
sed-pattern commands but instead removes Bashentirely. Upstream bug, no fix in 11 months — #6527.
Subagents don't inherit restrictions. Even if the parser worked
correctly, subagents bypass
disallowedToolsentirely. Upstreambug, newly filed — #78063.
No version monitoring. There's no alert or check comparing the
Claude Code version across runs. The jump from v2.1.91 to a
post-enforcement version produced no notification.
Experiment 0021
ran on the last unaffected version. The experiment tested
disallowedToolson v2.1.118 (Apr 23 02:05 UTC) and concluded itwas inert. v2.1.119 was released 21 hours later, changing the
behavior. The experiment's conclusion was invalidated before the
ink dried.
Appendix: image and config references
images/sandbox/Containerfileimages/code/Containerfile.fullsend/harness/code.yaml→base:→ scaffold templateghcr.io/fullsend-ai/fullsend-code:latest.github/workflows/sandbox-images.ymlchore(deps): update openshellBeta Was this translation helpful? Give feedback.
All reactions