From 1d8c7a09b85b80eaa1616e302914b3d18bdc197f Mon Sep 17 00:00:00 2001 From: Dotta <34892728+cryppadotta@users.noreply.github.com> Date: Mon, 27 Apr 2026 08:11:52 -0500 Subject: [PATCH] [codex] Add security role route regression (#4586) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Thinking Path > - Paperclip orchestrates AI agents through company-scoped control-plane workflows. > - Agent creation is one of the core board/operator surfaces for defining who works in a company. > - The shared taxonomy now includes a first-class `security` agent role. > - Direct agent creation must preserve that role through default instruction materialization and telemetry. > - A prior replacement PR covered this path, but Greptile identified that the route-test mock could let a future patch object shadow the regression. > - This pull request reopens the narrow regression coverage from current `master` with the mock ordering fixed. > - The benefit is a focused guardrail that keeps `security` role creation observable without expanding the production diff. ## What Changed - Added a direct agent creation route regression test for `role: "security"`. - Verified telemetry receives `agentRole: "security"` after the default instruction materialization update path. - Ordered the regression mock as `...patch` before `role: "security"` so future patch fields cannot shadow the asserted role. ## Verification - `pnpm install --frozen-lockfile` to link dependencies in the fresh worktree; it completed with existing plugin SDK bin warnings. - `pnpm exec vitest run server/src/__tests__/agent-skills-routes.test.ts packages/shared/src/adapter-types.test.ts` ## Risks - Low risk. This is test-only coverage and does not change runtime behavior. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used - OpenAI Codex, GPT-5 based coding agent, tool-enabled with local shell and repository editing capabilities. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots (N/A: no UI changes) - [x] I have updated relevant documentation to reflect my changes (N/A: test-only regression) - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip --- .../src/__tests__/agent-skills-routes.test.ts | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/server/src/__tests__/agent-skills-routes.test.ts b/server/src/__tests__/agent-skills-routes.test.ts index 99cff4a4..129075c9 100644 --- a/server/src/__tests__/agent-skills-routes.test.ts +++ b/server/src/__tests__/agent-skills-routes.test.ts @@ -436,6 +436,39 @@ describe.sequential("agent skill routes", () => { ); }); + it("accepts the security role on direct agent creation and preserves it in telemetry", async () => { + mockAgentService.update.mockImplementation(async (_id: string, patch: Record) => ({ + ...makeAgent("claude_local"), + ...patch, + role: "security", + adapterConfig: patch.adapterConfig ?? {}, + })); + + const res = await requestApp(await createApp(), (baseUrl) => request(baseUrl) + .post("/api/companies/company-1/agents") + .send({ + name: "Security Engineer", + role: "security", + adapterType: "claude_local", + adapterConfig: {}, + })); + + expect([200, 201], JSON.stringify(res.body)).toContain(res.status); + expect(mockAgentService.create).toHaveBeenCalledWith( + "company-1", + expect.objectContaining({ + role: "security", + }), + ); + expect(mockTrackAgentCreated).toHaveBeenCalledWith( + expect.anything(), + expect.objectContaining({ + agentId: "11111111-1111-4111-8111-111111111111", + agentRole: "security", + }), + ); + }); + it("materializes a managed AGENTS.md for directly created local agents", async () => { const res = await requestApp(await createApp(), (baseUrl) => request(baseUrl) .post("/api/companies/company-1/agents")