Idea
Extend the no-chaining hook to block ; and newline-based command chaining the same way it currently blocks && and ||. Today, semicolons and newlines are allowed because shell constructs like for/do/done and if/then/fi require them. But they have the exact same permission-bypass risk as && — a command like ls; rm -rf / auto-approves based on ls at the start.
Why this is safe to do now
This is blocked by #31 (trimkit-symlink). The primary reason semicolons are allowed today is the worktree symlink loop pattern:
MAIN=/path/to/main WORKTREE=/path/to/wt; for item in .env; do ln -sf "$MAIN/$item" "$WORKTREE/$item"; fi
Once trimkit-symlink replaces this with a flat command, the main use case for semicolons in Bash tool calls goes away. Any remaining legitimate multi-statement needs can be handled with multi-line commands (which should also be analyzed) or multiple Bash tool calls.
What to block
- Semicolons (
;) outside of quoted strings — same stripping logic the hook already uses for &&/||
- Newlines used to sequence independent commands — this is trickier since newlines are also structural (e.g., heredocs, multi-line strings). Needs careful design to distinguish
echo "hello\nworld" from ls\nrm -rf /
Design considerations
- Newline analysis is harder than semicolon analysis. Consider starting with semicolons only and deferring newline chaining to a follow-up if the detection logic is complex.
- The hook already strips quoted strings before checking for operators — the same approach works for semicolons.
- Need to audit existing allowed patterns and CLAUDE.md examples to ensure nothing legitimate breaks.
- The
for/do/done and if/then/fi constructs that currently rely on semicolons would need to be rewritten with newlines in any documentation or templates — but if newlines are also being blocked, these constructs need an exemption or a different approach.
Acceptance criteria
Idea
Extend the
no-chaininghook to block;and newline-based command chaining the same way it currently blocks&&and||. Today, semicolons and newlines are allowed because shell constructs likefor/do/doneandif/then/firequire them. But they have the exact same permission-bypass risk as&&— a command likels; rm -rf /auto-approves based onlsat the start.Why this is safe to do now
This is blocked by #31 (
trimkit-symlink). The primary reason semicolons are allowed today is the worktree symlink loop pattern:Once
trimkit-symlinkreplaces this with a flat command, the main use case for semicolons in Bash tool calls goes away. Any remaining legitimate multi-statement needs can be handled with multi-line commands (which should also be analyzed) or multiple Bash tool calls.What to block
;) outside of quoted strings — same stripping logic the hook already uses for&&/||echo "hello\nworld"fromls\nrm -rf /Design considerations
for/do/doneandif/then/ficonstructs that currently rely on semicolons would need to be rewritten with newlines in any documentation or templates — but if newlines are also being blocked, these constructs need an exemption or a different approach.Acceptance criteria
;outside quoted strings is blocked with the same mechanism as&&