From c23dde1c3023212ccf1f98c9b789836373301b07 Mon Sep 17 00:00:00 2001 From: Aiden Cline Date: Thu, 9 Jul 2026 18:07:59 -0500 Subject: [PATCH] test(core): cover plugin permission precedence --- packages/core/src/config/plugin/agent.ts | 13 +++++++++++-- packages/core/test/config/agent.test.ts | 22 ++++++++++++++++++---- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/packages/core/src/config/plugin/agent.ts b/packages/core/src/config/plugin/agent.ts index 9b0ec3d56b..19d687d214 100644 --- a/packages/core/src/config/plugin/agent.ts +++ b/packages/core/src/config/plugin/agent.ts @@ -78,8 +78,17 @@ export const Plugin = define({ if (configuredDefault !== undefined) draft.default(AgentV2.ID.make(configuredDefault)) for (const current of draft.list()) { draft.update(current.id, (agent) => { - const initial = AgentV2.Info.empty(AgentV2.ID.make(current.id)).permissions.length - const hasBuiltInDefaults = AgentPlugin.defaultPermissions.every((rule, index) => { + const defaults = AgentV2.Info.empty(AgentV2.ID.make(current.id)).permissions + const hasDefaults = defaults.every((rule, index) => { + const existing = agent.permissions[index] + return ( + existing?.action === rule.action && + existing.resource === rule.resource && + existing.effect === rule.effect + ) + }) + const initial = hasDefaults ? defaults.length : 0 + const hasBuiltInDefaults = hasDefaults && AgentPlugin.defaultPermissions.every((rule, index) => { const existing = agent.permissions[initial + index] return ( existing?.action === rule.action && diff --git a/packages/core/test/config/agent.test.ts b/packages/core/test/config/agent.test.ts index 0dcf261116..1b8c6ed2cf 100644 --- a/packages/core/test/config/agent.test.ts +++ b/packages/core/test/config/agent.test.ts @@ -70,7 +70,10 @@ describe("ConfigAgentPlugin.Plugin", () => { type: "document", info: decode( ConfigMigrateV1.migrate({ - permission: { bash: { "rm*": "ask", "git reset*": "ask" } }, + permission: { + bash: { "rm*": "ask", "git reset*": "ask" }, + read: { "secret*": "deny" }, + }, }), ), }), @@ -87,6 +90,8 @@ describe("ConfigAgentPlugin.Plugin", () => { expect(PermissionV2.evaluate("shell", "rm -rf tmp", build.permissions).effect).toBe("ask") expect(PermissionV2.evaluate("shell", "rm -rf tmp", explore.permissions).effect).toBe("deny") expect(PermissionV2.evaluate("shell", "ls", explore.permissions).effect).toBe("deny") + expect(PermissionV2.evaluate("read", "secret.txt", build.permissions).effect).toBe("deny") + expect(PermissionV2.evaluate("read", "secret.txt", explore.permissions).effect).toBe("allow") }), ) @@ -94,12 +99,16 @@ describe("ConfigAgentPlugin.Plugin", () => { Effect.gen(function* () { const agents = yield* AgentV2.Service const build = AgentV2.ID.make("build") - yield* agents.transform((editor) => + const replacement = AgentV2.ID.make("replacement") + yield* agents.transform((editor) => { editor.update(build, (agent) => { agent.mode = "primary" agent.permissions.push({ action: "bash", resource: "*", effect: "allow" }) - }), - ) + }) + editor.update(replacement, (agent) => { + agent.permissions.splice(0, agent.permissions.length, { action: "bash", resource: "*", effect: "deny" }) + }) + }) const config = Config.Service.of({ entries: () => @@ -156,6 +165,11 @@ describe("ConfigAgentPlugin.Plugin", () => { ]) expect(PermissionV2.evaluate("bash", "git status", buildAgent.permissions).effect).toBe("allow") expect(PermissionV2.evaluate("bash", "bun test", buildAgent.permissions).effect).toBe("allow") + expect((yield* agents.get(replacement))?.permissions).toEqual([ + { action: "bash", resource: "*", effect: "ask" }, + { action: "read", resource: "*", effect: "allow" }, + { action: "bash", resource: "*", effect: "deny" }, + ]) const reviewer = yield* agents.get(AgentV2.ID.make("reviewer")) if (!reviewer) throw new Error("expected configured reviewer agent")