diff --git a/src/agents/sandbox-tool-policy.test.ts b/src/agents/sandbox-tool-policy.test.ts index b829564290b..56ee3e63fa2 100644 --- a/src/agents/sandbox-tool-policy.test.ts +++ b/src/agents/sandbox-tool-policy.test.ts @@ -1,18 +1,21 @@ import { describe, expect, it } from "vitest"; +import type { OpenClawConfig } from "../config/config.js"; +import { resolveEffectiveToolPolicy } from "./pi-tools.policy.js"; import { pickSandboxToolPolicy } from "./sandbox-tool-policy.js"; +import { resolveEffectiveToolFsRootExpansionAllowed } from "./tool-fs-policy.js"; describe("pickSandboxToolPolicy", () => { it("returns undefined when neither allow nor deny is configured", () => { expect(pickSandboxToolPolicy({})).toBeUndefined(); }); - it("treats alsoAllow without allow as a restrictive allowlist", () => { + it("keeps alsoAllow without allow additive", () => { expect( pickSandboxToolPolicy({ alsoAllow: ["web_search"], }), ).toEqual({ - allow: ["web_search"], + allow: ["*", "web_search"], deny: undefined, }); }); @@ -51,4 +54,27 @@ describe("pickSandboxToolPolicy", () => { deny: ["exec"], }); }); + + it("keeps global alsoAllow additive in effective tool policy resolution", () => { + const cfg: OpenClawConfig = { + tools: { + profile: "coding", + alsoAllow: ["lobster"], + }, + }; + + const resolved = resolveEffectiveToolPolicy({ config: cfg, agentId: "main" }); + expect(resolved.globalPolicy).toEqual({ allow: ["*", "lobster"], deny: undefined }); + expect(resolved.profileAlsoAllow).toEqual(["lobster"]); + }); + + it("does not block fs root expansion when only global alsoAllow is configured", () => { + const cfg: OpenClawConfig = { + tools: { + alsoAllow: ["lobster"], + }, + }; + + expect(resolveEffectiveToolFsRootExpansionAllowed({ cfg, agentId: "main" })).toBe(true); + }); }); diff --git a/src/agents/sandbox-tool-policy.ts b/src/agents/sandbox-tool-policy.ts index 19967899872..4e6102e55e2 100644 --- a/src/agents/sandbox-tool-policy.ts +++ b/src/agents/sandbox-tool-policy.ts @@ -11,7 +11,7 @@ function unionAllow(base?: string[], extra?: string[]): string[] | undefined { return base; } if (!Array.isArray(base)) { - return Array.from(new Set(extra)); + return Array.from(new Set(["*", ...extra])); } if (base.length === 0) { return base;