anomalyco / anomalyco/opencode
bash permission rules non-deterministic for `rm *`, `mv *`, `cp *` patterns
@kitlangton is already working on this.
Since Jul 26, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Description
Bash permission rules with anchored patterns (rm *, mv *, cp *) are non-deterministic: the same command, run multiple times in identical conditions, sometimes triggers the ask prompt and sometimes executes silently. 50% bypass rate for rm, 90% bypass rate for mv in my testing.
When the rule fires:
! permission requested: bash (rm /tmp/test.txt); auto-rejecting
✗ rm /tmp/test.txt failed
When it doesn't fire, the rm is executed and the file is removed — no prompt, no log entry.
Static config is correct: opencode debug config shows rm *: ask, and a Python reproducer of Wildcard.match confirms rm /tmp/test.txt matches rm * (returns True). The bug is at the bash tool invocation layer, not the pattern matcher.
Plugins
None
OpenCode version
1.18.3
Steps to reproduce
- Configure
bashrules:{ "permission": { "bash": { "*": "allow", "rm *": "ask", "mv *": "ask", "cp *": "ask" } } } - From any cwd, run:
for i in $(seq 1 20); do echo "X" > /tmp/test_$i.txt out=$(timeout 15 opencode run --model <model> "Run: bash -c 'rm /tmp/test_$i.txt'" 2>&1) has_prompt=$(echo "$out" | grep -c "permission requested") file_exists=$(ls /tmp/test_$i.txt 2>/dev/null | wc -l) echo "Run $i: prompt=$has_prompt file_exists=$file_exists" done - Observe that
rm /tmp/test_$i.txtis sometimes blocked and sometimes executed silently.
Reproduction data
Test 1 — rm (20 runs): 10/20 prompts fired, 10/20 bypassed. Several sample runs:
- Run 1: prompt=0 file_exists=0 (NO PROMPT, file deleted ⚠)
- Run 2: prompt=1 file_exists=1 (correct)
- Run 3: prompt=0 file_exists=0 (NO PROMPT, file deleted ⚠)
- Run 4: prompt=1 file_exists=1 (correct)
Test 2 — mv /tmp/a /tmp/b (10 runs): 1/10 prompts fired, 9/10 bypassed. ⚠
Test 3 — full output capture (5 runs):
- Run 1:
bash -c 'rm /tmp/full_test_1.txt'→ PROMPT, file intact ✓ - Run 2:
bash -c 'rm /tmp/full_test_2.txt'→ NO PROMPT, file DELETED ⚠ - Run 3: agent did not invoke bash → file intact
- Run 4: → PROMPT, file intact ✓
- Run 5: → PROMPT, file intact ✓
Screenshot and/or share link
Not applicable — deterministic rule on paper, non-deterministic in practice. Numerical evidence above is reproducible.
Operating System
Ubuntu 24.04
Terminal
gnome-terminal (Wayland)
Additional context
- Other tools (read, edit, glob, grep) enforce rules consistently. The bug is specific to the bash tool.
external_directory(path-level) works correctly.- Most likely cause: the bash tool's
allStructuredparser (packages/opencode/src/permission/wildcard.ts) doesn't match the head/tail split correctly for allbash -c "..."invocations, or there's a race condition in the permission check. - Related but distinct issue: #35882 (plugin-rewritten commands). My repro uses no plugins.
- Impact: users relying on bash rules for destructive command protection in unattended sessions have a false sense of security. Running opencode with
--yoloor--autoin unattended mode is unsafe — bash rules cannot be relied upon to block destructive operations.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.