paperclip/packages/shared/src/validators
Devin Foley 54dd0f4868
feat(agents): grant new agents hire permission by default (#12814)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agent permissions control which agents can create or hire other
agents (`canCreateAgents`)
> - Today only CEO-role agents get this permission by default; every
other agent starts without it
> - Teams that want agents to delegate and build out their own teams
must flip the toggle on each hire, and most operators want delegation to
work out of the box
> - This pull request makes `canCreateAgents` default to enabled for new
standard-trust agents, while low-trust agents keep a disabled default
> - The benefit is that agent teams can grow without per-agent
permission toggling, while low-trust containment and checkout protection
stay intact

## Linked Issues or Issue Description

Related (not fixed by this PR): #8064 also decouples an authority from
`agents:create`.

**Subsystem affected**

Server agent permissions (`server/src/services/agent-permissions.ts`),
authorization (`server/src/services/authorization.ts`), the shared
`agentPermissionsSchema` validator, and the UI trust-preset helper.

**Problem or motivation**

New agents cannot hire other agents unless an operator enables
`canCreateAgents` on each one. Only CEO-role agents get the permission
by default. This blocks delegation-by-default workflows. Operators must
toggle the permission for every hire.

**Proposed solution**

Default `canCreateAgents` to `true` for newly created agents. Apply and
persist the default at creation only. Stored rows without an explicit
value stay fail-closed at read and enforcement time. Keep the default at
`false` when the agent's permissions record marks it low-trust (the
`low_trust_review` preset or a trust boundary). Explicit values always
win. Decouple `tasks:manage_active_checkouts` from `canCreateAgents` so
the default-on flag does not let a peer agent write over another agent's
checked-out issue.

**Alternatives considered**

Granting the default only at the route layer would leave stored rows and
enforcement out of sync. Keeping the checkout authority coupled to
`canCreateAgents` would void the active-checkout write protection once
the flag is default-on. A per-company setting adds configuration surface
without a clear need; explicit per-agent overrides already exist.

**Roadmap alignment**

Governance and trust-preset work already separates standard-trust from
low-trust agents. This change follows that line: capability by default
for standard trust, containment by default for low trust.

## What Changed

- `normalizeAgentPermissions` now takes a `create`/`stored` context.
Creation writes get the new default: enabled unless
`permissionsImplyLowTrust()` detects the low-trust review preset or a
trust boundary. Stored rows without an explicit value normalize to
disabled (fail-closed). The role parameter is gone.
- `agentPermissionsSchema` no longer injects `canCreateAgents: false`
when the field is omitted. The server-side default applies instead.
- `authorization.ts` normalizes raw agent rows for `agents:create`, so
enforcement matches what the API reports for legacy rows.
- `tasks:manage_active_checkouts` no longer rides on `canCreateAgents`.
CEO role, explicit grants, and the manager chain remain the paths.
- `agents:create` is denied outright inside any resolved low-trust
execution context (agent, project, issue, or run policy). The default-on
flag can never reach the legacy creator allow there.
- The UI trust-preset helper sets `canCreateAgents: false` when an agent
is switched to the low-trust preset, instead of carrying the old value
forward.
- `doc/CLI.md` describes the new default for `teams install`.
- Tests pin the default matrix (standard, low-trust, explicit overrides)
on the server and in the UI helper.

## Verification

- `cd server && npx vitest run
src/__tests__/agent-permissions-service.test.ts
src/__tests__/agent-permissions-routes.test.ts
src/__tests__/low-trust-red-team-routes.test.ts
src/__tests__/authorization-service.test.ts` — 143 tests pass.
- Broader sweep: 18 suites that touch `canCreateAgents` (hire,
pending-approval, teams catalog, portability, built-in agents,
plugin-managed agents) pass locally.
- `cd ui && npx vitest run src/lib/trust-policy-ui.test.ts
src/components/TrustPresetSection.test.tsx src/pages/NewAgent.test.tsx
src/pages/Agents.test.tsx` — passes.
- Typecheck is clean for the changed files in `packages/shared`,
`server`, and `ui`.

## Risks

- Behavioral shift: agents created after this change persist
`canCreateAgents: true` unless low-trust. Pre-existing agents keep their
stored value. Legacy or malformed permission records without an explicit
value stay fail-closed at read and enforcement time; they never gain the
authority retroactively.
- Low-trust runs can no longer create agents at all, even when the agent
carries an explicit `canCreateAgents: true`. Before this change, that
combination could hire. The red-team suite and a new authorization test
pin the denial.
- Narrowing: a non-CEO agent with `canCreateAgents: true` loses implicit
`tasks:manage_active_checkouts`. The manager chain and explicit grants
still provide it. This narrowing is deliberate; without it, the
default-on flag would let any peer bypass active-checkout write
protection.
- No migrations. No API shape changes. Low-trust defaults are covered by
the red-team regression suite.

## Model Used

- Claude Fable 5 (`claude-fable-5`), Anthropic — via Claude Code CLI
with extended thinking and tool use (code search, editing, local test
execution).

## 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 searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-09-03 23:26:51 -07:00
..
access.test.ts feat(observability): add opt-in Sentry error monitoring for the server and the browser (#12190) 2026-08-26 11:15:45 -07:00
access.ts feat(server): split the Sentry DSN into front-end and backend variables (#12678) 2026-09-01 11:02:04 -07:00
adapter-auth-session.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
adapter-registry.test.ts feat(server): kubernetes execution integration for sandbox-provider plugins (stage 2/3) (#7938) 2026-06-10 21:09:02 -07:00
adapter-registry.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
adapter-skills.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
agent.ts feat(agents): grant new agents hire permission by default (#12814) 2026-09-03 23:26:51 -07:00
app-definition.ts feat(apps): add Paperclip Cloud managed OAuth connector (#12600) 2026-08-31 14:34:46 -05:00
approval.test.ts Normalize escaped multiline issue and approval text (#4444) 2026-04-24 18:02:45 -05:00
approval.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
artifact.test.ts PAP-10440: group artifacts by task stacks (#7654) 2026-06-06 10:22:47 -05:00
artifact.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
asset.test.ts fix(assets): accept identity-provider characters in image upload namespaces (#12288) 2026-08-27 11:27:31 -07:00
asset.ts fix(assets): accept identity-provider characters in image upload namespaces (#12288) 2026-08-27 11:27:31 -07:00
budget.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
claude-setup-token-session.test.ts feat: Claude login on the new-agent page before agent creation (#11347) 2026-08-17 13:42:51 -07:00
claude-setup-token-session.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
company-portability.ts Remove the company brand color and per-company attachment limit (#12291) 2026-08-27 12:11:05 -07:00
company-skill.test.ts Build the Skills Store (#7990) 2026-06-11 14:02:09 -05:00
company-skill.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
company.test.ts Remove the company brand color and per-company attachment limit (#12291) 2026-08-27 12:11:05 -07:00
company.ts Remove the company brand color and per-company attachment limit (#12291) 2026-08-27 12:11:05 -07:00
connection-intent.test.ts feat(connections): add self-serve intent runtime (#12345) 2026-08-29 12:08:34 -05:00
connection-intent.ts feat(connections): add self-serve intent runtime (#12345) 2026-08-29 12:08:34 -05:00
cost.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
decision-queue.ts feat(decisions): add desk workflow and retention (#10672) 2026-08-02 10:47:03 -05:00
decision.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
document-annotation.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
environment-custom-images.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
environment.ts refactor(environments): make execution environments instance-scoped (#8375) 2026-06-20 09:42:53 -07:00
execution-workspace.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
external-object.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
feedback.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
finance.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
folder.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
goal.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
inbox-agent-policy.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
index.ts Clean up experimental settings features (#12681) 2026-09-01 14:23:05 -05:00
instance.test.ts feat(ui): add streamlined navigation foundation (#12746) 2026-09-02 23:55:43 -07:00
instance.ts feat(ui): add streamlined navigation foundation (#12746) 2026-09-02 23:55:43 -07:00
issue-tree-control.ts [codex] Roll up May 17 branch changes (#6210) 2026-05-17 17:15:06 -05:00
issue.test.ts Remove cheap model profiles (#12683) 2026-09-01 14:57:38 -05:00
issue.ts Remove cheap model profiles (#12683) 2026-09-01 14:57:38 -05:00
native-finalization.test.ts feat(runner): add native persistence contracts (#12169) 2026-08-25 13:08:39 -05:00
native-finalization.ts feat(runner): add native persistence contracts (#12169) 2026-08-25 13:08:39 -05:00
onboarding-seed.ts feat(server): receive and apply the Paperclip Cloud onboarding seed (#11098) 2026-08-12 22:54:07 -07:00
partial.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
pipeline.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
plugin.test.ts feat: parallelize sandbox file-sync behind a provider opt-in capability (#11736) 2026-08-19 12:34:11 -07:00
plugin.ts feat(runner): add remote execution substrate (#12638) 2026-09-01 01:29:06 -05:00
project.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
provider-trace.ts feat(runner): add Codex-native application integration (#12591) 2026-08-31 14:38:38 -05:00
resource-memberships.ts feat(server): add per-user document stars (#9952) 2026-07-27 19:13:35 -05:00
routine.test.ts feat(routines): expose activity gate API (#9438) 2026-07-24 16:47:24 -05:00
routine.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
runtime-exposure.test.ts feat(runtime-exposure): least-privilege Tailscale HTTPS broker, shared contract, and persisted exposure state (#11524) 2026-08-17 05:54:12 -04:00
runtime-exposure.ts feat(runtime-exposure): least-privilege Tailscale HTTPS broker, shared contract, and persisted exposure state (#11524) 2026-08-17 05:54:12 -04:00
search.ts fix(search): honor extract match limits + harden pr-gardening candidate discovery (#9652) 2026-07-15 21:44:21 -05:00
secret.test.ts feat(secrets): add user-specific runtime secrets (#8825) 2026-07-05 05:58:20 -05:00
secret.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
sidebar-preferences.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
skill-policy.test.ts feat(skills): open-by-default company skill policy and core UX (#9564) 2026-07-15 11:42:40 -05:00
skill-policy.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
smoke-lab.ts feat(mcp) [split 2/8]: add governed access contracts (#9557) 2026-07-14 12:57:20 -05:00
status-card.test.ts feat(status-cards): add experimental status card update view (#10101) 2026-07-24 12:26:43 -05:00
status-card.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
summary-slot.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
teams-catalog.ts [codex] Add teams catalog extraction (#7550) 2026-06-05 12:55:49 -05:00
text.ts Normalize escaped multiline issue and approval text (#4444) 2026-04-24 18:02:45 -05:00
tool-access.test.ts feat(connections): add managed external MCP connectors (#12346) 2026-08-29 12:08:34 -05:00
tool-access.ts feat(connections): add managed external MCP connectors (#12346) 2026-08-29 12:08:34 -05:00
trust-policy.test.ts fix(auth): clarify protected-agent assignment blocks (#10893) 2026-08-05 10:09:17 -05:00
trust-policy.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
work-product.test.ts Harden issue artifact metadata 2026-05-30 20:41:13 +00:00
work-product.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00
workspace-file-resource.ts build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) 2026-08-21 00:04:14 -07:00