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:
- 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());
}
}
- How to execute:
mvn -pl agentscope-core test -Dtest=AcceptEditsReproTest
- 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):
PermissionEngine#checkExploreMode handles ACCEPT_EDITS only for tool.isReadOnly() tools; edit tools get null and fall through.
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).
- 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.
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 consumesPermissionContextState#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 ofACCEPT_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:
main):mvn -pl agentscope-core test -Dtest=AcceptEditsReproTestExpected behavior
ACCEPT_EDITS+ an edit tool + every operated path resolving inside a configured working directory → ALLOW, exactly as thePermissionMode/AdditionalWorkingDirectoryjavadoc 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:
ASKPermission required for write_text_fileMode: accept_editsEnvironment (please complete the following information):
c32de522; also confirmed unchanged on latest maina37bfa85)Additional context
Root cause (traced through
PermissionEngine.checkPermission):PermissionEngine#checkExploreModehandlesACCEPT_EDITSonly fortool.isReadOnly()tools; edit tools getnulland fall through.PermissionEnginenever readscontext.getWorkingDirectories()— a global search shows no production consumer of the working-directory map in the permission path (AgentSpawnToolonly merges the map into child contexts).ToolBase#checkPermissionsreturns plainPASSTHROUGHand 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 defaultcheckPermissionsinToolBase(dangerous path → bypass-immune Safety-ASK;ACCEPT_EDITS+ all declared paths inside a working directory → ALLOW; otherwise PASSTHROUGH), leavingPermissionEngineuntouched. 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.