docs: clarify bash.patterns gates bash tool only, not eval
bash.patterns only feeds the bash tool's approval decision. The eval tool declares the exec tier and can spawn a shell via subprocess, so a deny rule there does nothing for the same command run through eval; under yolo the exec call resolves to allow. Note the scope and point at tools.approval.eval as the lever that closes the path in bash-tool-runtime.md, approval-mode.md, and settings.md. Fixes #8838
This commit is contained in:
@@ -57,6 +57,8 @@ approval: { tier: "exec", override: true, reason: "Critical pattern detected" }
|
||||
|
||||
`bash` uses this for critical destructive patterns such as `rm -rf /`, fork bombs, remote-fetch-then-execute, writes to `/etc/passwd`, and host shutdown commands. It also supports configured `bash.patterns` rules: `deny` is absolute, `prompt` forces a prompt, and `allow` explicitly allows the matching call at the `write` tier. Reasons appear in the approval prompt. In `yolo`, a bare critical override is ignored, but an explicit tool/user `prompt` or `deny` policy is still enforced.
|
||||
|
||||
`bash.patterns` only feeds the `bash` tool's approval decision. The `eval` tool declares the `exec` tier and can spawn a shell via subprocess, so a `bash.patterns` `deny` rule does not apply to the same command run through `eval` — under `yolo`, that `exec` call resolves to `allow`. To gate the shell `eval` can reach, add a `tools.approval.eval` policy (`prompt` or `deny`) alongside `bash.patterns`.
|
||||
|
||||
### Computer safety
|
||||
|
||||
The disabled-by-default [`computer` tool](./computer-use.md) chooses its tier from the call's `read_only` declaration:
|
||||
|
||||
@@ -35,6 +35,8 @@ There are no structured `head` or `tail` parameters. Before execution, internal
|
||||
|
||||
The bash tool has the `exec` approval tier. `bash.patterns` rules can explicitly `allow`, `deny`, or `prompt`: deny/prompt rules match the complete command or a tokenized compound-command segment, while allow rules must match the entire command and never allow shell-control syntax. A fixed set of critical destructive and remote-fetch-and-execute patterns always forces exec approval even if a user allow rule matched. Interception and approval are separate mechanisms: interception routes misuse toward dedicated tools; approval governs whether execution may proceed.
|
||||
|
||||
These rules govern the **`bash` tool only**. They do not constrain shells started through other tools — notably `eval`, which can spawn a shell via subprocess (`subprocess.run(["bash", "-c", ...])`, `Bun.$`, etc.). A `bash.patterns` `deny` rule therefore does nothing when the same command is issued through `eval`. To harden against destructive commands across both surfaces, pair `bash.patterns` with a `tools.approval.eval` policy (`prompt` or `deny`); see [Tool approval mode](./approval-mode.md).
|
||||
|
||||
## 2) Optional interception (blocked-command path)
|
||||
|
||||
If `bashInterceptor.enabled` is true, `BashTool` loads rules from settings (`getBashInterceptorRules()`) and runs `checkBashInterception()` against the command — checking both the original and the cwd-normalized form (after a leading `cd … &&` is extracted) when they differ. Rule syntax is unchanged: each rule checks the complete input first, then raw flat command fragments separated by unquoted/unescaped `&&`, `||`, `;`, `|`, `|&`, `&`, or newlines, then those fragments with leading `NAME=value` assignments removed. Fragments that receive piped stdin from `|` or `|&` are excluded from the fragment candidates, including across blank/comment continuation lines, because a stdin-consuming stage cannot be replaced by a path-based dedicated tool.
|
||||
|
||||
@@ -172,6 +172,8 @@ Valid rule approvals are `allow`, `prompt`, and `deny`. Critical bash commands s
|
||||
|
||||
Matching is asymmetric so that rules mean what they appear to: `deny` and `prompt` rules fire when the glob matches the whole command **or any single segment** of a compound line (split on `&&`, `||`, `;`, `|`, a single `&`, subshells, and newlines), so `match: "rm -rf *"` still denies `cd /tmp && rm -rf build` and `sleep 1 & rm -rf build`. `allow` rules must match the **entire** command and never apply to a compound line, so a narrow allow such as `match: "git *"` cannot vouch for `git status && rm -rf /`.
|
||||
|
||||
`bash.patterns` gates the `bash` tool only. It does not cover shells started through `eval`, which can spawn one via subprocess, so a `deny` rule here is bypassed when the same command runs through `eval`. To close that path, add a `tools.approval.eval` policy (`prompt` or `deny`) as well; see [Tool approval mode](./approval-mode.md).
|
||||
|
||||
### Bash interceptor patterns
|
||||
|
||||
`bashInterceptor` is separate from `bash.patterns`: it redirects Bash commands to dedicated tools rather than defining whether a command may execute. Enable it explicitly and configure regular-expression patterns with a replacement tool and a model-facing message:
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
### Changed
|
||||
|
||||
- The `read` tool now materializes a local text file once per invocation instead of once per consumer. A ranged read of a file within the snapshot cap previously cost four opens and three UTF-8 decodes — an 8KiB binary sniff, a streaming scan for the rendered window, a whole-file read for bracket context, and another whole-file read to hash the snapshot — with two of those readers separately normalizing line endings; whole-file reads under the structural summarizer paid a fifth read. Byte counts and truncation boundaries are now measured on the buffered bytes, so they stay exact for content that is not valid UTF-8. Files above the snapshot cap keep streaming, since nothing on that path wants the whole file. Raw reads, which skip the tree-sitter parse that documented the old cost, no longer pay for it.
|
||||
- Documented that `bash.patterns` gates the `bash` tool only and does not cover a shell that `eval` can spawn via subprocess, and that closing that path needs a `tools.approval.eval` policy — noted in `docs/bash-tool-runtime.md`, `docs/approval-mode.md`, and `docs/settings.md` ([#8838](https://github.com/can1357/oh-my-pi/issues/8838)).
|
||||
|
||||
### Fixed
|
||||
|
||||
|
||||
Reference in New Issue
Block a user