Skip to content

fix(permission): scope "always" approval to the command that was shown - #40152

Open
0xSemizzz wants to merge 1 commit into
anomalyco:devfrom
0xSemizzz:fix/permission-always-scope
Open

fix(permission): scope "always" approval to the command that was shown#40152
0xSemizzz wants to merge 1 commit into
anomalyco:devfrom
0xSemizzz:fix/permission-always-scope

Conversation

@0xSemizzz

@0xSemizzz 0xSemizzz commented Aug 2, 2026

Copy link
Copy Markdown

collect() accumulated one arity-widened always pattern per command node into a single set, and Permission.reply installs an allow rule for every entry of that set when the user answers "always".

For a compound command this turns one user decision into several grants: approving git status && rm -rf ~ installs both git status * and rm *, and rm * matches rm -rf / on the next turn.

Keep the widened prefix only when the request covers exactly one command. Otherwise fall back to the literal command strings, so "always" grants exactly the commands that were displayed in the prompt.

Issue for this PR

Closes #40158

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

scan.always in tool/shell.ts is a Set that gets one entry per command node found in the parsed command. ask() sends the whole set as the request's always list, and permission/index.ts loops that list on an "always" reply, pushing an allow rule for each entry.

So the widening is per command but the approval is per request. With one command that is fine: you approve git status, you get git status *. With two it is wrong, because you see one prompt, click once, and get a rule for each command in it. The rm case is the bad one, since BashArity gives rm an arity of 1, so rm -rf ~ widens to rm *, which then matches any future rm.

The fix keeps the existing widening when found.length === 1 and otherwise uses the literal command text. Re-running the same compound command still matches and stays allowed. rm -rf / does not match rm -rf tmp and still prompts.

How did you verify your code works?

Two tests in packages/opencode/test/tool/shell.test.ts. One asserts git status still widens to git status *. The other asserts git status && rm -rf tmp yields neither rm * nor git status *, but does yield both literals. Both use the existing capture(requests, err) helper so the command never actually executes.

cd packages/opencode && bun test test/tool/shell.test.ts

Screenshots / recordings

N/A, no UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

`collect()` accumulated one arity-widened `always` pattern per command node
into a single set, and `Permission.reply` installs an allow rule for every
entry of that set when the user answers "always".

For a compound command this turns one user decision into several grants:
approving `git status && rm -rf ~` installs both `git status *` and `rm *`,
and `rm *` matches `rm -rf /` on the next turn.

Keep the widened prefix only when the request covers exactly one command.
Otherwise fall back to the literal command strings, so "always" grants
exactly the commands that were displayed in the prompt.
@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@github-actions github-actions Bot added needs:compliance This means the issue will auto-close after 2 hours. and removed needs:issue needs:compliance This means the issue will auto-close after 2 hours. labels Aug 2, 2026
@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Approving "always" on a compound bash command grants a rule for every command in it

1 participant