<!-- entire-trail-link-start --> https://entire.com/gh/paperclipai/-/trails/1/changes/paperclip/1 <!-- entire-trail-link-end --> ## Thinking Path > - Paperclip manages agents and their execution environments. > - New agent setup saves an inactive agent before model connection tests. > - Some plugins need that agent to prepare its execution resource. > - The wizard tested without the agent ID, while the setup hold prevented preparation. > - Environment changes also discarded the selected model account. > - This change prepares the saved draft during setup and keeps normal execution held. > - Users can test the prepared resource before they finish hiring. ## Linked Issues or Issue Description **What happened?** An agent-owned plugin environment could not acquire a test lease during hiring. Changing environments also returned the user to Connect and cleared the selected account. **Expected behavior** Keep the selected account, invalidate its test, and prepare the saved agent resource in the background. Test that same agent before finishing setup. **Steps to reproduce** 1. Start a new Claude or Codex agent and select a saved account. 2. Change to an agent-owned plugin environment. 3. Try to finish setup or reconnect the account. Related: #17750 defers probes until after hire submission. This change implements preparation during the wizard instead. The related PR search and ROADMAP review found no other implementation of this setup preparation path. ## What Changed - Add the optional `requiresAgent` driver declaration. Require agent lifecycle participation when it is set. - Prepare saved drafts on creation or environment changes. Keep the setup hold and wait in `verifying` without background verification scans. - Bind tests to the saved agent. Return a warning without allocating a lease when the required agent is absent or still preparing. - Preserve the account and configuration step when the environment changes. Save the selection and invalidate the old test. - Show active preparation and support authorized retries. Keep approval, company, budget, and normal task admission controls. - Document the contract and cover lifecycle, lease, manifest, and wizard behavior. ## Verification - Server and UI TypeScript checks passed. - 112 wizard and setup helper tests passed. The shared manifest suite passed. - 123 lifecycle, policy, lease, and environment-test API cases passed after the approval-gate fix. The diagnostic and driver suites and all 80 agent adapter route tests also passed. - Token gates, module boundaries, map validation, and whitespace checks passed. - All 66 lifecycle/policy cases passed after the stopping-draft permission fix. The new real-DB route case verifies creator success, other-creator denial, and refusal to complete a hire while stopping. - Full workspace typecheck and build were attempted. Both stop at the unchanged Rust Runner step because Cargo is not installed on this host. - CI on43be3c93dpassed all automated checks, including full test shards, typecheck, build, Rust checks, browser suites, and canary checks: https://github.com/paperclipai/paperclip/actions/runs/40368174530. - The full local repository test command was started. Two unchanged workspace tests assume Git's initial branch is master; this host defaults to main. Both fail in isolation under the host default and pass with process-scoped init.defaultBranch=master. The broad run was stopped after those confirmed fixture failures; CI supplies the full clean check. - Early new-test failures were fixture collisions and an unscoped sweep assertion; the fixtures and assertion were corrected. One route-suite load raced with SDK output regeneration; rebuilding first and running the suite afterward passed. - Initial CI exposed a route mock missing the new prerequisite lookup. The fixture was updated and a real HTTP no-lease case was added; all 54 cases in that route suite pass. Security review identified allocation before required approval; the new approval gate and its tests address it. - CI on50b5a08afreported 32 of 33 expected calls in the unchanged cleanup-history scheduling test. Its isolated case passed locally without cleanup-code changes; the original failure remains recorded and the final CI run passes on the current head. - Standard Greptile reviewed43be3c93dat 5/5. A subsequent deeper review identified runner selection, stale detail reads, error retention, and test file size issues; 70343387b addresses all four with resolved threads. Standard review returned 5/5 on that commit and again on rebased headfda42c5ab. The rebase preserves master's new managed environment skill declarations alongside requiresAgent. Full CI onfda42c5abpasses: 55 successful checks, two intentional skips, no failures. Run: https://github.com/paperclipai/paperclip/actions/runs/40405121641. - After those fixes, 133 UI tests and 61 lifecycle/policy cases pass; all eight focused UI regressions fail against the previous implementation and pass with the fix. Token, map, and whitespace gates pass. The stale-read fixture initially omitted the setup URL because navigation is mocked; following the URL activates the real detail query and reproduces the race. - UI TypeScript passes. This host's server dependency links now point to a separate scratch checkout lacking requiresAgent, so the ordinary server check reports that missing property. A no-emit check pinned to this branch's shared declarations passes; it disables declaration generation and supplies explicit local type roots. The first temporary configuration lacked those type roots; the corrected configuration passes. CI remains the full workspace verification. - After rebasing onto8373d7867, all 133 UI, 61 lifecycle/policy, and 44 manifest cases pass again, as do UI TypeScript, token, map, and whitespace checks. The server no-emit check now hits three mismatched SDK/Runner declarations from the scratch dependency links; these are outside this change. Full CI builds the complete dependency set. - Review cycle: the first Apex review scored 3/5 with four findings. All were fixed together, the branch was rebased to resolve a schema conflict, full CI and standard Greptile passed, and a second Apex review returned 5/5 onfda42c5abwith zero new comments. All six review threads are resolved, and the PR is conflict-free. Review: https://github.com/paperclipai/paperclip/pull/17761#issuecomment-6422635718. - No live provider resource was created and no deployment was performed. ## Risks Plugins must opt in and ship a compatible declaration. Companies requiring hire approval keep drafts paused and defer allocation and verification until approval. Other companies prepare drafts during the wizard under their existing agent-creation authority; the setup hold still blocks ordinary work. Preparation uses existing lifecycle ownership, retry, and cleanup paths. The open wizard polls only while preparation or stopping is active. No database migration is required. ## Model Used OpenAI Codex, based on GPT-6, with reasoning, tool use, and code execution. The exact serving model ID and context window size are not exposed. ## 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 described the issue in-PR using the bug report fields - [x] I have not referenced internal or instance-local issues or links - [x] My branch name describes the change and contains no internal ticket id - [x] I have run the targeted tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation - [x] I have considered and documented the risks - [x] All Paperclip gates are green — 55 successful checks and two intentional skips onfda42c5ab- [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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
20 KiB
Hiring, agent configuration, and organization — agent access
Product map: Hiring, agent configuration, and organization.
Feature ID: agents.
Review date: 2026-10-12. Source commit: 58e16dbddfc9c8d0cf60867f9d9847f0feda055b.
Native REST transport reconciled in this change; see the
shared transport contract.
This is a source-reviewed baseline of representative operations and known gaps. Each capability needs operation-level review before its entire scope can be qualified. No live agent execution is claimed. Follow the map contract for format, permission checks, evidence and maintenance.
Scoped runner-default source review: 2026-10-12 at
eee0534154eaf5d0d3f2bbc97c1e24d86f34a5a5, limited to creation/configuration,
approval activation, built-in provisioning and import preservation described
below. The original baseline commit above still governs unrelated entries; this
update does not claim operation-complete review or live agent verification.
hire
Capability ID: agents/hire.
Review: baseline.
API: present — representative operation IDs:
POST /api/companies/{companyId}/agent-hires.POST /api/companies/{companyId}/agents.
Agent access: partial — Native hire_agent; REST / CLI agent; runtime inheritance for
native hires.
Creation requests can use runner: auto | paperclip | legacy; the server resolves
and persists execution configuration. Claude Auto selects the native ACPX profile
on qualified macOS and GNU/Linux x64/ARM64 targets; unknown environment
qualification remains Legacy. Darwin SSH defaults to Legacy while preserving
explicit native assets and saved execution. Saved runner/model/provider overrides survive edits
and approval activation. This selection does not grant connection access or
bypass hiring authorization. Source: runner resolver.
Policy: Agent creation/configuration uses action grants, resource policies and change consent; some controls require a board actor.
The early wizard record (setupId on create) and completion of that record
(setupAgentId on hire) require a board actor and company-scoped creation
permission. Its creator can finish their own inactive setup with that permission;
changing another person's setup requires configuration permission.
Creation retries reuse only records owned by the caller. Returning a completed
record also requires the normal agent-read and configuration-read checks.
An unfinished record keeps compatibility status paused with a
setup hold and cannot receive API keys or authenticate with keys or JWTs.
Its standard grants apply at hire. Authorized completion retries recover the
same record and approval without changing the submitted configuration.
Normal agent-authored hiring keeps its existing approval policy.
An agent-owned plugin may prepare the draft and leave its lifecycle in
verifying while that setup hold remains. Only bounded Core-issued setup probes
can run there. The creator's company creation permission also covers configuring
and retrying their draft during preparation or stopping; other actors still require the
ordinary configuration permission. This is a board wizard path, not new agent
execution or probe authority. Lifecycle and component regressions cover these
transitions; no permitted-agent or live-provider journey is claimed here.
Companies requiring hire approval keep drafts paused and allocate no agent-owned
resource before approval. Selecting an account there is pending verification,
not approval or execution authority.
The creation boundary resolves the request-level runner before adapter validation
and credential normalization. Omitted/automatic new Codex selection uses the
qualified target's default; explicit Legacy is retained. Disabled adapters and
external overrides affect new selection, while missing credentials/runtime or
incompatible settings remain errors. Existing agents and reviewed pending hires
retain their recorded execution. Native hire_agent explicitly inherits its
caller's runtime and remains subject to permission and credential restrictions;
it is not an arbitrary host-configuration or login tool. REST/CLI creation and
hire runner options use the shared request contract.
Evidence: source-only — implementation at
the reviewed commit above.
Scoped Evidence: source-only — creation policy,
runner resolution,
native hire binding,
frozen approval activation
and same-harness import preservation
at the scoped commit. No permitted-agent journey was executed for this map update.
Verification: not-run — exercise a listed permitted operation with actual agent
credentials/run context; inspect its result and applicable persistence/attribution.
Assert the relevant denied actor, owner, company or mode from Policy. Review the
remaining operations before qualifying the whole capability.
For this scope, compare automatic and explicit Legacy creation, assert foreign company/environment and missing-grant denials, then compare pending approval configuration across restart and activation. An unrelated edit/import update must not change existing execution; a new package without a runner choice receives creation defaults. Do not count a board call or component test as agent evidence.
Gaps: Identity/persona hiring works. Operator account login and sensitive adapter/environment configuration are separate guarded actions.
The runner request does not grant new account, environment-probe or native API fallback authority; see validation access and environment administration. Full access qualification remains not run.
instructions
Capability ID: agents/instructions.
Review: baseline.
API: present — representative operation IDs:
GET /api/agents/{id}/instructions-bundle/file.GET /api/agents/{id}/project-accessandPOST /api/agents/{id}/project-accessare board-only. The POST requiresagents:create, checks selected projects in the same company, and adds IDs under an agent row lock. It preserves existing containment, audits new grants and rejects pending-approval agents. Agent keys cannot use this route to grant themselves access; a read-only board viewer receivescanManage: false. Saving never creates a run or wakeup.PUT /api/agents/{id}/instructions-bundle/file.PATCH /api/agents/{id}with an explicitrunner: "paperclip"upgrade.POST /api/agents/{id}/qualify-runnerto qualify the saved effective sandbox before upgrading.PATCH /api/agents/{id}withruntimeSettings: { harness, model?, aiConnection?, expected: { model, aiConnection } }for a narrow roster edit. Each request handles one agent; the UI batches at most four writes and collects per-agent outcomes.
Agent access: available — Native read/update/history/restore instruction tools; REST /
CLI.
Policy: Agent creation/configuration uses action grants, resource policies and change consent; some controls require a board actor.
The roster intent preserves unrelated settings, rejects stale model/connection previews and harness changes, and checks the full execution configuration under the lifecycle write lock. It uses the same configuration, company, credential, environment, and consent checks as other edits. It adds no agent permission or credential fallback. Pool and externally managed agents use their existing configuration surfaces. Board browser verification does not qualify agent access.
The existing-agent upgrade notice uses this configuration PATCH. It does not
grant configuration, account, or environment access. The server resolves the
saved settings under normal company/configuration authorization. Obsolete Claude
tuning fields are removed with configurationWarnings; security incompatibilities
remain errors. Unqualified sandbox upgrades first use the agent-scoped
POST /api/agents/{id}/qualify-runner under the same agent_config:update
authorization as saving the upgrade. The server resolves the saved computer;
expectedEnvironmentId rejects stale state and cannot select another computer.
Qualification checks company binding, returns only its receipt, and audits within
the agent's company. General instance environment probes still require instance
admin. No probe runs merely on page load. Operator browser evidence does not
qualify the agent permission paths for this operation.
Evidence: source-only — implementation at
the reviewed commit above.
Verification: not-run — exercise a listed permitted operation with actual agent
credentials/run context; inspect its result and applicable persistence/attribution.
Assert the relevant denied actor, owner, company or mode from Policy. Review the
remaining operations before qualifying the whole capability.
Gaps: Canonical entry file, revision guard, company boundary, and protected-change policy apply.
organization
Capability ID: agents/organization.
Review: baseline.
API: present — representative operation IDs:
GET /api/companies/{companyId}/org.PATCH /api/agents/{id}.
Agent access: available — list_agents/get_agent; native call_api for permitted
configuration fields; REST / CLI.
Policy: Agent creation/configuration uses action grants, resource policies and change consent; some controls require a board actor.
Evidence: source-only — implementation at
the reviewed commit above.
Verification: not-run — exercise a listed permitted operation with actual agent
credentials/run context; inspect its result and applicable persistence/attribution.
Assert the relevant denied actor, owner, company or mode from Policy. Review the
remaining operations before qualifying the whole capability.
Gaps: Reporting-line changes need configuration authorization; a title alone gives no authority.
lifecycle
Capability ID: agents/lifecycle.
Review: baseline.
API: present — representative operation IDs:
POST /api/agents/{id}/pause.POST /api/agents/{id}/resume.POST /api/agents/{id}/terminate.DELETE /api/agents/{id}permanently purges an eligible terminated/rejected agent.POST /api/agents/{id}/lifecycle/retry.GET /api/agents/{id}returns the safe failed phase/step and action inlifecycleError.
Agent access: partial — REST / native call_api resume under agent_config:update
change-grant authorization; pause and termination remain board-only.
Policy: Agent creation/configuration uses action grants, resource policies and change
consent; some controls require a board actor.
Permanent deletion is board-only. Retained case handoff references return
409 agent_case_history_retained before dependency cleanup; keep the agent terminated.
Evidence: source-only — implementation at
the reviewed commit above.
Verification: not-run — exercise a listed permitted operation with actual agent
credentials/run context; inspect its result and applicable persistence/attribution.
Assert the relevant denied actor, owner, company or mode from Policy. Review the
remaining operations before qualifying the whole capability.
Gaps: Resume has a generic native REST path. Pause and termination remain enforced actor restrictions.
built-in
Capability ID: agents/built-in.
Review: baseline.
API: present — representative operation IDs:
POST /api/companies/{companyId}/built-in-agents/{key}/provision.
Agent access: partial — REST / native fallback for eligible provisioning; built-in
routine controls require board.
Policy: Agent creation/configuration uses action grants, resource policies and change consent; some controls require a board actor.
Evidence: source-only — implementation at
the reviewed commit above.
Verification: not-run — exercise a listed permitted operation with actual agent
credentials/run context; inspect its result and applicable persistence/attribution.
Assert the relevant denied actor, owner, company or mode from Policy. Review the
remaining operations before qualifying the whole capability.
Gaps: Provisioning checks agents:create. Enabling/running its built-in routine is not the same permission path.
Scoped source review: built-in provisioning recognizes the underlying Codex harness of a native company agent. New configured provisioning resolves the runner, while unrelated reconciliation and same-harness edits retain existing execution. Verify explicit runner changes preserve compatible saved settings; the general creation/access policy above still applies. This is source-only evidence at the scoped commit, not a live provisioning result.
primary-agent
Capability ID: agents/primary-agent.
Review: baseline.
API: present — GET and PUT /api/companies/{companyId}/primary-agent/me.
Agent access: restricted — this is the authenticated human's personal
preference. Agent keys and native call_api use agent identity and are denied by
the board gate; no dedicated agent selection tool is present.
Policy: Requires board user identity, company access and active membership, except implicit-local board or instance administrator. Viewers may choose their own primary. Selection requires a same-company readable, available agent and is scoped to actor user ID; the request cannot select another user's preference. Explicit null selection is rejected; leave/termination can clear an unavailable choice. Initialization stays recorded so clearing does not silently replace it.
Evidence: source-only — reviewed on 2026-10-13 at
60bc0d5fee9a6e48db08fc016521fee3d9f57d67:
routes,
service,
provider, and
route tests.
Verification: not-run — select and read the preference as two company users;
assert isolation, wrong-company/unreadable targets, pending/terminated agent
rejection and agent-key denial. Verify replacement confirmation and fallback
precedence in the UI; inspect the cleared state after permitted leave/termination.
Gaps: No agent mutation path for another person's preference. Live human/agent access is unverified; UI fixture callbacks do not establish persistence or task and Chat default resolution.
grok-bot
Capability ID: agents/grok-bot.
Review: baseline.
API: present — POST /api/companies/{companyId}/grok-invitations, operator-owned Grok invitations and agent-scoped /grok-binding setup, routine, verify, stop, recover and disconnect endpoints. Direct HTTPS /mcp/runner uses fixed named-agent OAuth. Grok tools expose durable assignment operations and task-bound upload/download grants.
Agent access: available — paperclip_grok_* through the dedicated agent grant. First-party Paperclip operations execute through the shared Rust Runner. The Bot retains its own apps; Paperclip workspace and third-party app tools are unavailable.
Policy: company/agent/client/resource/authorizer binding; current manage-agent permission for consent and subsequent calls; normal task ownership, controller lease, governance, pause, revocation and recorded budget checks. Execution and file transfers require current task-bound sessions. Secret credentials remain in encrypted secret storage and are redacted from HTTP logs.
Evidence: source-only — routes, shared authority, routine receipts and Runner broker. Temporary actual-client OAuth and an outbound routine wake are qualified separately; they do not prove this candidate’s acceptance.
Verification: not-run — deployed acceptance pending; focused protocol/authorization and actual Rust backend tests; run fresh/saved setup, assigned and proactive tasks, duplicate calls, stale sessions, restart, ambiguous delivery, stop and recovery through the real client on the serving managed candidate.
Gaps: deployed two-way work and unattended first-time onboarding remain unqualified; remote termination, provider transcript streaming and usage accounting are unavailable.
api-keys
Capability ID: agents/api-keys.
Review: baseline.
API: present — GET /api/agents/{id}/keys; POST /api/agents/{id}/keys; DELETE /api/agents/{id}/keys/{keyId}.
Agent access: restricted — key listing and mutations require board identity and agent-management authority. The CLI token agent commands use authorized board context. Ordinary agent REST/native call_api and public assistant capabilities do not grant key-management authority.
Policy: getAccessibleAgent checks company access and agents:create through the shared access evaluator for reads as well as mutations. Creation rejects pending_approval and terminated agents. Keys retain the creating person’s responsibleUserId; only a hash is stored and token plaintext is returned on creation. Revocation checks that the key belongs to the selected agent. Authentication separately applies agent state, revocation, scope, and responsible-user membership intersections.
Evidence: source-only — reviewed at 9ef434fe79c57d976b8b03b14c5242db270b8320. Keys tab, key routes, key service, authentication, and CLI token commands.
Verification: not-run — Create a disposable key as a permitted authenticated board person, prove one harmless agent read, revoke, and retry the same bearer. Assert metadata persistence, once-only token display, activity, missing management permission, agent identity denial, cross-company/cross-agent IDs, ineligible targets, and missing responsible-user binding.
Gaps: Local implicit key creation does not by itself prove a usable responsible-user binding. No ordinary-agent self-management or assistant delegation path is established; browser creation and actual bearer use need live evidence.
managed-agent-setup
Capability ID: agents/managed-agent-setup.
Review: baseline.
API: present — GET and POST /api/companies/{companyId}/managed-agent-profiles. Provisioning separately calls Anthropic /v1/environments, /v1/agents, and /v1/agents/{id}/versions with operator provider credentials; --probe does not resolve a Paperclip client context or call the profile API.
Agent access: operator-only — provider qualification/provisioning uses the explicit operator CLI. Persisted profile reads/writes require board/company identity; viewer writes are denied. This does not authorize a company agent to provision external provider resources.
Policy: A profile uses an active same-company, company-scoped secret reference. Qualification requires the source-supported pinned model/version, no tools/MCP/skills/multiagent capability, and a locked no-network/no-packages environment with retention acknowledgement. Qualified configuration revisions are immutable; changed qualified configuration requires a new profile key. Provider API credentials and Paperclip profile authority are separate checks.
Evidence: source-only — reviewed at 9ef434fe79c57d976b8b03b14c5242db270b8320. Managed-agent CLI, profile routes, profile service, and runtime validation.
Verification: not-run — Compare provider and Paperclip state before/after probe, then inspect a permitted create/adopt and repeated resource reuse. Reject missing acknowledgement, unsafe resources, invalid model/version/secret/company, and viewer/agent mutations. Separately run a bounded useful task with the saved qualified profile before claiming runtime readiness.
Gaps: This is a provider-specific setup path, not qualification of every managed service or deployed environment. Mocked setup and source validation do not prove live retention, remote execution, or provider availability.