From 9d21754105f8882f690d8048ee24da484007b024 Mon Sep 17 00:00:00 2001 From: Dotta Date: Thu, 30 Apr 2026 13:49:08 -0500 Subject: [PATCH] Prevent agents from clearing user policy gates Co-Authored-By: Paperclip --- .../issue-execution-policy-routes.test.ts | 33 +++++++++++++++++++ server/src/routes/issues.ts | 3 +- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/server/src/__tests__/issue-execution-policy-routes.test.ts b/server/src/__tests__/issue-execution-policy-routes.test.ts index 714d0e58bdb..a820348c46f 100644 --- a/server/src/__tests__/issue-execution-policy-routes.test.ts +++ b/server/src/__tests__/issue-execution-policy-routes.test.ts @@ -292,6 +292,39 @@ describe("issue execution policy routes", () => { ); }); + it("rejects agent attempts to remove existing execution policies with user participants", async () => { + const policy = normalizeIssueExecutionPolicy({ + stages: [ + { + id: "11111111-1111-4111-8111-111111111111", + type: "approval", + participants: [{ type: "user", userId: "local-board" }], + }, + ], + })!; + const issue = { + id: "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa", + companyId: "company-1", + status: "in_progress", + assigneeAgentId: "22222222-2222-4222-8222-222222222222", + assigneeUserId: null, + createdByUserId: "local-board", + identifier: "PAP-999", + title: "Policy removal attempt", + executionPolicy: policy, + executionState: null, + }; + mockIssueService.getById.mockResolvedValue(issue); + + const res = await request(await createApp(agentActor())) + .patch("/api/issues/aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa") + .send({ executionPolicy: null }); + + expect(res.status, JSON.stringify(res.body)).toBe(403); + expect(res.body.error).toBe("Agents cannot author execution policies with user participants"); + expect(mockIssueService.update).not.toHaveBeenCalled(); + }); + it("rejects agent PATCH attempts to assign issues directly to users", async () => { const issue = { id: "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa", diff --git a/server/src/routes/issues.ts b/server/src/routes/issues.ts index dde8049e4aa..abce52819be 100644 --- a/server/src/routes/issues.ts +++ b/server/src/routes/issues.ts @@ -2089,7 +2089,8 @@ export function issueRoutes( if ( req.actor.type === "agent" && req.body.executionPolicy !== undefined && - executionPolicyHasUserParticipants(nextExecutionPolicy) + (executionPolicyHasUserParticipants(nextExecutionPolicy) || + executionPolicyHasUserParticipants(previousExecutionPolicy)) ) { res.status(403).json({ error: "Agents cannot author execution policies with user participants",