fix(tool): stop git subcommands from passing the read-only fast path with destructive arguments by ydflow · Pull Request #2883 · agentscope-ai/agentscope · GitHub
Skip to content

fix(tool): stop git subcommands from passing the read-only fast path with destructive arguments - #2883

Merged
DavdGao merged 3 commits into
agentscope-ai:mainfrom
ydflow:fix/bash-git-readonly-continuation
Sep 28, 2026
Merged

DavdGao merged 3 commits into
agentscope-ai:mainfrom
ydflow:fix/bash-git-readonly-continuation

Conversation

@ydflow

@ydflow ydflow commented Sep 27, 2026

Copy link
Copy Markdown
Contributor

AgentScope Version

2.0.8, main a388212

Description

Background

The read-only matcher (BashCommandParser.is_read_only_command) prefix-matches git subcommands against the whole command. Since git branch, git tag, git remote and git reflog are in READ_ONLY_COMMANDS, the following were all classified as read-only and auto-allowed by PermissionEngine's read-only fast path before any rule or mode restriction applied:

git branch -D main                      -> read-only
git tag -d v1                           -> read-only
git remote add origin https://...       -> read-only
git reflog expire --expire=now --all    -> read-only

That is a write-permission bypass in every permission mode — including explore mode, where modifications are documented as categorically denied — and check_dangerous_command never runs because the read-only check returns first. Bare git branch <name> (no flags at all) is equally mutating: it creates a branch.

Changes

src/agentscope/tool/_builtin/_bash_parser.py, mirroring the per-predicate analysis already done for find (FIND_MUTATING_PREDICATES): the continuation arguments of the four destructive-capable git prefixes are analyzed token by token via a small GIT_MUTATING_CAPABLE_COMMANDS table.

A command stays read-only only while it matches known read-only forms:

  • a listing flag (git branch -a, git tag -l), after which bare positionals are just name patterns (git branch --list feat*);
  • a read-only subcommand consuming its arguments (git remote show origin, git remote get-url ..., git reflog show, git reflog exists);
  • attached short-option values (git tag -n5).

Any unknown or destructive flag (-D, -m, --expire, ...), or a bare positional without a listing flag (git branch main, git tag v1.0, git remote add ...), fails closed into the normal permission flow (ASK/deny). Other git prefixes (status, log, diff, show, ...) remain read-only regardless of arguments, so no existing legitimate read behavior outside these four prefixes changes.

The fail-closed direction means exotic-but-harmless read flags for these four subcommands (e.g. git branch --sort=-committerdate) now ask instead of auto-allowing; the whitelist is trivial to extend.

How to test

Two new tests in tests/permission_bash_parser_test.py:

  • test_git_listing_forms_stay_read_only — 19 legitimate listing forms stay auto-allowed;
  • test_mutating_git_commands_are_not_read_only — 15 destructive continuations (branch delete/rename/create, tag delete/create, remote add/remove/set-url/prune, reflog expire/delete) no longer pass the fast path.

Both mirror the existing test_mutating_find_commands_are_not_read_only style. Note the whole file is @unittest.skipIf(sys.platform == "win32") (Bash tool unsupported on Windows), so these run on the Linux/macOS CI legs; behavior was additionally verified directly against the parser (36/36 cases). pytest tests -k "permission or bash or parser" is green (127 passed), and pre-commit passes on both changed files.

Note on the issue checklist item

This account currently holds 5 open issues (the tracker cap from #2761), all of which already have open PRs, so the automation would auto-close a sixth issue. Happy to file the issue and link it here as soon as a slot frees up — or if a maintainer prefers, treat this PR description as the issue.

…with destructive arguments

The read-only matcher prefix-matched git subcommands against the whole
command, so 'git branch -D main', 'git tag -d v1', 'git remote add
origin <url>' and 'git reflog expire --expire=now --all' were all
classified as read-only and auto-allowed by the permission engine's
fast path before any rule or mode restriction applied — including in
explore mode, where modifications are supposed to be categorically
denied. Bare 'git branch <name>' even creates a branch.

Analyze the continuation arguments of the four destructive-capable git
prefixes (branch, tag, remote, reflog) the way find's mutating
predicates are already analyzed: a command stays read-only only while
its arguments match known listing forms (list-mode flags, then bare
name patterns) or read-only subcommands (remote show/get-url, reflog
show/exists). Any unknown or destructive flag, or a bare positional
that could be a creation target, fails closed into the normal
permission flow. Other git prefixes (status, log, diff, ...) remain
read-only regardless of arguments.
@github-actions github-actions Bot added pr/awaiting-review Waiting for maintainers to review this PR pr/no-linked-issue This PR does not link to any issue labels Sep 27, 2026
@github-actions

Copy link
Copy Markdown
Contributor

@ydflow

ydflow commented Sep 27, 2026

Copy link
Copy Markdown
Contributor Author

DavdGao and others added 2 commits September 28, 2026 11:55
Replace the argument parser with removing git branch/tag/remote/reflog
from GIT_READ_ONLY_COMMANDS so they go through the normal permission check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y fast path

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@DavdGao DavdGao left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@DavdGao
DavdGao merged commit ab4bfbe into agentscope-ai:main Sep 28, 2026
8 checks passed
@github-actions github-actions Bot removed the pr/awaiting-review Waiting for maintainers to review this PR label Sep 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr/no-linked-issue This PR does not link to any issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants