From c036bbfa98494dcfe2521aab65019a4cd021c769 Mon Sep 17 00:00:00 2001 From: Dotta <34892728+cryppadotta@users.noreply.github.com> Date: Sun, 26 Apr 2026 07:52:05 -0500 Subject: [PATCH] Add first-class security agent role to taxonomy (#4532) ## Thinking Path > - Paperclip is the control plane for AI-agent companies, so agent metadata is part of the platform's governance and audit surface. > - The shared agent taxonomy in `@paperclipai/shared` is the source of truth for allowed agent roles and their UI labels. > - The current taxonomy lacks a `security` role, which causes Security Engineer hires to collapse into `engineer`. > - That breaks separation-of-duties evidence in telemetry and weakens role-level audit fidelity even though it does not directly change permissions. > - This pull request adds `security` as a first-class shared role and covers the prior rejection path with a regression test. > - The benefit is that Security Engineer agents can now be persisted and rendered under the correct role without schema or permission churn. ## What Changed - Added `security` to `AGENT_ROLES` in `packages/shared/src/constants.ts`. - Added the `Security` display label to `AGENT_ROLE_LABELS` so existing UI consumers render the new role automatically. - Added a shared validator regression test proving `createAgentSchema` accepts `role: "security"` and that the label stays stable. ## Verification - `pnpm --filter @paperclipai/shared typecheck` - `pnpm --filter @paperclipai/shared exec vitest run src/adapter-types.test.ts` ## Risks - Low risk. This is a shared enum expansion with no database migration and no permission-model change. - Residual risk: this PR does not backfill existing agents already persisted as `engineer`; it only fixes new validations and labels going forward. > I checked `ROADMAP.md`/`doc` for overlap and did not find an existing planned item covering this taxonomy fix. ## Model Used - OpenAI GPT-5.4 via the Codex local adapter, with tool use and local code execution enabled. The runtime did not surface a separate context-window identifier in agent metadata. ## 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 - [ ] If this change affects the UI, I have included before/after screenshots - [ ] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --- packages/shared/src/adapter-types.test.ts | 14 +++++++++++++- packages/shared/src/constants.ts | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/shared/src/adapter-types.test.ts b/packages/shared/src/adapter-types.test.ts index 29fb6eec..4be83236 100644 --- a/packages/shared/src/adapter-types.test.ts +++ b/packages/shared/src/adapter-types.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "vitest"; -import { acceptInviteSchema, createAgentSchema, updateAgentSchema } from "./index.js"; +import { AGENT_ROLE_LABELS, acceptInviteSchema, createAgentSchema, updateAgentSchema } from "./index.js"; describe("dynamic adapter type validation schemas", () => { it("accepts external adapter types in create/update agent schemas", () => { @@ -35,4 +35,16 @@ describe("dynamic adapter type validation schemas", () => { }).adapterType, ).toBe("external_adapter"); }); + + it("accepts the security agent role and exposes its UI label", () => { + expect( + createAgentSchema.parse({ + name: "Security Engineer", + role: "security", + adapterType: "codex_local", + }).role, + ).toBe("security"); + + expect(AGENT_ROLE_LABELS.security).toBe("Security"); + }); }); diff --git a/packages/shared/src/constants.ts b/packages/shared/src/constants.ts index df99bb33..cbcd7878 100644 --- a/packages/shared/src/constants.ts +++ b/packages/shared/src/constants.ts @@ -42,6 +42,7 @@ export const AGENT_ROLES = [ "cto", "cmo", "cfo", + "security", "engineer", "designer", "pm", @@ -57,6 +58,7 @@ export const AGENT_ROLE_LABELS: Record = { cto: "CTO", cmo: "CMO", cfo: "CFO", + security: "Security", engineer: "Engineer", designer: "Designer", pm: "PM",