Development record
The guard refused 'A=/path/to/scripts/abcd.sh && $A capture remedy iss-N "each a payload (internal/core/guard/payload.go). Either flatten."' as script-runs-hazard on an 'rm -rf' text in that Go file, though no shell runs the file. The cause is the tokenizer's split at a '(' that follows a command's words (parenWord, internal/core/guard/tokenize.go): the text after the '(' is read as a new command, so targetsOf (internal/core/guard/script.go) resolves the repository path there and reads it as a script the command runs, and '. Either' becomes a source of a missing file. After ordinary command words bash refuses such a '(' as a syntax error, so the path is never run; the same split is also made after words such as time and coproc, where the subshell does run, so the split alone does not mark a line the shell refuses. The variable reaches it only because guessedEvalPayload (internal/core/guard/payload.go) reads quoted arguments behind an unknown program name as possible eval text, which is the correct fail-closed reading; the literal 'eval ... "(path)"' form and the unquoted spelled-program form block the same way, while the same path quoted without a '(' is allowed (reproduced with abcd guard check on 2026-10-31). It bites a remedy or message that writes a guard source path after a '('.
The guard refused 'A=/path/to/scripts/abcd.sh && $A capture remedy iss-N "each a payload (internal/core/guard/payload.go). Either flatten."' as script-runs-hazard on an 'rm -rf' text in that Go file, though no shell runs the file. The cause is the tokenizer's split at a '(' that follows a command's words (parenWord, internal/core/guard/tokenize.go): the text after the '(' is read as a new command, so targetsOf (internal/core/guard/script.go) resolves the repository path there and reads it as a script the command runs, and '. Either' becomes a source of a missing file. After ordinary command words bash refuses such a '(' as a syntax error, so the path is never run; the same split is also made after words such as time and coproc, where the subshell does run, so the split alone does not mark a line the shell refuses. The variable reaches it only because guessedEvalPayload (internal/core/guard/payload.go) reads quoted arguments behind an unknown program name as possible eval text, which is the correct fail-closed reading; the literal 'eval ... "(path)"' form and the unquoted spelled-program form block the same way, while the same path quoted without a '(' is allowed (reproduced with abcd guard check on 2026-10-31). It bites a remedy or message that writes a guard source path after a '('.
Frontmatter
| id | iss-2610312056566760 |
|---|---|
| type | issue |
| lifecycle | open |
| severity | minor |
.abcd/work/issues/open/iss-2610312056566760-when-a-command-s-program-is-a-shell.md
open on GitHub ↗ · commit history ↗