Skip to content

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

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

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. 👍

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Automated PR Cleanup

Thank you for contributing to opencode.

Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions.

This PR was closed because it matched the following cleanup criteria:

  • The PR was created more than 1 month ago
  • The PR had fewer than 2 positive reactions
  • Positive reactions are counted as thumbs-up, heart, celebration, or rocket reactions on the PR

PRs created within the last month are not affected by this cleanup.

If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate.

Thanks again for taking the time to contribute.

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

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