Skip to content

[Bug]: ACCEPT_EDITS ignores working directories — in-scope edit tools always ask #2870

Description

@kevinyang03

AgentScope-Java is an open-source project. To involve a broader community, we recommend asking your questions in English.

Describe the bug

Under PermissionMode.ACCEPT_EDITS, edit tools (write_file, edit_file, write_text_file, insert_text_file, …) operating on files inside a configured working directory return ASK instead of the documented ALLOW. Configured working directories are effectively dead configuration — nothing in the permission evaluation path ever consumes PermissionContextState#getWorkingDirectories().

This breaks the contract declared consistently in three places:

  • PermissionMode.java:27"ACCEPT_EDITS: file edits inside working directories are auto-allowed"
  • AdditionalWorkingDirectory.java:25"Working directories drive the auto-allow behaviour of ACCEPT_EDITS"
  • docs/v2/{en,zh}/docs/building-blocks/permission-system.md — mode table: "Auto-allow file ops inside the working directory", plus the decision-flow diagram ("ACCEPT_EDITS + safe file op? → ALLOW")

A side effect: under DONT_ASK, the wrongly-produced ASK is demoted to DENY, so unattended runs silently reject in-scope edits.

To Reproduce

Steps to reproduce the behavior:

  1. Your code — a minimal JUnit test against the current engine (verified on current main):
import io.agentscope.core.permission.*;
import io.agentscope.core.tool.ToolBase;
import io.agentscope.core.tool.Toolkit;
import io.agentscope.core.tool.file.WriteFileTool;
import java.nio.file.Path;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

class AcceptEditsReproTest {

    @Test
    void acceptEditsAsksForInScopeEdit(@TempDir Path workDir) {
        PermissionContextState context = PermissionContextState.builder()
                .mode(PermissionMode.ACCEPT_EDITS)
                .addWorkingDirectory(workDir.toString(),
                        new AdditionalWorkingDirectory(workDir.toString(), "session"))
                .build();
        PermissionEngine engine = new PermissionEngine(context);

        Toolkit toolkit = new Toolkit();
        toolkit.registerTool(new WriteFileTool());
        ToolBase writeTextFile = (ToolBase) toolkit.getTool("write_text_file");

        PermissionDecision decision = engine.checkPermission(
                        writeTextFile,
                        Map.of("file_path", workDir.resolve("demo.txt").toString(),
                               "content", "hello"))
                .block();

        // Expected: ALLOW | Actual: ASK
        System.out.println(decision.getBehavior() + " | " + decision.getMessage());
    }
}
  1. How to execute:
mvn -pl agentscope-core test -Dtest=AcceptEditsReproTest
  1. See error (actual console output):
ASK | Permission required for write_text_file

Expected behavior

ACCEPT_EDITS + an edit tool + every operated path resolving inside a configured working directory → ALLOW, exactly as the PermissionMode / AdditionalWorkingDirectory javadoc and the permission-system documentation promise. Paths outside every working directory should keep falling through to the default ASK.

Error messages

No exception — the failure is a wrong decision rather than an error. The engine returns:

  • behavior: ASK
  • message: Permission required for write_text_file
  • decision_reason: Mode: accept_edits

Environment (please complete the following information):

  • AgentScope-Jafe Version: 2.0.3-SNAPSHOT (main @ c32de522; also confirmed unchanged on latest main a37bfa85)
  • Java Version: 21 (Temurin 21.0.11)
  • OS: macOS 26.2 (logic-only bug, OS-independent)

Additional context

Root cause (traced through PermissionEngine.checkPermission):

  1. PermissionEngine#checkExploreMode handles ACCEPT_EDITS only for tool.isReadOnly() tools; edit tools get null and fall through.
  2. PermissionEngine never reads context.getWorkingDirectories() — a global search shows no production consumer of the working-directory map in the permission path (AgentSpawnTool only merges the map into child contexts).
  3. The default ToolBase#checkPermissions returns plain PASSTHROUGH and the engine has no way to know which tool argument is a file path — so step 4 (allow rules), step 5 (BYPASS) and step 6 (default ASK) decide, yielding ASK.

I have a working fix on a local branch and would be happy to open a PR: a declarative tool-side path contract (@Tool(filePathParams = {...}) / ToolBase.builder().filePathParams(...)) that enables a path-aware default checkPermissions in ToolBase (dangerous path → bypass-immune Safety-ASK; ACCEPT_EDITS + all declared paths inside a working directory → ALLOW; otherwise PASSTHROUGH), leaving PermissionEngine untouched. The built-in edit tools then simply declare their path parameter.

Related: #2137 asks for propagating parent working directories into spawned subagent contexts. That is a different layer (context propagation vs. engine enforcement) and the two compose — once child contexts receive working directories, the fix proposed here makes the engine actually honor them.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions