mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-06 10:48:12 +02:00
c5c80e1febe903e5e2d45d2664cd4394b5e797ed
454
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
60ee13a0f7 |
feat: allow operator UI snippets on Cloud instances (#13168)
Adds an optional Cloud-only HTML snippet so operators can load Plain’s standard chat bubble. **6 files, 16 implementation lines added; 102 additions including tests and docs.** ## Thinking Path > - Paperclip serves Cloud and self-hosted users. > - Closed beta users need a way to report problems. > - Plain provides a ready-made chat widget. > - Cloud operators can load it through a generic deployment setting. > - Self-hosted instances ignore that setting. ## Linked Issues or Issue Description **Subsystem affected** Server-served UI HTML. **Problem or motivation** Enable a chat bubble in Cloud without adding a support feature to the React app. **Proposed solution** Insert trusted `PAPERCLIP_CLOUD_UI_SNIPPET` HTML before `</body>` when the existing Cloud-managed predicate is true. The setting is off by default. Related Cloud-gated integration: #12190. ## What Changed Review the [final diff](https://github.com/paperclipai/paperclip/pull/13168/files) in this order: 1. `server/src/cloud-ui-snippet.ts`: the eight-line Cloud gate and HTML insertion. 2. `server/src/static-index-html.ts` and `server/src/app.ts`: apply it to static root/index, SPA routes, and Vite HTML. 3. Two test files and `doc/cloud-ui-snippet.md`: boundary checks and setup instructions. React UI, customer identity, and database behavior are unchanged. The existing feedback flag remains. Plain chat is anonymous; no Paperclip name, email, or organization is supplied. ## Verification - **Greptile: 5/5**, no actionable findings, reviewed commit `04bb44515`. - **[CI passed](https://github.com/paperclipai/paperclip/actions/runs/34535763243)**, including build, typecheck, server tests, and end-to-end tests. - Local: six focused tests, full typecheck, and build passed. The full local suite has not produced a final result; CI is the completed full verification. - Staging deployment and live chat testing remain to be done. ### Staging setup Set **one server environment variable**, `PAPERCLIP_CLOUD_UI_SNIPPET`, to: ```html <script> (function(d) { var script = d.createElement('script'); script.src = 'https://chat.cdn-plain.com/index.js'; script.onload = function() { Plain.init({ appId: 'liveChatApp_01M26J213F6RR53YRARZVAFCZZ' }); }; d.head.appendChild(script); })(document); </script> ``` This is the public staging app ID. **No API key or signing secret is needed.** Deploy to staging and restart the app with this setting. Test `/`, `/index.html`, and an organization dashboard; send a message and confirm a support reply returns. Production rollout is separate. [Plain embed docs](https://www.plain.com/docs/product/channels/chat) · [Configuration and rollback](https://github.com/paperclipai/paperclip/blob/04bb4451510b124f21b6771b7a8163faad61d8ec/doc/cloud-ui-snippet.md) ## Risks Only trusted operators should set this value. The HTML is public and scripts execute in the app origin; do not include secrets or user-provided HTML. Plain owns the anonymous browser session, with no Paperclip account-switch integration. To roll back, unset the variable, restart, and refresh open tabs. ## Model Used OpenAI Codex (GPT-6), with repository inspection and code execution. Exact runtime model identifier and context size are not exposed in this session. ## 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 and contains no internal Paperclip ticket id or instance-derived details - [ ] 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
889947c238 |
feat: add experimental native chat connectors (#13038)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - People also ask agents for work in their existing chat tools. > - Each external conversation needs one task and a current authorized source. > - Retries, Stop, and provider failures must not duplicate work or expose private data. > - The first chat PR establishes the opt-in provider and data contracts. > - This PR adds experimental channel integration and its durable control plane. > - Users can request work from connected channels and inspect delivery in Paperclip. ## Linked Issues or Issue Description Refs #13100 and #13092. This is the second of exactly two chat PRs. Foundation #13100 is merged and changed 143 files. Runner prerequisite #13092 is also merged. This PR changes 400 files against master, below the 500-file review limit. It contains no wireframe images or HTML galleries. ## What Changed - Add native Slack, GitHub, Microsoft Teams, Telegram, and Discord chat connections. Keep chat disabled unless the operator enables experimental chat connectors. Preserve the production GitHub tool connection and its normal setup path. - Bind each provider bot identity to one immutable Paperclip agent. Bind each admitted external conversation to one task. Paperclip owns tasks, runs, permissions, and audit records. - Add durable admission, per-conversation queues, questions, task controls, progress, final replies, images, files, and delivery receipts. Board comments remain internal unless explicitly sent to the channel. - Check current identity, provider reach, resource access, credentials, runtime generation, and exact source before provider effects. Keep private responses private. Never send raw reasoning, private logs, credentials, or tool arguments. - Hold uncertain sends for explicit audited resolution. Make Board Send-to-channel atomic and idempotent. Keep reconnect and setup credentials in Paperclip secret storage. - Preserve current native-runner authority across retries, lost acknowledgements, and recovery. Keep immutable input and completion contracts separate from newer user input. Receipt reconciliation cannot launch a provider. - Reconcile chat close/new ordering and provider-effect lock order. Audit resource access changes in the same transaction. Submit only the selected resource from each UI toggle so stale pages cannot undo unrelated access changes. - Drain Codex stdout before certifying process exit. Bound the drain with the existing shutdown grace. Preserve observed terminal authority without treating an undrained process as successful or reusable. - Incorporate master `018ca5da` with its ACP Stop, mobile task layout, runner packaging, and official lock changes. Preserve dedicated chat-answer continuations in both directions when ordinary queued comments are adopted after Stop. - Fence late adapter readiness behind an earlier Stop for the same run. Preserve verified cleanup for registered adapters. Handle single Stop, agent pause, duplicate Stops, and failure release without creating a false cancellation receipt. - Incorporate master's `6dd48cad4` wake-queue extraction. Preserve exact failed-chat retry authorization and lineage, retired question-source suppression, and the block on generic recovery that would discard the admitted source. Fresh deferred input retains its separate promotion path. - Incorporate master `2a05b5ed3` and its queue-admission extraction, simplified transaction ports, and separate runner CI job. Preserve exact durable receipts, actor separation, and dedicated-answer isolation through the new module. A failed receipt insert rolls back the accompanying deferred-wake merge. ## Verification Current head: `afe19299d06253cb628eb398e91d1200ea9f412a`, incorporating master `2a05b5ed3457ea33efd6895520447d1d97fe98d8`. The conflicts are resolved. This successor fixes two test-harness boundaries exposed by CI: per-case route-module preparation and actual durable-save completion before intentional runner termination. Production code and all existing test/turn deadlines are unchanged. [Exact-head Greptile review](https://github.com/paperclipai/paperclip/pull/13038#issuecomment-5587250594) is **5/5**, completed September 10 at 13:20:55 UTC, with no actionable findings or open review threads. [Fresh exact-head CI](https://github.com/paperclipai/paperclip/actions/runs/34481724341) passes **all 24 jobs**, including Build and both required aggregates. Normal exact-head guarded merge was attempted and rejected by the remaining branch approval policy: CODEOWNER review is required and no human approval is present. Normal **squash auto-merge is enabled** as of September 10 at 13:36:26 UTC. Requested CODEOWNERS have been notified; no approval bypass or self-approval was used. Earlier-head results below remain historical evidence, not qualification of this successor. - Final exact-head Linux evidence: 995/995 chat integration cases; 36/36 agent-skills routes; 35/35 runner live-session cases, including real process kill/resume; 1948 runner Vitest cases with three existing benchmark/platform guards; 870/870 API-authority cases; and 104 browser cases with four existing optional skips. Rust, conformance/replay, full repository build, typecheck, canary, all server/workspace shards, and both required aggregates pass with normal CI concurrency. Earlier failed attempts remain recorded below. - Latest test-only qualification: 141/141 route/permissions/authentication cases pass in separate cold forks, with plain server types and independent review clear. The real-runner suite passes 35/35, with plain runner types and independent review clear. A controlled premature-save acknowledgement fails as expected; matching ownership/effect/process evidence, rejected saves, real turn outcome, test abort, and pre-kill liveness are covered. No local reproduction of the original CI scheduling failure is claimed. The preceding [CI run](https://github.com/paperclipai/paperclip/actions/runs/34479680858) passes 21/24 jobs, including all 995 Linux chat cases and browser aggregate (104 passed, four existing optional skips); only Build, the skills serialized shard, and the required verification aggregate fail. Its exact-head Greptile review was 5/5. Both failed job logs are retained. - Final fixture qualification: all eight focused Discord cases and all 995 chat integration cases pass. The exact modal statement/PID is observed before taking the real connection lock; the test then proves its actual blocking relationship before mutation. Original SQL execution, provider behavior, negative assertions, and 1s/15s timeouts remain unchanged. Independent review is clear and test/production hashes remain frozen. The preceding [CI attempt](https://github.com/paperclipai/paperclip/actions/runs/34477184777) passed 22 jobs, including Build/runner, typecheck, canary, all other test shards, and browser aggregate (104 passed, four existing optional skips); the two fixture failures and failed verification aggregate remain recorded, not relabeled as a pass. - Current queue-module composition: 308/308 recovery/batching/queue/Stop tests; 995/995 full chat integration; 89/89 module tests, including real PostgreSQL receipt-insert rollback; 24/24 workflow/module-boundary tests; plain server and UI types. All four actual local process/ACP browser paths pass in 1.4 minutes. Fresh databases, no skips or retries, stable reviewed source hashes. The initial boundary failure is retained; its no-op service wrapper was removed without changing recovery context or weakening the check. An exploratory standalone test-directory typecheck fails because its new upstream transformation config is not a standalone typechecking project; standard CI/build does not invoke it, and no configuration was weakened to suppress those diagnostics. - The preceding head `e02a63d462ce5d47433b0aeb632bb6fd20aab1ba` passed [all 24 CI jobs](https://github.com/paperclipai/paperclip/actions/runs/34436462958) and exact-head Greptile review at 5/5. Required CODEOWNER review prevented its normal merge before master advanced again. - Final extracted-module composition: 307/307 recovery, batching, queue and Stop-control tests; 995/995 full chat integration; 49/49 module tests including eight PostgreSQL adapter cases; and 19/19 issue-update tests. Plain server types pass. All four actual local process/ACP browser paths pass in 1.3 minutes. Fresh databases, no skips or retries in these cohorts, frozen source hashes, and independent review clear. - The preceding head `3e4e1c1c` passes [all PR CI jobs](https://github.com/paperclipai/paperclip/actions/runs/34415826820), including Build and required `ci / verify` and `ci / e2e`. Both the original Rust failure and the previously load-sensitive lineage fixture pass with unchanged Linux concurrency. Master advanced afterward and required this reconciliation. - Final master composition: 448/448 focused UI tests, 186/186 adapter tests, 24/24 queue/control tests, and 11/11 packaging tests. Plain UI, server, shared, and adapter types pass. Token gates and diff checks pass. Independent server and UI reviews are clear. - Stop-registration regression: both real-service cases fail against exact `a95` source and pass with the fix. The full corrected recovery/control suite passes 265/265. Duplicate-owner and failed-Stop controls also pass. Plain server types pass. The readiness barrier prevents provider startup without adding an acknowledgment to an already terminal run. - Final qualification strengthens terminal-field equality and repeats both affected cases successfully on a fresh database. All four actual local process/ACP browser paths pass again in 1.3 minutes, without skips or retries. The final screenshot shows Cancelled, a paused subtree, retained input, and no error toast. - Two new actual-service regressions fail before the merge fix. They prove that queued-comment adoption could consume a dedicated chat answer or add unrelated input to that answer. The fixed four-case cohort passes, including ordinary upstream continuation and adapter Stop controls. Full recovery passes 257/257. All four actual local process/ACP Stop browser flows pass in 1.4 minutes, without skips or retries, on a fresh database. - The unchanged runner artifact was qualified with 171/171 transport tests, 870/870 API-authority tests, conformance 1/1, and replay 11/11. Six controlled reader tests prove the exit/drain repair. Its local serial Rust workspace passed 546 top-level cases plus two invoked helpers; the later passing Linux CI supplies default-concurrency evidence. - Prior exact-source full chat integration passes 995/995. Settings regressions cover concurrent stale pages, 501 destinations, pending state, rejected updates, and explicit retry. These deterministic tests do not prove live provider behavior. - Retained failed attempts and their causes are in the [qualification log](https://github.com/paperclipai/paperclip/blob/afe19299d06253cb628eb398e91d1200ea9f412a/doc/plans/chat-adapters/2026-09-08-chat-queue-and-webhook-repair.md). The first merge adapter run timed out while macOS slept for 290 seconds. Its unchanged repeat passed with a temporary sleep guard. No assertion, deadline, or CI gate was weakened. Review commands include `pnpm --filter @paperclipai/server exec vitest run src/__tests__/heartbeat-process-recovery.test.ts src/__tests__/issue-queued-comments-routes.test.ts` and `pnpm exec playwright test --config tests/e2e/playwright.config.ts tests/e2e/acp-stop-continuation.spec.ts`. Database suites require fresh disposable databases. See the [browser runbook](https://github.com/paperclipai/paperclip/blob/afe19299d06253cb628eb398e91d1200ea9f412a/doc/plans/chat-adapters/2026-09-04-chat-adapters-browser-e2e-runbook.md) for provider setup and separate live acceptance steps. ## Risks - This remains experimental. Deterministic tests and bounded live evidence do not establish every provider feature, tenant, permission layout, or media shape. Teams work-tenant qualification is still open. - Failed and uncertain provider effects remain visible and can require operator action. A transport receipt does not prove recipient visibility. - Native controller and runner artifacts must remain compatible. Preserve lease ownership, terminal authority, source binding, and quarantine during future changes. - Access and audit rows commit together, but activity notifications remain best-effort. This is not a new durable event outbox. - The PR operation does not deploy a live server, replace its runner, or change provider permissions. Remaining live qualification is documented in the [temporary handoff](https://github.com/paperclipai/paperclip/blob/afe19299d06253cb628eb398e91d1200ea9f412a/doc/plans/chat-adapters/2026-09-08-open-qualification-followups.md). ## Model Used OpenAI Codex assisted with implementation, tool execution, testing, and review. The work records `gpt-6-astra` assistance. The environment does not report a context-window size. No private reasoning traces are included. ## 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
018ca5daaf |
fix: verify ACP Stop and preserve safe continuation (#13119)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Task controls coordinate provider execution and queued user messages. > - Stop could finish before an embedded ACP provider stopped its tools. > - A later request could be held for reconciliation without a clear task response. > - A restored provider could also retain the stopped run's API credential. > - This pull request verifies provider termination and preserves safe session continuation. > - Operators can continue known-safe work and see why uncertain work cannot start. ## Linked Issues or Issue Description **What happened?** Stop could leave an embedded ACP provider running. A queued follow-up followed by “go” could fail before it reached the provider. Task chat could show a generic missing-response message. Even a restored session could use the previous run's credential and fail its task update. **Expected behavior** Stop waits for confirmed provider termination. A later explicit wake continues the same compatible session only when recorded actions have known outcomes. It carries pending comments and the current run's environment. Uncertain actions retain a visible reconciliation hold. Composer Stop preserves the existing pause rule: conversation can continue while paused, but task work requires Resume. **Steps to reproduce** 1. Start an embedded ACP task. 2. Send a second request while the provider is running. 3. Interrupt the run, then send “go”. Also test composer Stop followed by Resume work. 4. Check that the request is delivered once and that the provider can complete the task through the current run's API credential. 5. Repeat with an unfinished write. Confirm that the write stops and that further execution stays blocked with a visible reason. **Paperclip version or commit** Built from source on master at `3bc60dd8b` plus this branch. **Deployment mode** Local source build with an isolated embedded PostgreSQL instance. Refs #11183. Refs #12552. Those changes address recovery after operator cancellation. This change also covers embedded ACP termination, session proof, pending-comment delivery, and task feedback. ## What Changed - Propagate Stop into embedded ACP and wait for bounded adapter cleanup and provider exit. Retain the actual ChildProcess object for forced termination on all platforms; never signal a recycled numeric PID. - Preserve interrupted checkpoints only for acknowledged, local, persistent sessions with settled reads or no tools. Keep writes, incomplete actions, and forced termination blocked. - Restore the same compatible provider session with the current run's environment. Reject fresh-session fallback for an interrupted checkpoint. - Adopt pending comments on the next explicit wake. Stop alone does not dispatch them. - Share the execution-blocker rule across dispatch, Resume, and task detail. Show Stopped or Couldn't start with the recorded reason. Resolve the stopped agent for the run link, including reviewer runs. - Keep execution reconciliation holds intact when generic recovery sees queued comments or healthy child tasks. - Add process, service, component, and browser regression coverage. Fix disposable database cleanup and React test settling exposed by the full suite. ## Verification - Passed `pnpm -r typecheck`, `pnpm build`, and `pnpm check:token-gates`. - Passed all three `acp-stop-continuation.spec.ts` browser journeys. They use an actual ACP child process and require task completion through the agent API. - Passed 165 adapter execution, operator-stop, and child-process control tests, 17 queued-comment route tests, and 65 tests in the two adjusted UI suites. Earlier focused recovery, heartbeat, and task-control tests also passed. - Manually used the browser to queue a request, Stop, send “go” while paused, and Resume. The same session answered once and moved the task to Done with the current run's credential. - Manually interrupted an unfinished write. Its file size stayed fixed for five seconds. “Go” showed the reconciliation reason and did not start another provider prompt. - Separate live Claude ACP smoke checks confirmed that Stop ended a disposable local write and that a no-tool interruption could resume the exact provider session. The browser fixture does not call Drive or another external app. - Passed all 5,615 UI tests and 3,090 other workspace tests. The CLI and general server groups pass with targeted retries: two transient server failures passed together on retry, and two embedded-database startup failures passed after removing abandoned shared-memory segments from this task's completed browser fixtures. All 144 serialized server suites completed, with 2,189 tests passing after two transient HTTP socket failures passed on retry. - Passed all 135 heartbeat process/recovery tests, including a deterministic regression that failed before the recovery-sweep fix. - Passed 18 dispatch integration tests, including stopped-reviewer links, company boundaries, and malformed run IDs. - Greptile is 5/5 on `7dd170d83`, with zero unresolved review threads. The security scan and all required CI gates pass for the same commit. ## Risks - Safe continuation depends on complete tool reporting and a restorable local provider session. Unknown outcomes remain blocked and require reconciliation. - Provider cleanup can take time. A timeout does not grant replay permission. - The change adds optional adapter context fields and an optional issue projection. It does not change the database schema or require a migration. - Test cleanup truncates company data only in a disposable test database. ## Model Used OpenAI GPT-6, running as Codex with repository tools, code execution, and browser interaction. The runtime does not expose a more specific model deployment ID or context-window size. ## 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
3b550c80fa |
fix(codex): correct startup trust, history reads, and resume usage (#13110)
## Thinking Path
> - Paperclip runs Codex locally and in remote sandboxes.
> - The runner must preserve startup configuration and session identity.
> - Missing project trust can disable repository configuration.
> - Full-history requests use deprecated provider fields.
> - Resume usage describes old work and must not become new run usage.
> - This change corrects startup trust, state reads, and usage
classification.
## Linked Issues or Issue Description
**What happened?**
Normal Codex runs could show repository-trust and history-deprecation
warnings.
Resume could report the preceding turn's token snapshot as a late-turn
warning.
The historical last-usage value could also be attributed to the new run.
**Expected behavior**
Trust the server-selected startup root in isolated configuration. Read
lightweight
provider state and paginated evidence. Use historical cumulative usage
as a
baseline without a new charge or user-facing warning.
**Steps to reproduce**
1. Start a native Codex task in a selected repository.
2. Finish the turn and resume the provider thread.
3. Inspect provider notices, history requests, and per-run usage.
4. Repeat startup and cold resume inside a Daytona sandbox.
**Paperclip version or commit**
Codex CLI 0.153.4 is the pinned runtime and reproduced baseline.
Replayed onto master at
|
||
|
|
ca96e1eb0a |
fix(runner): keep streaming after task completion tools (#13108)
Keep receiving provider events after paperclip_finish, drain pending event persistence, and select the final assistant answer after the provider turn ends. Preserve cancellation, failure, and governed-wait behavior. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
6abeb67334 |
feat: add opt-in chat provider and data foundation (#13100)
Add dormant provider contracts, qualified patched adapters, tenant-scoped persistence and lifecycle ownership without activating chat routes. Preserve the experimental integration as dependent PR #13038. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
2991a59b17 |
fix(adapters): prevent engine fallback and preserve usable runtime defaults (#13105)
## Thinking Path > - Paperclip manages agents that must write work and report task outcomes through its API. > - Local adapters select an execution engine and its permission settings. > - A higher ACP Node requirement can make an unchanged installation lose access to its default engine. > - The adapter then silently selects CLI, which can change permissions and block API access. > - This pull request keeps the engine choice fixed and reports missing prerequisites before work starts. > - It also gives explicit Codex CLI runs usable defaults and keeps managed services on a supported Node runtime. ## Linked Issues or Issue Description Refs #12215. Related changes: #11792 raised the Node requirement; #13094 addressed separate runner networking behavior. This change fixes the engine-selection and managed-launcher paths. **What happened?** An unchanged agent could switch from ACP to CLI after an upgrade. Codex CLI then used read-only permissions with networking disabled. The run could finish without updating its task. Repeated recovery attempts used the same unavailable setup. Managed updates also skipped the Node check and did not refresh old launchers. **Expected behavior** An unavailable engine must fail with a clear setup error. It must not silently select another engine. Explicit CLI runs must be able to write workspace files and call the API unless the operator configures stricter settings. Managed updates must validate Node and keep child tools on that runtime. **Steps to reproduce** 1. Run an ACP-default agent under Node 22 after the ACP minimum rises to 24.11. 2. Leave the engine unset and disable the approval/sandbox bypass. 3. Observe the old adapter select CLI and fail to write task disposition through the API. 4. Start a managed service with an old launcher and a supervisor PATH that selects a different Node for child tools. ## What Changed - Remove automatic engine fallback for Codex, Claude, Gemini, and Kimi. Check prerequisites for default and explicit ACP selections. - Return a configuration error with proof that provider work did not start. Stop automatic continuation retries for this error. - Enable Codex ACP workspace networking at the actual turn boundary. Upstream mode presets otherwise force it off even when config.toml enables it. Preserve explicit network denial and read-only mode. - Set workspace-write and network access defaults for explicit Codex CLI runs. Preserve explicit sandbox modes, profiles, and network restrictions. - Pin the validated Node directory in managed launcher PATH. Refresh legacy launchers during installs and npm/Git updates. - Reject updates on unsupported Node. Keep update checks, dry runs, and rollback available. - Synchronize the qualified Codex ACP executable identity across server, TypeScript runner, Rust runner, and provider-pack launch paths. - Add regression tests and update engine and installation documentation. ## Verification - [Full CI passed on the final head](https://github.com/paperclipai/paperclip/actions/runs/34387099695): typecheck, build/native runner verification, all general and serialized test shards, all browser shards, release registry, canary dry run, and policy checks. - Greptile: 5/5 on `2c1d6e2815830a5cd39e36c8a082cc0c4441b6c0`, with no unresolved review findings. Security gates are green. - Full workspace typecheck and build also passed locally. The final deployed Linux build passed. - Full Codex, Claude, Gemini, and Kimi source test suites: 804 passed, 2 skipped. Installer, updater, and launcher tests: 47 passed. Installed ACP turn-boundary tests: 3 passed. ACP packaging tests: 14 passed. Focused recovery classification tests also passed. - Real Linux Codex CLI runs, both fresh and resumed, wrote a workspace file and reached the control-plane health API with the new defaults. - Explicit read-only and network-disabled control probes retained those restrictions. - A real ACP run on the final deployed Linux build wrote a file and reached the control-plane API with HTTP 200, without engine fallback. The same probe failed DNS before the turn-policy patch. - Executable-identity and installed-policy contracts: 12 passed. Affected native server tests: 197 passed. Runner factory tests: 21 passed. Rust qualification and native provider integration tests: 11 passed. - Deployed the production changes to a Linux service on Node 24.20 after a verified database backup. Health, bootstrap readiness, static UI, executable/cwd identity, and guarded restart checks passed. The restart lost no runs. - Corrected stale Kimi skill-default and Gemini remote-archive fixtures; both suites pass. ## Risks - Default or legacy auto engine settings now fail when ACP is unavailable. Operators who intend to use CLI must select it explicitly. - Codex CLI now permits workspace writes and networking by default, and ACP workspace-write turns permit networking by default. Explicit operator sandbox settings remain authoritative. - Old managed launchers keep their pinned Node until they are reinstalled under a supported runtime. An old updater cannot repair itself; the documentation gives the current installer command. - Custom service wrappers and global/source installations must configure their runtime PATH. No database migration is required. ## Model Used OpenAI Codex, based on GPT-6, with reasoning, repository inspection, shell execution, and test tools. The exact serving model identifier and context-window size are not exposed in this session. ## 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
8cfd30fb07 |
feat(ui): add composer Stop and simplify task controls (#13104)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The task composer is where operators direct running agents. > - Operators need to stop work without leaving the conversation. > - Existing pause controls already hold task trees and interrupt both runner types. > - This pull request connects the composer to those controls and removes repeated feedback. > - Operators can pause work quickly and still queue messages while agents run. ## Linked Issues or Issue Description **What existing behavior does this improve?** Task pause, resume, and cancellation in the task page and composer. **Current behavior** The empty composer cannot stop a running task. Task controls require extra confirmation and reason text. Pause can show several notifications for the task already on screen. **Proposed behavior** Show Stop while this task runs and the composer is empty. Text or attachments switch it to Send. Stop and the menu use the same manual pause hold. Parent pauses include descendants. Keep task cancellation in the menu with a compact confirmation. Show one quiet pause row and gray cancelled-run details. **Reason and benefit** Operators can interrupt execution with one click. Drafts and queued messages keep their existing behavior. The UI waits for actual termination, including native cancellation acknowledgment. **Breaking changes** No endpoint, schema, or task-status change. Pause no longer asks for confirmation or a reason. Resume now honors the existing wake-agents option. Task notifications are suppressed for the task and subtree currently in view. Related UI work: #8228 changes navigation and composer shortcuts. This PR covers execution controls. No duplicate Stop-button PR was found. The change improves existing controls and does not duplicate a roadmap milestone. ## What Changed - Add Stop, pending feedback, duplicate-click protection, and inline errors to the composer. - Share the pause mutation across the composer, active-run controls, and menu. - Poll affected runs after a pause request. Require native cancellation acknowledgment. - Remove pause confirmation and shared reason fields. Reduce cancel confirmation to its task count and actions. - Honor wake-agents for executable tasks only. Preserve the pause when recovery review is needed; show partial wake failures inline. - Preserve explicit legacy reconciliation decisions while their continuation waits for dispatch. - Suppress notifications for visible task trees. Use quiet pause and cancellation feedback. - Add interactive stories using production controls and native/legacy end-to-end tests. ## Verification - User reviewed the running feature and revised Storybooks in the browser. - Rebased focused checks passed: 295 original targeted tests, 161 updated route/page/notification/status tests, and 26 recovery integration tests. - Both isolated runner journeys pass on the final revision (1.7 minutes). Coverage includes queueing, parent and child interruption, persisted holds, no automatic continuation, reconciled resume, cancellation, terminal exclusions, and no Stop toast. - Native coverage uses real runnerd with a deterministic provider fixture. Legacy coverage checks actual process termination. Live hosted-provider execution was not tested. - Repository typecheck and build, Storybook build, and token gates passed after rebase. The final server typecheck/build also passed. - The broad local run completed its general-server stage with 7,219 passing tests, 48 skipped, and two failures from cached pre-fix source and a stale native provider fixture. Both failed tests pass in fresh final-head reruns after rebuilding the fixture; the script did not continue to its later local stages. CI runs all test groups on the final revision. - Final revision: all 31 applicable CI checks passed; Storybook visual regression was skipped by its workflow conditions. Greptile: 5/5, zero unresolved comments. - Review `Tasks / Execution Controls` in Storybook. Type and clear a draft, stop a run, expand cancellation details, and test the menu on desktop and mobile. ## Risks - Stop pauses descendants for a parent task. This is the existing pause contract. - A held task can remain active if interruption fails. The UI shows an error instead of claiming termination. - Resume can start multiple assignees when wake-agents is selected. Backlog, blocked, and terminal tasks stay excluded. Existing execution reconciliation remains mandatory where required; Resume never invents action-outcome evidence. - Notification suppression uses the visible task and cached subtree. Notifications for unrelated work remain enabled. ## Model Used OpenAI GPT-6 through Codex. The exact runtime snapshot and context-window limit are not exposed in this session. Used reasoning, tool calls, code execution, and browser inspection. ## 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
bf753b997a |
fix(connections): keep task context through Cloud enrollment and OAuth (#13098)
## Thinking Path
> - Paperclip lets people manage agent work from tasks.
> - Agents can request app access in a task card.
> - Some apps first require Paperclip Cloud enrollment.
> - Enrollment could leave the task, and OAuth could lose the task
interaction ID.
> - This PR keeps enrollment in a separate window and retains the
interaction ID through OAuth.
> - The task can then recognize the connection and continue
automatically.
## Linked Issues or Issue Description
**What happened?**
A first Gmail connection could leave the task dialog during Cloud
enrollment. Setup resumed on the Apps page. Gmail connected, but the
task card could remain pending because OAuth did not retain its
interaction ID.
**Expected behavior**
Keep the task open and preserve its access choices. Resolve the card
after the server verifies connection access. Continue the agent
automatically.
**Steps to reproduce**
1. Start a fresh source test-drive instance without Cloud enrollment.
2. Ask an agent to read Gmail.
3. Open Connect on the task card.
4. Complete Cloud enrollment and Gmail authorization.
5. Check whether the task card updates without selecting the connection
again.
**Paperclip version or commit**
Reproduced on
|
||
|
|
82f662656a |
fix(runner): restore legacy Git access and independent networking (#13094)
## Thinking Path
> - Paperclip runs agents for people with different GitHub accounts.
> - Managed operations must use the intended person's eligible
connection.
> - A failed duplicate connection must not hide a healthy grant for the
same account.
> - Legacy hosts also need their existing Git configuration when managed
access is not configured.
> - Runner networking and local Git operations must not depend on GitHub
broker availability.
> - This pull request separates those policies and improves failure
diagnostics.
## Linked Issues or Issue Description
**What happened?** New runs always cleared host Git credentials and
installed managed launchers. Network permission depended on GitHub
environment variables. A launcher failure could stop even local `git
status`. A newer unhealthy duplicate could take precedence over a
healthy connection, and generic health errors were shown as reconnect
requirements.
**Expected behavior:** Use a healthy eligible managed connection for the
intended account. Preserve host authentication only for unconfigured
standard-trust local or SSH execution. Permit local Git during broker
failures and keep network permission independent of GitHub credentials.
**Steps to reproduce:** Configure healthy and unhealthy grants for one
GitHub account, dispatch an agent, and execute Git commands. Separately
run an unconfigured legacy host with existing GitHub CLI authentication.
Stop the broker and run local `git status`.
**Paperclip version or commit:** Master at
|
||
|
|
2ceb630b6c |
fix(workspaces): preserve dependency provisioning failures (#13093)
## Thinking Path > - Paperclip runs agent work in isolated worktrees. > - Each worktree needs dependencies that match its source and patches. > - A failed install currently loses its exit status after an `if` statement. > - The provisioner can then record a successful dependency fingerprint. > - This pull request preserves failures and bounds lockfile recovery. > - Agents receive a usable workspace or an accurate provisioning failure. ## Linked Issues or Issue Description **What happened?** A nonzero pnpm install could return success and save a fingerprint. Patch changes alone also did not invalidate the fingerprint. **Expected behavior:** Fail provisioning on an unsuccessful install. Retry known frozen-lockfile mismatches once and record success only after installation succeeds. **Steps to reproduce:** Run the provisioner in a worktree with a pnpm install that exits nonzero. The regression suite uses real shell execution and a controlled pnpm fixture. **Paperclip version or commit:** Reproduced on master before this change. **Deployment mode:** Self-hosted. **Installation method:** Git checkout. **Agent adapters involved:** Core workspace provisioning. **Database mode:** Not relevant. **Access context:** Execution host. **Node.js version:** 26.4.0 locally; supported minimum remains unchanged. **Operating system:** macOS locally and Linux execution hosts. **Relevant logs or output:** `ERR_PNPM_LOCKFILE_CONFIG_MISMATCH`, `ERR_PNPM_OUTDATED_LOCKFILE`, and ordinary installation failures. **Additional context:** Related lockfile maintenance: #13061. No lockfile or workflow changes are included. ## What Changed - Capture the failed install status inside the `else` branch. - Use the existing single retry for both frozen-lockfile mismatch errors. - Include patch contents in the dependency fingerprint. - Add executable regression coverage and document the behavior. ## Verification - All CI checks passed, including build, typecheck, tests, browser suites, canary dry run, and security scans. Greptile: 5/5 with no remaining findings. - `node --test scripts/__tests__/provision-worktree-self-heal.test.mjs`: 19 passed; one existing test requires Linux flock and was skipped on macOS. - `bash -n scripts/provision-worktree.sh` and `git diff --check` passed. - Full workspace typecheck and build passed in the companion runner-fix worktree at the same base revision. This change only touches shell provisioning, its tests, and documentation. - CI and review are pending. ## Risks The existing non-frozen recovery can update a worktree-local lockfile. Committed lockfile updates remain bot-owned. Ordinary failures now correctly stop provisioning and may expose previously hidden installation problems. ## Model Used OpenAI GPT-6 through Codex, with code editing, shell execution, tests, and browser inspection. The exact model variant and context-window size are not exposed in this session. ## 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
35fdc0c66b |
fix: make task recovery durable and preserve current requests (#13075)
Make task recovery durable and preserve the latest user request across native and legacy continuations. Keep routine recovery quiet and prevent replay when action outcomes are uncertain. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
e200104727 |
feat: review connection actions from tasks (#13063)
Bring governed connection reviews into task history and composer approvals. Share resolution with Connections, add scoped remembered permissions, and resume agents through durable outcome receipts. Keep cards compact, collapse raw results, isolate untrusted provider output, bound continuation payloads, and reconcile missed live events. Add Storybook coverage, browser journeys, and service regression tests. Verification: all PR CI gates passed, Greptile 5/5, security scans passed, five connection-review browser journeys passed, and real native Codex approval/continuation was verified against the local MCP fixture. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
2043e0c735 |
fix: repair runner configuration, macOS execution, and artifact galleries (#13062)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agent adapters select a provider, a model, and a runtime. > - Runner conversion rejected existing Claude agents. The model list mixed providers. > - The native Claude runner rejected custom models and could not launch on macOS. > - This pull request fixes conversion, model selection, and verified macOS execution. > - It also groups configuration fields consistently across adapters and opens artifact images in the task gallery. > - Operators can change an agent configuration and run the selected model on their Mac. ## Linked Issues or Issue Description **What happened?** Converting an existing Claude agent to Paperclip Runner failed with a Codex-only restriction. ACPX Claude showed unrelated models and required `claude-sonnet-5`. Its native runtime rejected macOS. Configuration mixed common model settings with process controls. Artifact cards labeled “Open gallery” navigated to attachment URLs instead of opening the task gallery. **Expected behavior** Conversion keeps agent identity and compatible settings. ACPX Claude uses the normal Claude catalog and accepts typed model IDs. Codex uses the native runner. The verified Claude runtime can launch on macOS ARM64 and x64. Common configuration sections place the same fields together across adapters. Artifact images open in the shared task gallery with navigation and downloads. **Steps to reproduce** 1. Open the configuration of an existing Claude agent. 2. Convert it to Paperclip Runner. 3. Select ACPX Claude and a different catalog model or a typed model ID. 4. Save the agent and run a disposable task on macOS. 5. Inspect configuration and advanced run-policy controls across adapters. **Paperclip version or commit** The bugs were reproduced on `165ca56a22adb60e5fda56045442d9c8498116a8`. This branch was rebased onto `7ed122911`. **Deployment mode** Built from source. Local test-drive instance on macOS ARM64 with an isolated database. Related work: #11798 addresses unsupported ACP session options in the existing adapter path. #13048 addresses working-folder preservation. This change fixes native runner configuration and launch behavior. ## What Changed - Remove the Codex-only conversion restriction. Preserve agent identity, instructions, directories, credentials, and compatible model settings. Reset incompatible sessions while retaining history. - Show ACPX Claude and native Codex as distinct provider choices. Remove ACPX Codex from advertised configuration. Normalize legacy configurations before fresh runs without rewriting historical run descriptors. - Select model catalogs and cache entries by provider. Support refresh and typed model IDs. Pass exact Claude IDs through session creation, model changes, and recovery. - Add verified macOS ARM64 and x64 Claude SDK snapshots. Bound executable allocation and total snapshot size. Preserve package checks, dependency isolation, process ownership, cancellation, and Linux descriptor loading. - Probe local runtime readiness. Report remote platform checks as incomplete until the remote runner verifies its runtime. - Surface actual model rejection and allow correction and retry. - Repair missing ACPX goal-capability helpers exposed by the post-rebase live test. Persist and restore the optional capability without breaking session startup. - Put Agent identity first and intentionally remove the Capabilities editor, as requested. This is removal of UI editing, not relocation: preserve existing capability metadata and API compatibility without adding another editor. Use the themed select for configurable permission modes, with normal text instead of monospace. - Put model and provider under Adapter. Give environment variables their own section. Fold command and arguments under Configuration. Fold lifecycle, timeout, and interrupt grace under Advanced Run Policy. Hide single-option permission controls. - Open image and video artifact cards in the existing task gallery, including cards in the artifacts panel. Chat attachment images use the same gallery. Preserve standalone media previews and download links. ## Verification - Rebased focused UI/API/database suites: 293 tests passed. - Rebased native runtime and ACPX suites: 242 passed, 7 skipped. - Repository typecheck, build, and token gates passed for the runner changes. Gallery follow-up UI typecheck, build, and token gates also passed. - Follow-up UI suites passed (86 tests), packaging checks passed (14 tests), and the final focused runtime suites passed (126 passed, 7 skipped). - Linux container isolation and lifecycle fixtures passed before rebase (57 passed, 2 skipped). Rust ACPX provider-session tests passed after rebase (8 tests). - Browser tests completed actual Claude and native Codex tasks on macOS ARM64. They covered conversion, catalog refresh, a non-default catalog model, a typed `haiku` ID, save/reload, cancel, follow-up session continuity, invalid-model errors, and recovery. - Final-revision live tests completed a typed Claude task, a follow-up with the same provider session, and a native Codex task on macOS ARM64. - Browser tests confirmed the moved interrupt-grace field saves and survives reload. Cross-adapter tests cover Claude, Codex, Gemini, process, gateway, and schema forms. - Full local run: 7,080 passed, 30 skipped, and two timeouts. Both timeout suites passed on isolated rerun (84 tests); the failures were the plugin login-worker exit diagnostic and the runner real-server vertical slice. - Final follow-up checks: 50 registry tests and 45 snapshot/installation tests passed (6 platform-specific skips). Oversized executable rejection is covered before allocation or reading; unsupported-platform tests invoke the real installation probe. - Runner head `ddb5101c483a297f74875ab96b3c66035b002d50`: all CI gates green, including full runner verification, repository build, typecheck, general/serialized server suites, browser tests, and canary dry run. [CI run](https://github.com/paperclipai/paperclip/actions/runs/34286178670). - Greptile: 5/5 on that runner head. All four review threads resolved. Superagent, Socket, and Snyk checks green. - After snapshot hardening, another real Claude task completed on this Mac using the rebuilt runtime. - Gallery follow-up: 148 focused tests passed, covering artifact selection, shared attachment collections, deduplication, image/video cards, standalone previews, downloads, and closing. Live browser verification completed on the settings follow-up: artifact selection, 6-image pagination with wrapping, download action, and closing all stayed on the same task URL. All checks passed on gallery head `96136da58ff195bf6ca00b281eb3022ad12d7bd8`: [CI run](https://github.com/paperclipai/paperclip/actions/runs/34287987536). Greptile returned 5/5 on that exact head with no unresolved threads. - Final settings polish: 96 focused tests, UI typecheck/build, and token gates passed. A real browser walkthrough verified readable permission options, identity placement, Capabilities removal, and permission save/reload. Original test-agent permission mode restored. All 31 checks passed on final head `e46540d6bf32bfb0566dca16b2f4a75ba437618c`: [CI run](https://github.com/paperclipai/paperclip/actions/runs/34292797886). Greptile returned 5/5 with no unresolved threads. ## Risks - Capabilities intentionally has no editable UI field after this change. Existing values remain readable and API-compatible; removing the field does not erase stored metadata. - macOS launch now copies verified package files into private snapshots. The implementation must retain isolation and clean up snapshots on exit. - Runtime provider or model changes reset the current session. Historical runs remain available. - The macOS x64 SDK executable digest was verified, but a live Intel Mac run was not available. Linux verification used container fixtures, not a real Claude task. - Remote environment tests report a warning when only the platform has been checked. They do not claim package readiness from the server host. ## Model Used OpenAI Codex, based on GPT-6. The exact served model identifier and context-window limit are not exposed in this session. Used reasoning, repository inspection, code execution, Rust and TypeScript tests, and browser automation. ## 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 (focused suites and both timeout suites on rerun; full-run counts above) - [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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
7ed122911b |
Add end-to-end session goals to Paperclip Runner
Add capability-aware slash-goal controls, durable provider goal state, PRP v2 negotiation, autonomous goal execution, and safe local session recovery. Integrate with current master, preserve provider session identity, and verify the browser goal/chat/replacement/clear workflow and unsupported-agent rejection. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
6019e2bd6e |
feat(adapter-utils): carry binary bodies and attachment routes over the HTTP/2 sandbox bridge (#12923)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Paperclip runs agents in local and remote sandboxes through adapter utilities > - The HTTP/2 sandbox bridge decoded every body as UTF-8 text and rejected non-JSON content > - This stopped agents from uploading or downloading issue attachments through that bridge > - This pull request carries raw bytes, permits the two attachment routes, and enforces a shared body limit > - The benefit is correct attachment transfer with a process-wide memory guard ## Linked Issues or Issue Description **What existing behavior does this improve?** The HTTP/2 sandbox bridge forwards request bodies between an agent sandbox and the Paperclip host. It now supports binary bodies and the issue attachment routes. **Current behavior** The bridge decodes each body as UTF-8 text. It returns HTTP 415 for content types outside the JSON route list. An agent cannot upload or download an issue attachment through this transport. **Proposed behavior** The bridge carries raw bytes through the forward path. It permits the attachment upload and content routes. The queue transport and file gateway keep their existing route behavior. A shared 10 MiB body limit and process-wide byte reservation protect memory use. **Reason and benefit** Attachment clients need byte-preserving transfer. The shared limit keeps the gateway and host aligned. The reservation prevents concurrent streams from exceeding the accepted process memory ceiling. **Breaking changes** The HTTP/2 bridge accepts two attachment routes and permits binary content. The queue transport and file gateway keep their previous route lists and HTTP 415 behavior. No schema or external endpoint changes. ## What Changed - Carry request and response bodies as raw bytes through the HTTP/2 bridge. - Permit attachment upload and attachment content routes on the HTTP/2 bridge only. - Raise the resolved per-body limit to 10 MiB and share it between the gateway and host. - Reserve body bytes before allocation and release each stream reservation on every terminal path. - Document the body limit, process ceiling, and reservation behavior. ## Verification - Run `pnpm exec vitest run packages/adapter-utils/src/http2-bridge-server.test.ts packages/adapter-utils/src/execution-target-sandbox.test.ts packages/adapter-utils/src/sandbox-callback-bridge.test.ts`; 226 tests pass. - Run `pnpm --filter @paperclipai/adapter-utils typecheck`; it passes. - Run the direct server TypeScript check with `tsc --noEmit` in `server/`; it passes with zero errors. - Verify multipart upload and binary download round trips over HTTP/2 without corruption. - Verify the queue transport and file gateway return HTTP 415 for the same routes. - Verify the host rejects bodies over the resolved limit. - Verify a denied reservation returns HTTP 503 and allocates no copy. - Verify stream cleanup releases reservations after completion, error, abort, timeout, and close. ## Risks The bridge now accepts larger bodies and binary content. The process-wide reservation limits total live body bytes to 1 GiB. Route behavior changes only for the HTTP/2 bridge. The security review found no blocking issue for this commit range. ## Model Used OpenAI Codex, GPT-5. The runtime used tool calls and code execution. The runtime did not expose the context window size. No model-generated code changes were made for this pull request. ## 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
e095b84dab |
feat(connections): connect services from native task feeds (#13058)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Agents use connections to reach external services. > - A fresh native task can have no service tools installed. > - The agent needs a way to discover services and ask the responsible person for access. > - This pull request brings the existing connection-intent flow into native task execution. > - The person can connect from the task, and the agent can continue with updated tools. ## Linked Issues or Issue Description **Subsystem affected** Native runner tool authority, connection intents, task interactions, and shared connection setup. **Problem or motivation** A task that needs an unconnected service cannot finish its work. Leaving the task to configure access also loses context. A resolved request must survive a restart and resume the correct agent once. **Proposed solution** Expose connection discovery and access requests as server-owned native tools. Render a durable task card and use the shared setup dialog. Persist outcome delivery and start a fresh provider session after access is ready. **Alternatives considered** Sending the person to the Connections page adds navigation and does not solve continuation. Polling for authorization consumes runs and can create duplicate requests. **Roadmap alignment** This extends the existing connection-intent runtime and setup experience. It reuses the shared access model and the native runner. Related: #12345, #12347. The service-slug fix in #12906 is related but separate. Companion evaluation PR: https://github.com/paperclipai/paperclip-evals/pull/21. ## What Changed - Expose `connections_search` and `connection_request` with server-bound company, task, agent, and responsible user. Preserve the legacy entry points. - Discover catalog services and authorized custom connections. Check installation, identity, health, and executable permissions before reporting ready. - Keep pending cards through ordinary messages. Reuse requests and retire stale ownership. Put Connect at the right of Not now. - Reuse the shared setup flow in a task dialog. Keep access additive and default to the requesting agent. Recover from cancelled or blocked OAuth windows with a new-tab fallback. - Persist outcome delivery with an idempotent wake key. Resume in a fresh session and recheck ownership before dispatch. - Add native browser fixtures, offline Storybook states, server contracts, and evaluation fixtures. Update guidance and documentation. ## Verification - `pnpm build`: passed after replaying the change on current master. - `pnpm -r typecheck`: passed. - `pnpm check:token-gates`: passed. - `pnpm --filter @paperclipai/ui build-storybook`: passed. - New continuation-policy regression cases: 16 passed. - Docker-backed PostgreSQL regressions passed for requester-only OAuth access, assignment-only expiry, terminal expiry, and credential-free setup metadata. - Shared setup and task-card UI tests: 121 passed, including configured MCP reconnect URL recovery and preserving user edits across refetch. - Storybook browser checks: all 119 passed on the latest reconnect fix. - `pnpm test:run`: 4,734 tests passed in the first server group, but embedded PostgreSQL startup failures and resulting cleanup errors prevented a complete local pass. All Linux CI lanes passed on the latest reviewed commit. One external-object route test returned an unexplained 500 on the first run; it passed twice locally and the failed shard passed on retry without code changes. - Earlier feature-checkout evidence: three deterministic native browser journeys passed, including restart delivery and an actual fixture tool result. Legacy scripted coverage also passed. All 59 added stories were inspected in light and dark themes. - Live Notion testing recorded successful provider reads. The manual test used a local-trusted instance. It does not prove authenticated/cloud deployment or every provider journey. - Native browser rerun reached the embedded PostgreSQL startup limit before bootstrap, so the latest checkout’s full native browser journey remains unverified. Both OAuth page/task regression cases passed against isolated Docker-backed PostgreSQL 17. They verify no premature task access, requester-only completion, additive retries, and reconnect preservation. - Applied both new migrations twice to isolated PostgreSQL 17. Foreign keys remained intact, duplicate active delivery keys were rejected, and failed delivery records did not block retries. Reviewer path: start a fresh test drive, enable the native runner, use an agent that can perform work directly, and ask it to summarize a Notion page. Connect from the card, then verify the resumed provider call and source-linked answer. The default test-drive CEO is instructed to delegate, so it can introduce an unrelated hiring step. ## Risks - Two additive migrations create durable deliveries and a partial unique wake index. They are idempotent. The wake index can require a maintenance window on large tables because migrations run in a transaction. - OAuth and continuation cross asynchronous boundaries. Tests cover ownership changes, retries, additive access, and restart delivery; live provider behavior still varies. - The latest requester-scope fix has not yet been exercised through live OAuth. GitHub, API-key, authenticated-user, and all recovery journeys are not claimed as verified. ## Model Used OpenAI GPT-6-based Codex assisted with implementation, tests, and review using tools and code execution. The runtime does not expose the exact model version, context window, or reasoning setting. Live evaluation used `gpt-5.6-luna`; manual native testing used `gpt-5.6-sol`. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used and disclosed unavailable runtime details - [x] I have checked ROADMAP.md and confirmed this extends existing connection work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have described the issue in-PR following the feature issue template - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal ticket id - [ ] I have run all required 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 risks - [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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
ebaeba40ee |
feat: simplify agent onboarding and configuration (#13011)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Operators create agents and configure their runtimes in the board UI. > - The old creation flow presents several choices and a large form before an agent can start. > - The existing onboarding controls already provide clear provider connection steps. > - This pull request uses those controls in a new-agent wizard and organizes the full configuration pages. > - Operators can connect, test, save, and assign a first task while keeping the existing configuration tools. ## Linked Issues or Issue Description Related: #10974. That earlier open PR also reorganizes agent configuration. This PR follows the reviewed Storybook designs for agent creation and the current configuration tabs. **What existing behavior does this improve?** Agent creation, provider connection, runtime tests, and full agent configuration. **Current behavior** The creation dialog leads to a large manual configuration form. Provider login controls differ from onboarding. Environment variables and secret access appear in separate places. **Proposed behavior** Choose a name and adapter. Connect Claude or Codex through the existing onboarding controls. Configure and test the runtime, save the agent, and open a task dialog with that agent assigned. Use the same design on the existing configuration tabs. **Reason and benefit** The first setup asks for fewer decisions. The full editor keeps instructions, skills, runtime controls, secret access, permissions, keys, and revisions available in clear sections. **Breaking changes** The board creation and configuration layouts change. The test-environment API adds an optional, allowlisted `testCredentials` field for one-shot probes. Database contracts stay the same. Native ACPX tests now reject unsupported local platforms before a CLI login can mask the runtime restriction. ## What Changed - Added a new-agent wizard with numbered steps, adapter branding, provider connections, editable model choices, runtime tests, and confirmation. - Added Codex app-server, Claude ACPX, and OpenCode runner choices. - Stored API credentials through existing secret APIs and persisted references in agent configuration. New setup keys are isolated from credentials used by existing agents. - Preserved external-agent invitations beside the wizard, including optional messages, one-time prompts, and clipboard fallback. - Added OpenRouter provider and secret bindings for Pi and OpenCode. - Added adapter-specific prerequisite fields for Cursor, Gemini, Kimi, and Hermes. Cursor Cloud keys are saved as new organization secrets. - Fixed Cursor Cloud repository field mapping, omitted empty remote environment values, and added useful model and repository error messages. - Preserved complete MCP assignments when multiple valid profiles contain more than 250 tools in total. Generated profiles retain exact tool selectors. - Added service branding and deployment-aware adapter choices. Cloud setup offers Claude, Codex, and OpenCode; local native runners require the experimental setting. - Made the agent list responsive at intermediate widths. - Applied the reviewed design to the real agent configuration pages. Kept the instruction editor, skills, and existing mutations. - Combined secret access and environment variables under one Save and Discard action. - Added interactive Storybook screens for setup, configuration, confirmation, authentication, and test results. - Fixed Pi provider-error parsing and thinking-effort persistence. Native ACPX validates Linux x64 on the actual local, SSH, or sandbox target. - Redacted the complete transient probe-credential field from HTTP error logs, including rejected provider names. ## Verification - Current head `df0292fe6` has a fresh Greptile 5/5 review with no unresolved findings. All 31 executed CI checks passed, including the aggregate verification gate and all browser E2E shards. Storybook visual regression is skipped by its workflow; the local Storybook build passed. - Browser tests completed real assigned tasks with direct Codex, Claude, OpenCode, Pi, and native Codex. - Verified external-agent invitation generation and automatic prompt copying in the live browser. - Pi and OpenCode used an existing OpenRouter secret. Browser checks covered save and reload, instruction edits, skill selection, environment-variable Save and Discard, and assigned task creation. - Invalid Claude API credentials remained on the connection step with an error. A live Pi/OpenRouter invalid-key probe returned a provider failure and left the user-secret inventory unchanged (zero entries before and after). - Full workspace typecheck and build passed after rebasing onto current master. After review fixes, server and UI typechecks, token gates, and the full build passed again. Storybook built successfully. - All 5,542 local UI tests passed. The Cursor Cloud and Pi adapter regressions passed all 24 tests. Review regressions passed 69 server tests and all 18 agent-list tests. - The local full test command ran 6,971 general server tests successfully. Editing review fixes during that long run caused nine tests to use stale modules; fresh isolated runs passed. An unrelated embedded-Postgres fixture hit the host shared-memory limit; its 15 affected tests passed when the fixture groups ran separately. - Local workspace groups passed after rerunning 18 CLI tests sequentially to avoid host database limits and parallel-load timeouts. The local full command stopped at the general server phase, so serialized server verification comes from the five passing CI shards. - Browser testing at 390px confirmed that the agent action menu opens and the page has no horizontal overflow. CI browser E2E shards passed. - Review the `Onboarding / New agent` and `Agents / Configuration refresh` Storybook groups. In the real app, create an agent, run its connection test, save it, assign a task, and reload its configuration. ## Risks - This changes the main agent setup and configuration UI. Regression tests cover routing, persistence, secret bindings, and form actions. - Native Claude ACPX requires Linux x64. Direct Claude works on macOS. Remote checks execute a bounded platform probe and reject unsupported or unverified targets. - A native OpenCode task reached the provider context limit because of its tool payload. Its provider connection test passed. Direct OpenCode completed a task. This existing native execution limit is not fixed here. - Claude and Codex connection keys use the existing user-secret store. Other runtime setup keys use distinct organization secrets. Existing credentials are never rotated. Probes do not store entered keys. Failed agent creation removes newly staged credentials. - Cursor Cloud has not completed a live task. Its authenticated account still needs GitHub repository access. The live run passed MCP provisioning, remote environment validation, and explicit Auto model selection before the repository prerequisite blocked execution. - Generated runtime MCP profiles can exceed the public profile-edit request limit. They still contain exact catalog selectors and preserve permission boundaries. - No database migration, dependency, lockfile, or workflow changes are included. ## Model Used OpenAI Codex, based on GPT-6, with reasoning, repository tools, shell execution, and browser automation. The runtime did not expose the exact model ID or context window size. ## 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
3ad494aacd |
fix(adapter-utils): preserve legacy sandbox PATH with managed GitHub (#13051)
## Thinking Path > - Paperclip lets people manage AI agents and their work. > - Remote agents need both their installed tools and managed GitHub credentials. > - The GitHub launcher replaces a missing remote PATH with a small system path. > - Legacy images install agent CLIs outside that path, so those agents cannot start. > - This pull request preserves the remote toolchain and puts managed GitHub commands first. > - Command checks now use the same environment as execution. ## Linked Issues or Issue Description Refs #13005. Related: #10239 fixes a separate Cursor environment path issue. Searched open issues and PRs for sandbox PATH and GitHub launcher changes. No duplicate of this launcher fix was found. **What happened?** A remote Claude or Codex run passes command discovery, then fails with `command not found` and exit code 127. Managed GitHub launchers use only their own directory and `/usr/local/bin:/usr/bin:/bin`. This drops NVM and other toolchain directories from the sandbox path. **Expected behavior** Agent CLIs remain available on legacy and current sandbox images. Managed `git` and `gh` still resolve first and use the responsible person's credentials. **Steps to reproduce** 1. Use a sandbox whose agent CLI is installed in an NVM or other non-system bin directory. 2. Start an agent run with managed GitHub launchers and no explicit PATH override. 3. Observe that command discovery succeeds but the agent command exits with code 127. **Paperclip version or commit** Observed on `b97101893f0926f57ed0ce9ef1f8d3e4780c62c2`. The same launcher behavior remains on the base commit `be6bb768b`. **Deployment mode** Hosted server with remote sandbox execution. The shared launcher also supports SSH targets. ## What Changed - Read the remote target's effective PATH when no remote override is set. Do not copy an inherited controller PATH. - Prepend the managed launcher directory and retain the combined path in shell startup files. - Stop startup if path discovery fails. Frame the response so login banners cannot contaminate PATH. - Pass the sanitized launch environment to sandbox command checks, installation, and the second check. - Add real shell tests for legacy and current CLI layouts, quoted paths, managed GitHub command execution, explicit overrides, SSH, and failure cases. - Document the remote path contract. ## Verification - Four focused adapter utility suites passed: 153 tests. - The regression suite passed: 13 tests, including the Linux stdin handling fix. - `pnpm --filter @paperclipai/adapter-utils typecheck` passed. - Full workspace `pnpm -r typecheck` and `pnpm build` passed. - The regression suite fails on the unchanged base revision (12 failures, 1 pass) and passes with this change (13 passes). The baseline ran in an isolated scratch copy. - Full local test coverage was attempted using the official CI shards. The run was stopped after macOS Postgres shared-memory exhaustion and CLI timeouts under load. The affected server database suite passed in isolation (31 tests), as did the five affected DB/CLI suites (89 tests). - [Full Linux CI](https://github.com/paperclipai/paperclip/actions/runs/34258333833) passed on `4e1426f5b`: all general and serialized test shards, all browser shards, typecheck and release registry checks, native runner verification, application build, and release canary dry run. - Greptile scored the latest commit 5/5 with no unresolved findings. - Shell tests use isolated local fixtures and make no provider or model requests. No live sandbox qualification is claimed. ## Risks - Remote startup adds one bounded path query when no explicit override exists. A failed query stops startup. - Explicit remote path overrides still control which tools are available. Invalid overrides now fail the command check earlier. - Credential selection and GitHub broker policy are unchanged. Tests verify managed wrappers stay first and can invoke underlying commands. - No database migration or sandbox image replacement is required. ## Model Used OpenAI GPT-6 through Codex, with reasoning, repository editing, and terminal tools. The exact serving model ID and context-window size are not exposed in this session. ## 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
db85bf4b7a |
fix(ui): simplify GitHub repository access controls (#13047)
## Thinking Path > - Paperclip helps people manage AI agents and their connected apps. > - GitHub permissions show which repositories an account can access. > - The page adds an account dropdown and search above the repository list. > - These controls add clutter to a view meant to show the full access list. > - This change removes both controls and their filtering state. > - People see all repositories directly, with the existing scrolling and access controls. ## Linked Issues or Issue Description Refs #12998. **Current behavior** GitHub permissions show an “All accounts” dropdown and a “Search repositories” input above the repository list. **Proposed behavior** Show the full repository list directly. Keep the scroll limit, repository links, private-repository icons, refresh button, and GitHub configuration links. **Reason and benefit** Remove unnecessary controls from the access summary. Users manage repository permissions on GitHub. ## What Changed - Remove the account dropdown, search input, filtering state, and unused imports. - Rename the GitHub configuration button to “Add More Repos on GitHub”. - Render every returned repository and simplify the empty-list message. - Update the existing multi-account test and permissions documentation. ## Verification - All 55 AppDetail tests passed. - `pnpm check:token-gates` passed. - Full `pnpm build` and `pnpm -r typecheck` passed. All 31 CI checks passed on `cb9b8bb14a880d926393c62821265fbd2d8c5d31`. Storybook visual regression was correctly skipped. - Fresh Greptile review on the same commit: 5/5, with no unresolved findings. ## Risks Users can no longer narrow this list by account or search text. The list still scrolls and shows each repository’s full owner/name. This change does not alter GitHub permissions or credential selection. ## Model Used OpenAI GPT-6 through Codex, with code editing and shell verification tools. The exact model variant and context-window size are not exposed in this session. ## 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
5752d6bd93 |
fix(heartbeat): block runs on a stuck sandbox plugin and re-enable errored bundled plugins at boot (#12957)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agents run inside environments. A sandbox environment gets its
sandbox from a provider plugin (for example the bundled
`paperclip.kubernetes-sandbox-provider`), and every run starts by
acquiring a lease through that plugin.
> - When a plugin activation fails once (on a hosted deployment: one
`RPC call "initialize" timed out after 15000ms`), the loader calls
`markError`. That persists `status = error` on the plugin row and
switches off worker auto-restart. Boot activation (`loadAll`), the
bundled-plugin bootstrap and the lazy worker recovery all consider only
`ready` plugins, so the plugin stays in `error` across restarts until an
operator enables it by hand.
> - Every run that needs the provider then fails before dispatch with
`Sandbox provider "kubernetes" is installed via plugin "...", but that
plugin is currently error.` That message matches neither the retryable
classifier (`... but its worker is not running`) nor any configuration
classifier, so the run is recorded as a plain `setup_failed`, the issue
is released, and the scheduler dispatches the same failing run again on
the next tick. On the hosted deployment one company produced about
11,300 identical failed runs, one every 30 seconds, for a week (#12953
is a customer's report of the same condition).
> - Two gaps cause this: the heartbeat treats a condition that only an
operator can change as a transient setup failure, and the bundled-plugin
bootstrap never gives a plugin in `error` another chance even though the
bundle ships with the release image.
> - This pull request classifies the "installed but not ready" lease
failure as `configuration_incomplete`, so the existing recovery path
moves the issue to `blocked` with one recovery action and an actionable
notice; and it re-enables a bundled plugin found in `error` once per
boot, so the next server restart heals the plugin.
> - The benefit is that a stuck provider plugin surfaces as one blocked
issue per task with clear next steps, instead of an endless stream of
identical failed runs, and a restart repairs the plugin without an
operator having to know the plugin API.
## Linked Issues or Issue Description
- Refs #12953 — hosted report: "that plugin is currently error" on every
run for six days, including runs that were retried by hand. This PR
stops the retry loop (issue goes to `blocked`) and makes a server
restart re-activate the bundled plugin. It does not change how a managed
Kubernetes environment is provisioned for a company, which the same
report also mentions.
- Related PR: #9760 pauses the agent for the permanent `Adapter "..." is
not in the configured adapter registry` setup failure. This PR handles a
different permanent condition (plugin not `ready`) and routes it through
the existing `configuration_incomplete` recovery path (issue-level block
with a recovery action) rather than an agent-level pause, because the
gap is on the plugin, not on the agent. The two do not overlap in code
paths.
- No existing issue covers the bundled-plugin re-enable. Bug
description:
**What happened**
A bundled sandbox provider plugin went to `status = error` after one
failed activation. It stayed in `error` across every later server
restart. Every run for every agent on that provider failed lease
acquisition in under a second with `... but that plugin is currently
error.` (`setup_failed`), and the heartbeat kept dispatching new runs
that failed the same way.
**Expected behavior**
A run that fails because its provider plugin is not `ready` is recorded
as a configuration gap and the issue is moved to `blocked` with a notice
that names the plugin and its status, so no further runs are dispatched
until an operator acts. A bundled plugin left in `error` gets a fresh
activation attempt on the next boot.
**Steps to reproduce**
1. Install a sandbox provider plugin and create a sandbox environment
that uses it; make it an agent's default environment.
2. Set the plugin row's status to `error` (or make its worker fail
`initialize` once so the loader does it).
3. Assign an issue to the agent and let the heartbeat run it.
4. Observe: the run fails with `... but that plugin is currently error.`
as `setup_failed`, the issue is released, and the next tick dispatches
another run that fails the same way. Restart the server: the plugin is
still `error`.
**Paperclip version**
master at
|
||
|
|
023e640a7e |
fix(db): reap idle pool connections, name the pool, and end it on shutdown (#12956)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The server keeps one postgres.js pool (`packages/db/src/client.ts`, `createDb`) for every query it runs. #10795 made the pool tunable from the environment, but the defaults stayed at the driver defaults: an idle connection never closes, the pool reports itself as `postgres.js`, and no code path ever calls `sql.end()`. > - On a hosted Paperclip deployment the server entered a restart loop (a bundled plugin failure that #12953 describes made every run fail, and the pool saturated). Each generation opened its ten connections, died, and left the backends open on the PostgreSQL side until TCP keepalive reaped them hours later. After about 20 generations the backends exceeded `max_connections`, and every later boot died on its first bootstrap query with `sorry, too many clients already`, before `server.listen()`. The loop could not heal itself. #9555 describes the same shape on a launchd-supervised self-hosted install. > - Three properties of the pool combine to make this possible: idle connections are never reaped, the pool is never ended on any exit path, and an operator cannot even find the leaked backends in `pg_stat_activity` because they carry the generic driver name. > - This pull request gives the pool a 60 second idle timeout and the `paperclip` application name by default, exposes `max_lifetime` and `application_name` through the same `DATABASE_*` environment contract that #10795 introduced, and ends the pool on the orderly SIGINT/SIGTERM path and on the fail-loud startup path. > - The benefit is that a restarting or crash-looping server releases its backends instead of accumulating them, and an operator can see and count Paperclip's connections. ## Linked Issues or Issue Description - Refs #9555 — database connection pool leak causes an infinite restart loop under load. This PR closes the "pool never ends, idle connections never close" part of that report. - Refs #12953 — hosted outage report. The pool exhaustion is the second half of that incident; the first half (a stuck sandbox provider plugin) has its own PR. - Related prior PRs: #9597 and #8780 both propose hard-coded `idle_timeout` / `max_lifetime` values in `createDb`. Both predate #10795 (merged), which made these options environment-driven; this PR builds on the merged shape and adds the shutdown `end()` that neither covers. #4006 and #7481 are closed earlier attempts in the same area. ## What Changed - `packages/db/src/client.ts` - New `resolveDatabaseClientOptions()` applies Paperclip defaults on top of the environment: `idleTimeoutSeconds` defaults to 60 (`DEFAULT_DATABASE_IDLE_TIMEOUT_SECONDS`) and `applicationName` to `paperclip` (`DEFAULT_DATABASE_APPLICATION_NAME`). `createDb` uses it for both the environment path and explicit options. - `DATABASE_IDLE_TIMEOUT_SECONDS` now accepts `0` to restore the driver default (keep idle connections open). Negative or non-integer values still throw. - New environment variables: `DATABASE_MAX_LIFETIME_SECONDS` (positive integer, maps to `max_lifetime`) and `DATABASE_APPLICATION_NAME` (non-empty string, maps to `connection.application_name`). - `postgresJsOptions()` maps the two new options. - `server/src/shutdown.ts` - `finalizeServerShutdown` gains two optional ordered steps: `closeHttpListener` runs first, before the application services stop; `closeDatabase` runs after the application services and before the embedded PostgreSQL stop. A failure in either is logged and does not stop the teardown. Final order: listener → application services → database pool → embedded PostgreSQL → instrumentation → Sentry. - New `closeHttpListenerForShutdown()`: stops accepting requests, closes idle keep-alive sockets, waits up to 5 s for open connections, then closes whatever is left. Requests still in flight are drained while every service is available, and none can reach a route after `sql.end()`, on the signal path and the programmatic path alike (the programmatic path's later `server.close` finds the listener closed and skips). - `server/src/app.ts`: the app shutdown hook (`shutdownAppServices`) now stops the plugin job scheduler, whose tick queries the database, so a programmatic `shutdown()` leaves no timer running against the ended pool. - `server/src/index.ts` - `startServer()` is now a thin wrapper around the boot sequence. When the boot sequence throws after the pool exists, the wrapper ends the pool (and the separate migration pool, when configured) before it rethrows. This covers the `process.exit(1)` path in the main module and the CLI `paperclip run` path alike. - The orderly shutdown passes the same `closeDatabaseClients` to `finalizeServerShutdown`. - `endDatabaseClient` tolerates a client without `$client` (test doubles) and uses a 5 second end timeout. - Docs: `docs/deploy/database.md` gets a "Connection Pool Settings" table with every `DATABASE_*` pool variable, its default and its effect; `doc/DATABASE.md` lists the two new variables. - Tests - `packages/db/src/client-options.test.ts`: parsing of the new variables, `0` for the idle timeout, rejection of malformed values, driver option mapping, and the `resolveDatabaseClientOptions` defaults. - `packages/db/src/client.test.ts` (embedded PostgreSQL): `createDb(url)` reports `application_name = paperclip` for its own backend, and a pool with `idleTimeoutSeconds: 1` has zero backends in `pg_stat_activity` after the timeout. - `server/src/shutdown.test.ts`: the listener closes before the application services, and the database close runs between the application services and the embedded PostgreSQL stop; a failing database close is logged while the teardown still finishes; `closeHttpListenerForShutdown` closes idle sockets and resolves on close, force-closes after the grace period, and is a no-op when the listener was never bound. ## Verification - `pnpm --filter @paperclipai/db typecheck` — passes (`check:migrations` + `tsc --noEmit`). - `cd server && pnpm typecheck` — passes. - `cd packages/db && pnpm exec vitest run src/client-options.test.ts src/client.test.ts src/client-teardown-registry.test.ts` — 9 + 18 + 3 tests pass (the `client.test.ts` cases need embedded PostgreSQL; the new one waits up to 10 s for the idle reap and passed in about 3 s). - `cd server && pnpm exec vitest run src/shutdown.test.ts src/__tests__/server-startup-feedback-export.test.ts src/__tests__/bootstrap-claim-routes.test.ts` — 34 + 11 tests pass. The startup-feedback suite exercises `startServer()` with a mocked `createDb`, which is why `endDatabaseClient` tolerates a client without `$client`. - Manual check for a reviewer: start the server against any PostgreSQL, then run `SELECT application_name, state, count(*) FROM pg_stat_activity GROUP BY 1, 2;`. Paperclip's backends now show `paperclip`. Leave the server idle for more than 60 s and the idle backends disappear. Send SIGTERM and the backends close before the process exits. ## Risks - Behavior change with no environment set: idle pooled connections now close after 60 s. The next query after an idle period pays a reconnect (single-digit milliseconds on a local socket). postgres.js reconnects transparently. Set `DATABASE_IDLE_TIMEOUT_SECONDS=0` to keep the previous behavior. - `application_name` changes from `postgres.js` to `paperclip`. Anything that filtered `pg_stat_activity` on the old name would need an update; nothing in this repo does. - The HTTP listener now closes at the start of the final teardown (after the heartbeat run drain, which still needs the API for running agents). The pool close runs after the application services. A late query from a timer that survived the service shutdown would fail with a driver "connection ended" error instead of running; the known database-backed timer (the plugin job scheduler) is now stopped in the service shutdown. - The listener drain adds at most 5 s to a shutdown while long-lived connections (for example WebSocket clients) are open; after that they are closed forcibly. - `startServer()` is split into a wrapper and the boot sequence. The exported signature and return type are unchanged. - No migration, no schema change. ## Model Used - Claude Fable 5.1 (`claude-fable-5-1`) via Claude Code, extended thinking, tool use (file edits, shell, test runs). The change was produced with the model and reviewed by the submitting human. ## 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 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_014t3bi2beVNVVHAxK36dmXm --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
c723bb4dfc |
fix(skills): reuse validated runtime revisions during preparation (#13042)
## Thinking Path > - Paperclip manages AI agents and prepares their runtime inputs before each turn. > - Shared company skills are part of those inputs for native and legacy adapters. > - Runtime materialization refreshed the full inventory again for every declared file. > - Remote skill directories were also downloaded and rebuilt on every turn. > - Measured preparation took 42–73 seconds while runner execution took 7–9 seconds. > - This change reads the inventory once and reuses validated installed revisions. > - Agents retain their selected skills while repeated preparation avoids upstream work. ## Linked Issues or Issue Description **What happened?** One 114-skill preparation performed 407 inventory refreshes, 48 directory rebuilds, and 388 GitHub file fetches. Reusing existing local copies took 151 ms. **Expected behavior** Each listing refreshes inventory once. Unchanged installed remote revisions reuse complete, validated local copies. Local edits remain visible. Explicit updates select new revisions. **Steps to reproduce** 1. Import GitHub skills with supporting files. 2. Run an agent turn, then run another with the same installed revisions. 3. Observe repeated inventory scans, downloads, and runtime directory replacement before execution. Related prior attempts: #2330 and #9268 (still open; #9268 last updated July 9). Those use a marker compared with `updatedAt`. This patch follows the required content validation, immutable revision, company isolation, atomic publication, and read-only semantics, and removes refresh-per-file multiplication. ## What Changed - Split public file reading from reading an already loaded skill. Runtime listing refreshes inventory once. - Add a company-scoped revision cache with file manifests outside the delivered skill directory. Fingerprints omit cosmetic metadata. - Validate exact file inventory, sizes, and hashes before warm reuse. Reject traversal and symlinks. Stage complete builds and serialize atomic publication across processes. - Preserve local/catalog direct sources, stored Markdown fallback, explicit version snapshots, and legacy mutable-ref compatibility. Report missing supporting files and keep older valid revisions readable. - Clean both runtime layouts on rename/removal and record `skills.prepare` under preparation timing. - Add service/cache regressions and an isolated 114-skill benchmark, including a new-process warm run. ## Verification - Final targeted skill-service/cache/trace validation: 86 tests pass (61 embedded-PostgreSQL service tests, 19 cache tests, 6 trace tests). Database tests executed rather than skipped. Focused skill routes, adapter selection, and native runtime context also pass. - `pnpm -r typecheck` and `pnpm build` pass locally at `22caa1fe4`. - The full `pnpm test:run` matrix passes on supported Linux CI at the final head: [CI run](https://github.com/paperclipai/paperclip/actions/runs/34236097762). Local full-suite execution encountered PostgreSQL startup contention, a random allocated-port boundary, and a socket hang-up; every affected suite passed on an isolated rerun. The interrupted local serialized run is not claimed as a complete local pass. - Repeatable benchmark: `pnpm --filter @paperclipai/server exec tsx ../scripts/benchmark-skill-preparation.ts`. Mixed 114-skill inventory with 429 remote files on Linux: cold 286 ms, warm median 96 ms / maximum 153 ms including a new process. Every warm sample performs one refresh, zero upstream fetches/rebuilds, and reports no missing entries; content assertions pass. - Controlled deployment against the previously deployed revision completed with zero lost runs. Real inventory: 114 skills, 670 declared files; 402 cached files match the prior installed copies byte-for-byte. Ten post-deployment warm preparations: median 129 ms / maximum 208 ms; new-process warm 194 ms, zero downloads/rebuilds/missing entries. - Five sequential real browser questions persisted in 10.6–20.7 s (median 12.2 s), versus 50–83 s before. Skill preparation median 240 ms, with one 2.37 s outlier. Total preparation median 3.337 s / maximum 8.728 s **does not fully meet** the <3 s / <5 s target. The excluded historical-run redaction query takes about 1.36 s per scan at two preparation call sites; wider application latency coincided with the outlier, without a cache rebuild. These residuals are reported rather than discarded. - Disposable skill reimport verified through actual selected-skill runs: the next run read the changed code. Fixture removed and agent configuration verified unchanged. - Greptile 5/5, zero unresolved review threads, all final-head CI checks green. ## Risks - Cold preparation still requires upstream availability for supporting files. An unavailable revision is reported missing and never falls back to an older revision. - Valid older revisions and quarantined invalid entries consume additive disk space until skill cleanup. An abruptly killed publisher can leave a lock that requires operator cleanup after confirming its PID is dead. - Warm validation reads all cached file bytes. Very large inventories still have proportional local I/O cost. - No HTTP API, schema, agent configuration, or first-party Telemetry changes. OpenTelemetry retains its operator endpoint gate. ## Model Used OpenAI GPT-6 in Codex, with reasoning, repository inspection, code editing, and test execution. The exact serving snapshot and context-window size are not exposed in this session. ## 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 (targeted and isolated reruns; full Linux CI matrix passes, local full-run caveats above) - [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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
0cc796b7bd |
Build isolated preview artifacts for exact-source deployments (#13041)
## Thinking Path > - Paperclip manages AI agents and their work. > - Managed deployments need a cloud image and a database migration package. > - Branch commits can lack both artifacts until a normal release runs. > - Operators need to test an exact commit without advancing release aliases. > - This pull request adds a preview build mode to the existing release workflow. > - Builds use an immutable source SHA and publish isolated, reusable artifacts. ## Linked Issues or Issue Description **Subsystem affected** Release automation, cloud Docker images, and shared/database npm packages. **Problem or motivation** An operator cannot deploy an unpublished branch with new migrations using only the normal release artifacts. Publishing it through a normal lane would also advance shared release aliases. **Proposed solution** Dispatch the trusted release workflow on master with a full source SHA and a request UUID. Build missing SHA images and, when needed, deterministic preview shared/DB packages. Publish packages under the preview dist-tag with exact workspace pins. Reuse matching artifacts on retries. **Roadmap alignment** This extends release tooling for operator validation. It does not add a core product feature or duplicate a planned product capability. Related PR searches found no duplicate preview deployment workflow. ## What Changed - Add the preview channel, request correlation, artifact checks, and result artifact. - Compile source packages in a separate job from the npm publisher. The publisher uses trusted master code and disables package lifecycle scripts. - Publish only SHA cloud image tags. Preserve release aliases. Use full-SHA tags and no shared build cache. - Verify full source identity for reused packages and images. Both image and npm publishers use isolated jobs and the externally master-restricted npm-canary environment. Fail on registry authentication errors, outages, or artifact identity mismatches. - Let bundled-package preparation use patches from the requested source checkout. - Document publishing configuration, artifact contracts, and deployment order. ## Verification - Passed `pnpm -r typecheck` and `pnpm build`. - Passed `pnpm test:release-registry`: 107 tests, including eight preview tests. - Passed `actionlint -shellcheck= .github/workflows/release.yml`. - Built real shared and DB preview tarballs from an isolated exact-SHA checkout. Verified package source identity and all 244 SQL files and journal entries. - Verified the full revision behind an existing published SHA cloud image. - `pnpm test:run` exposed missing local embedded PostgreSQL library symlinks. The package's postinstall repair restored initdb; all 12 previously affected suites passed on rerun (95 tests). Additional local matrix reruns are in progress. The complete PR CI matrix is green, including general/serialized tests, e2e, typecheck, build, release registry, canary dry run, and the required verify gate. - Live preview publication and staging deployment require this workflow on master and the compatible control-plane backend. They have not run yet. No production deployment was performed. ## Risks Preview npm versions are immutable public artifacts. Both packages must retain their trusted publisher for release.yml in environment npm-canary. Source builds must remain separated from privileged npm publishing. The deploying control plane must verify source identity, integrity, and migration compatibility before use. Normal release jobs retain their existing conditions. Roll back by stopping preview dispatches and reverting the workflow/tooling. Published preview versions remain isolated from normal release tags. ## Model Used OpenAI GPT-6 through Codex, with repository tools, code execution, and test runs. The session does not expose a more specific model version or context-window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used with the available 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 - [x] I have described the issue in-PR following the feature template - [x] I have not referenced internal or instance-local issues or links - [x] My branch name describes the change and contains no internal ticket identifier - [ ] I have run the full tests locally and they pass - [x] I have added tests for the new behavior - [x] I have updated relevant documentation - [x] I have considered and documented risks - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open recommendations or follow-ups - [x] I will address review comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
b97101893f |
feat(projects): select multiple GitHub source repositories (#13010)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Projects give tasks a common source repository and execution context. > - The current project form asks for a raw URL and unrelated metadata. > - Teams need to select several repos from GitHub connections they can use. > - This pull request implements the reviewed project form and repository editor. > - The server checks credential ownership and shared audiences before discovery. > - Existing workspace URLs and runtime identity rules remain compatible. ## Linked Issues or Issue Description **Problem or motivation** Project creation accepts one raw repository URL. It does not help users select repos from their usable GitHub connections or attach several repos together. **Proposed solution** Add a shared GitHub repository picker to project creation and Configuration. Support multiple selections, transactional persistence, and the existing GitHub setup flow. Simplify the project form and Configuration tab as reviewed. **Alternatives considered** Keep a raw URL field or add a separate repository table. The existing workspace collection already supports several repositories and keeps legacy URLs compatible. **Roadmap alignment** This builds on the shipped MCP Tool Gateway and Apps capability. It does not change runtime credential delegation. Related work: #11662 addresses the existing dialog's viewport limits. #4552 addresses generic Git URLs; this change preserves those URLs in existing workspaces. ## What Changed - Add company-scoped repository discovery from usable personal and shared GitHub grants, with provider-ID deduplication, PAT pagination, and partial failure handling. - Document the repository endpoints and board access requirements in OpenAPI. - Validate new selections and save projects with multiple repository workspaces in one transaction. Preserve legacy URLs and existing selections whose access was lost. - Implement the reviewed Create project dialog, shared repository editor, scrolling, and mobile layout. - Move repositories above environment variables, remove Status and Goals controls and env help paragraphs, move Created to the bottom, and redirect Overview to Configuration. - Reuse GitHub setup in dialogs, preserve project drafts, and verify popup completion through the API. - Replace the configuration story's DOM adapter with explicit production composition. Keep the reviewed mobile and short-viewport stories. ## Verification - Passed: `pnpm build`, `pnpm -r typecheck`, `pnpm build-storybook`, and `pnpm check:token-gates`. - Passed: focused repository access, database persistence, configuration, and connection setup tests. - Passed: `pnpm exec playwright test --config tests/e2e/playwright.config.ts tests/e2e/project-repositories.spec.ts`. - The browser tests use a real temporary server/database. They cover create, forty persisted repos, mobile scrolling, save/reload, legacy URL editing, and rejection without a partial project. - GitHub responses and popup completion use deterministic fixtures. No real GitHub account was authorized by the test suite. - All CI general, serialized server, and browser test shards pass on the final commit. - The local full-suite run overlapped review edits and was stopped; fresh repository, OpenAPI, UI/CLI, and connection tests pass. Unrelated local worker, built-in-agent, and routine timing/socket failures passed isolated reruns. - Final commit `1b3308dca`: all CI gates pass, including build, runner verification, typecheck, canary dry run, and security checks. Greptile is 5/5 with no unresolved review threads. - Storybook visual regression is opt-in and was skipped by CI; the Storybook build passed locally. ## Risks - Repository discovery depends on provider availability. Failed connections are reported while successful results stay usable. - Selections identify source workspaces; they do not grant agents new credentials. The existing primary-workspace and responsible-user identity rules still apply. - No database migration is needed. Existing API status, goals, dates, and manual workspace URLs remain supported. ## Model Used OpenAI Codex, based on GPT-6, with repository inspection, code execution, and browser tools. The runtime does not expose a more specific model deployment ID or context-window size. ## 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
297d8741f5 |
fix: resolve duplicate connections to the same GitHub account (#13022)
## Thinking Path > - Paperclip lets people share agents while keeping GitHub access personal. > - Each managed Git or GitHub operation selects an eligible connection grant. > - Connecting the same GitHub account twice creates two grants. > - The old resolver counted grants and rejected them as competing identities. > - Managed commands then ran anonymously and reported a misleading login failure. > - This change compares GitHub account IDs and selects one eligible grant for the same account. > - The benefit is reliable access after reconnecting, with clear diagnostics for real failures. ## Linked Issues or Issue Description Refs #13005. **What happened?** Two active connections owned by one Paperclip user pointed to the same GitHub account. Managed Git refused both as ambiguous. The agent could not push, although the account was connected and had repository access. **Expected behavior** Multiple grants for the same GitHub account resolve to one eligible authorization. Different accounts remain ambiguous. Unavailable access explains its cause without blocking unrelated work. **Steps to reproduce** 1. Connect the same GitHub account twice for one Paperclip user and allow the shared agent through both connection audiences. 2. Start an instruction as that user. 3. Run managed gh or git push. Before this fix, no credential is provided. ## What Changed - Compare stable GitHub account IDs when more than one eligible grant exists. Never deduplicate by login alone. - Prefer an available grant, then the newest authorization with a stable ID tie-breaker. Refresh and webhook timestamps do not change the selection. - Keep the selected credential and connection policy together. Do not combine permissions or fall back from a dedicated account to a personal account. - Print the redacted unavailable reason in managed command output. Unrelated local operations still work anonymously. - Add database and executable launcher regressions, and document selection behavior. ## Verification - Final `pnpm -r typecheck` and `pnpm build` passed. - Fourteen operation credential integration tests passed, covering duplicate personal/dedicated grants, incomplete credentials, distinct accounts with the same login, missing identity metadata, revocation, membership, connection audiences, and A → B → A steering. Existing Git credential and gateway suites and both executable launcher tests also passed. - The local broad test run encountered three embedded-Postgres lifecycle timeouts and stale modules from edits made during that run. A fresh process rerun of all four affected suites passed all 35 tests. The full Node 24 CI test matrix passed on the final commit. - CI passed all 31 checks on `797973b30beb16ba5fa69ed281835e1ab812b449` (Storybook visual regression was correctly skipped). An unrelated Company Settings UI test failed once; the focused local reproduction and rerun of its CI shard both passed without code changes. - Fresh Greptile review of the final commit: 5/5, with no open findings. Security checks passed. - Live acceptance passed with both duplicate connections enabled: managed `gh api user` returned the expected account, managed `git push` succeeded, and the agent created #13023 and pushed its review fixes. No host login or credential changes were used. - Applied the final source/compiled patch to the affected instance with backups, after confirming no runs were active. Restarted service health and the final resolver selection were verified. The patch is an overlay on the existing deployment; this PR supplies the upstream fix. ## Risks The resolver selects one authorization for an already permitted GitHub account. It does not combine repository permissions across connections. If the selected authorization has narrower access, that operation can still be denied by GitHub. Different provider account IDs and unknown duplicate identities continue to fail closed. No schema, host credential, or connection permission changes are included. ## Model Used OpenAI GPT-6 through Codex assisted implementation and verification with shell, database, and browser tools. The exact model variant and context-window size are not exposed in this session. ## 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
d8b9580531 |
fix(ui): debounce recent task ordering (#13007)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - The recent tasks sidebar helps operators return to active and
completed work.
> - Task detail refreshes update the activity timestamps used to sort
that list.
> - Older responses can undo newer activity. Concurrent updates can move
rows repeatedly.
> - This pull request preserves the newest observed activity and
debounces row moves.
> - Operators can select a stable row while task text and live state
stay current.
## Linked Issues or Issue Description
**What happened?**
Recent task rows can repeatedly swap positions when two tasks receive
updates. Older detail responses can also move a task below another task
after a newer comment promoted it.
**Expected behavior**
Rows remain stable during an update burst. The final activity order
appears after one second of quiet. Old responses never reduce the
recorded activity time.
**Steps to reproduce**
1. Enable the streamlined UI and open multiple tasks.
2. Send alternating updates to two tasks in the recent list.
3. Observe row order while those updates arrive and while older detail
data refreshes.
**Paperclip version or commit**
Base commit:
|
||
|
|
1cc45086d3 |
feat: use the responsible person's GitHub for shared agent operations (#13005)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Several people can send instructions to the same agent and task. > - A fixed GitHub token in the provider process can keep the first person's access after another person's message is accepted. > - Task ownership cannot select credentials for each accepted instruction or preserve the identity of an operation already in progress. > - This pull request records ordered execution identity contexts and resolves credentials when managed Git, gh, or GitHub tools start. > - The benefit is automatic personal GitHub access for shared agents, with durable continuation rules and no teammate credential fallback. ## Linked Issues or Issue Description **Subsystem affected** Cross-cutting: orchestration, connection grants, database, runtime adapters, native runners, and run details. **Problem or motivation** A shared agent must use the person whose instructions it has accepted. A queued message must retain its author. A retry or approval without new instructions must retain the originating identity. GitHub must remain optional for ordinary work. **Proposed solution** Persist execution identity separately from task ownership. Give new processes a run-scoped broker capability and token-free managed launchers. Capture identity at operation start. Keep an explicit dedicated-agent grant as an override. Show redacted diagnostics in run details. **Alternatives considered** Per-task ownership, fixed provider tokens, and mutable repository author configuration do not handle accepted steering or concurrent operations. A manual account-selection action would add unnecessary setup to each turn. **Roadmap alignment** This completes the existing Multiple Human Users, MCP Tool Gateway & Apps, Secrets Manager, and Self-healing Runs capabilities. The implementation follows the maintainer-approved plan. Related work: Refs #12843, Refs #12907. Existing proposals #4618 and #8945 cover per-agent or per-worktree author configuration. This change instead follows the accepted human instruction across runtime types. Refs #11831 for governed personal connection delegation; this change preserves connection audience checks and does not use standing delegation as a personal credential fallback. ## What Changed - Add durable, ordered identity contexts and active run references. Preserve message authors through consolidation, steering, retries, delegation, approvals, routines, and restart. - Add an authenticated operation-time GitHub credential broker and local/remote managed git and gh launchers. Keep personal tokens out of the long-lived provider process. - Resolve GitHub gateway and server-side Git operations through the same responsible-person or dedicated-grant selection rules. - Make absent and unavailable GitHub credentials non-blocking at generic startup. Clear host and prior-person credentials. Keep anonymous Git access where supported. - Add run-detail identity history and the dedicated-account warning. Keep task ownership and queue-versus-steer decisions unchanged. - Preserve personal OAuth declarations through connection edits. Retain exact selected grants in the gateway. - Fix continuation races found during real acceptance: verify a warm owner before credential rotation, and wait for bounded durable runner suspension before the next run starts. - Make migrations replay-safe. Retain identity through agent/run deletion, remove it with its company, and clean terminal launcher directories before releasing execution environments. Document coordinated release and rollback. ## Verification - Full workspace typecheck, build, and token gates passed. The complete local suite passed in its normal test groups: 17,120 passing tests, including all 143 serialized server suites. After integrating the newly merged runner API work, full local typecheck and build passed again, along with 890 focused integration tests. All 31 checks on the integrated revision passed, including build, browser E2E, release registry, canary dry run, typecheck, security and all test suites. Greptile is 5/5 with all review threads resolved. - Current focused checks passed: 142 native executor tests, 67 runtime lifecycle tests, 9 durable identity tests, 75 credential/routine tests, 19 low-trust/resumption tests, and the executable migration replay test. - Authenticated browser acceptance with two Paperclip users and two GitHub accounts on one shared native agent passed. Real commits and pushes followed A → B accepted steering → queued A continuation in the same saved conversation. GitHub commit author and committer identities matched all three operations. Both runs succeeded and task ownership stayed unchanged. - Real GitHub MCP calls switched from A to B after accepted steering. A delegated subtask retained its originating identity across a server restart. - Disabling B's GitHub connection left ordinary work successful. Managed gh was unauthenticated and the provider had no inherited GH_TOKEN or GITHUB_TOKEN. - The browser displayed run-detail diagnostics and the exact dedicated-account warning. A final controller-restart check followed by another-person continuation retained the conversation, selected the correct GitHub login and Git author, and removed each terminal launcher directory. - Company-lifetime migration and all five previously failing CI suites passed locally (167 tests). Same-token gateway A → B → A and six broker/launcher boundary tests passed. - Remote callback, launcher, sandbox, and runtime contract tests passed. Both native and legacy Codex completed actual Daytona executions on the integrated revision ([campaign results](https://github.com/paperclipai/paperclip/actions/runs/34155056509)). The remote package-manager shim staging regression also passed locally. ## Risks - Deploy the migrations, server broker, launchers, and runner artifacts together. Existing processes finish with their original contract. New managed processes need the broker endpoint for GitHub operations. - Finish or stop new managed executions before rolling application code back. Keep the additive schema and identity history during rollback. - Scripts that require a persistent raw GH_TOKEN must use managed git, gh, or GitHub gateway tools. Run capabilities authorize code executing within that run to acquire its current identity; this is not hostile-code isolation within one execution principal. Managed commands prevent automatic credential carryover; arbitrary code deliberately copying a credential is outside that boundary. - Uncertain steering acknowledgement deliberately holds new credential acquisition until reconciliation. Already-started operations retain their captured identity. - GitHub private access and provider outages can still fail the specific operation that needs them. Dedicated grant failure does not fall back to personal access. ## Model Used OpenAI GPT-6 through Codex assisted implementation, review, shell execution, and browser acceptance. The exact model variant and context-window size are not exposed in this session. Tool use included TypeScript and Rust tests, database integration tests, GitHub CLI, and authenticated browser control. ## 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
5bddff0920 |
feat(runner): add guarded API search and call fallback (#13003)
## Thinking Path > - Paperclip manages AI agents and their work. > - The new runner gives agents dedicated tools for common tasks. > - Some API operations and parameters have no dedicated tool. > - Agents need a controlled way to find and use those operations. > - This pull request adds API search and calls through the real server routes. > - Existing tools remain the preferred path. The new tools are disabled by default. > - Paired tests measure correctness, tool choice, cost and time. ## Linked Issues or Issue Description **Subsystem affected** Paperclip Runner contracts, production tool authority and the server API catalog. **Problem or motivation** The runner cannot use much of the API described by the old Paperclip skill. A generic HTTP client would also let agents bypass runner control rules. **Proposed solution** Add `search_api` and `call_api`. Resolve calls from the mounted API catalog. Use server-held, run-bound credentials. Preserve route checks and runner lifecycle rules. Keep the tools disabled until an operator enables selected companies. **Alternatives considered** A dedicated tool for every endpoint would add a large initial prompt. An unrestricted HTTP tool would weaken authorization and replay controls. **Roadmap alignment** This extends the native runner tooling. The repository owner requested this design and implementation. The roadmap and related open PRs were checked. No duplicate API escape-hatch PR was found. ## What Changed - Register two compact fallback tools in canonical contracts and provider projections. - Build deterministic API discovery from OpenAPI, mounted experimental routes and the old skill reference. - Execute bounded JSON, text, file and download requests through authenticated HTTP routes. - Recheck active runs, company access and work modes. Block runner lifecycle, scheduling, credential and approval bypasses. Keep routine annotation collaboration available. - Retain mutation receipts. Report uncertain outcomes without blindly repeating writes. - Add a company rollout gate and a durable eval worker with complete cost accounting checks. - Record child-task creation in the activity log with the agent and run. - Add contract, authorization, file, replay and real runnerd/PRP/HTTP tests. - Document rollout gates and paid coverage limits. The companion eval repository retains immutable attempts and reports. ## Verification - Final app commit `da58370524c3626a744eec20164397c5fb6ba9ef`: all 32 checks passed; the unrelated Storybook visual check was skipped. Greptile 5/5; no unresolved review threads. - Full Linux build and recursive typecheck passed. Repository tests were run by project and serialized shard; all 143 serialized server suites passed. - Runner TypeScript: 1,599 passed, two skipped. Rust release: 451 passing test reports. Conformance and replay parity passed. The required API check passed 837 tests, including runnerd → PRP → authority → real HTTP. - Bindings cannot enable API tools without the explicit deployment flag. Unit and real-authority tests prove the default-off boundary. - The standalone API check builds and stages its own binary. It passed after existing staged and debug binaries were removed from the test container. - UI and CLI tests passed. Initial environment failures (missing jq, Docker overlay file identity, and parallel linker memory pressure) and focused passing reruns are retained. The macOS full runner suite has platform-specific failures; Linux is the qualified full-check platform. - Eval harness: 27 tests passed; existing CI discovery ran 86 tests with two unrelated skips. Credential export rejection is tested against the actual report command. - Luna and OpenRouter Sonnet each passed 60 common-workflow runs: ten workflows, three repetitions per arm, zero unnecessary API fallback. - Sonnet passed 11 selected capability/contract cases after fixes. Gemini passed three smoke cases. DeepSeek exceeded the 120-second limit and remains unqualified. - Luna's two cost flags received focused follow-up. The original flags and a later n=1 latency flag remain visible. Sonnet had no cost or latency increase above 20%. - The catalog contains 785 entries; 58 were exercised across all stages. Most operation probes remain unrun and some need additional fixtures. Authored probes do not establish successful coverage. - Total conservative accounted cost: $9.875960. Active paid-campaign time: 88.16/90 minutes. No missing accounting. Later security and harness fixes have provider-free verification; no paid validation is claimed for those revisions. - Inspect the [qualification report](https://github.com/paperclipai/paperclip-evals/blob/codex/seach-call-api-tools/evals/runner-api-tools/reports/2026-09-07-production/READINESS.md) and [verification record](https://github.com/paperclipai/paperclip-evals/blob/codex/seach-call-api-tools/evals/runner-api-tools/reports/2026-09-07-production/verification.json). ## Risks - This is a broad authenticated API surface. Keep the default-off gate until an operator selects initial rollout companies. - Paid coverage is incomplete. Small regression samples do not prove all workflows are unchanged. - A timeout or server failure can follow a committed mutation. The result reports an unknown outcome and requires state inspection. - The new definitions add prompt tokens. The report retains cost flags and cache variation. - No database migration is required. - Repository rules require code-owner approval before merge. Technical CI and automated review are complete. ## Model Used OpenAI Codex based on GPT-6 assisted with code, tests and review. The exact serving model ID and context window are not exposed in this session. It used reasoning, tool calls and code execution. Eval models: `gpt-5.6-luna` with low reasoning, `openrouter/anthropic/claude-sonnet-5`, `openrouter/google/gemini-3.8-flash`, and `openrouter/deepseek/deepseek-v4-flash-0731`. Attempts retain runtime versions, model identity, usage and source provenance. ## 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
f6a211479f |
fix: share current CLI runtimes across sandbox adapters (#12994)
## Thinking Path - Paperclip Runner needs its runtime preinstalled for fast sandbox startup. - Native and local adapters should launch one current CLI installation per provider. - An older global copy can shadow that installation, and exact native compatibility pins must match it. - Update the qualified releases and binary digests, expose shared CLI entrypoints from the provider pack, and prefer the image-owned bin directory. - Keep dependency installation in the image build; task startup only discovers, links, and verifies artifacts. ## Linked Issues or Issue Description **What happened?** Remote native startup rejected a stale global Codex, while CLI-only images lacked runnerd entirely. **Expected behavior** An image-baked runtime starts without uploading binaries or installing packages. All adapters share the same current provider CLI. **Steps to reproduce** Start a native remote task with the old global Codex and the updated runtime available only under `/opt/paperclip-runner/bin`. **Paperclip version or commit** Discovery behavior at `54a99d884`. **Deployment mode** Docker with a remote sandbox. ## What Changed - Prefer `/opt/paperclip-runner/bin`, then the user's local bin directory, then PATH. Existing metadata and version validation remains in force. - Qualify Codex 0.153.4, OpenCode 1.18.29, and Claude SDK 0.3.263 / CLI 2.1.263. Update binary digests, TypeScript/Rust checks, registry defaults, and the displayed OpenCode version together. - Share Codex and Claude's native executable with the ACP bridges through exact dependency overrides. Preserve the separately qualified ACP bridge implementations and their security patches. - Expose shared provider-pack CLI launchers; fail the pack build if Codex ACP resolves a separate Codex installation. Update the eval image's other agent CLIs to current stable releases and remove duplicate global provider installs. - Document the single-current-CLI policy in source comments and development guidance. Latest stable releases are resolved at review/build preparation and pinned; task startup never auto-updates. ## Verification - Native-session and adapter-registry suites: 158 tests passed. - Provider suites: 88 tests passed, 7 Linux-only checks skipped on macOS. One existing macOS temporary-path alias assertion passed when rerun with canonical `TMPDIR=/private/tmp`. - Package-contract and OpenCode materialization tests: 11 passed. - Full typecheck, build, and token gates passed. Rust native-provider/recovery tests: 19 passed. - Broad local suite: 5,974 passed, 23 failed, 41 skipped. Failures are in unchanged macOS workspace/path/port and connection suites; focused runtime tests pass. All latest-head Linux PR checks passed, including the full test shards, typecheck, build, runner verification, browser suites, and canary dry run. - The standalone fleet image built with one current provider CLI each and passed native Codex/Claude binary-integrity checks. A disposable Daytona sandbox reported ready in 798 ms; its baked runner completed an API-key `gpt-5.6-luna` turn in 2,430 ms and returned the expected marker with a usage receipt. No runtime artifacts were uploaded or installed. - The normal shared `codex exec` entrypoint also completed an API-key `gpt-5.6-luna` turn in 2,321 ms. - Both image builds verify the complete generated lockfile against a reviewed SHA-256 before package installation or lifecycle execution. Root lockfile changes remain CI-owned. Merge and rollout remain on hold for operator review. ## Risks - Updating provider CLIs changes their behavior for all adapters; version probes and live native smoke testing are required before image promotion. - The image-owned directory takes precedence. Its entries must launch the same shared CLI as the global PATH, not a private older/newer copy. - Application qualification pins and the deployed image must move together. No startup fallback installation is added. - No schema or authentication-policy changes. ## Model Used OpenAI GPT-6 (Codex). The session does not expose a more specific model ID or context-window size. Used reasoning, repository inspection, code execution, and browser verification. ## 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
932ddb7b37 |
feat: browse GitHub repository access across organizations (#12998)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - GitHub connections give agents access to approved repositories. > - One GitHub identity can use installations across several organizations. > - The permissions page linked to one installation and showed an unfiltered list. > - Users could not easily find another organization or inspect a large selection. > - This change adds account filtering, search, and access configuration links. > - Users can inspect repository access in one compact view. ## Linked Issues or Issue Description Refs #12993. Related repository-catalog work in #11228 and #11234 was checked. This change only improves the existing GitHub connection permissions page. **What existing behavior does this improve?** The GitHub connection permissions page and its repository display metadata. **Current behavior** The page links directly to an existing installation. The repository list has no account filter, search, height limit, or private-repository marker. Refresh access occupies a separate section. **Proposed behavior** Show all authorized repositories by default. Filter by account or organization and search by name. Open GitHub's account chooser to configure access across organizations. Show GitHub icons and private-repository locks. Keep refresh beside configuration and limit the visible list to about ten rows. **Reason and benefit** Users can find repositories across organizations and configure missing access without creating another GitHub identity. Large repository lists no longer fill the page. **Breaking changes** None. Repository display metadata gains an optional private flag. Older snapshots remain valid and gain the flag after access refresh. No SQL migration is required. ## What Changed - Add an All accounts view, account filter, search, and empty states. - Link both configuration controls to GitHub's app account chooser. - Place an accessible refresh icon beside the configuration button. - Keep the repository heading and list in one section. - Add GitHub icons and private-repository locks. - Cap the scrollable list at ten rows using a design token. - Persist GitHub's private flag only when the provider returns a boolean. - Recover missing legacy app configuration from GitHub installation metadata. - Update tests and the GitHub connection runbook. ## Verification - Focused tests passed: 54 permissions-page tests and four GitHub metadata tests. - UI and server typechecks passed before submission. Token gates passed. - Browser checks verified account filtering, search, empty results, and the configuration destination. - The live list contained 40 repositories. Its final height was 272 pixels, which fits ten single-line rows with gaps. Scrolling retained all rows. - A live access refresh populated 30 private-repository lock icons from GitHub metadata. - Full workspace typecheck and build passed. The broad local suite stopped in the general-server group with 18 failed files. Failures include macOS temporary-path handling and embedded PostgreSQL startup. That run also overlapped the legacy fix and retained a stale GitHub module; the final focused run passed all 58 tests. Clean-runner CI is tracked separately. - Latest-head review is 5/5 with the legacy chooser finding resolved. All CI checks passed on commit `0ff2b63f348f5c87d8b7df6e43388f60f5d872d9`, including build, typecheck, all test shards, browser tests, and canary dry run. ## Risks - Older repository snapshots lack visibility metadata until refreshed. Unknown visibility does not display a lock. - The account filter lists authorized installation owners. Users add other organizations through GitHub's chooser. - Filtering changes only the displayed list. GitHub remains authoritative for repository access. ## Model Used OpenAI GPT-6 (`gpt-6-astra`) via Codex. Reasoning, code execution, and browser tools were used. The exact context window size was 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 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
bac60d9d31 |
fix: preserve GitHub sign-in and show connected repository access (#12993)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - GitHub connections give agents an account with selected repository access. > - Fresh local instances enroll with production Paperclip Cloud. > - Enrollment could finish while the GitHub OAuth profile remained disabled. > - Setup then switched to a personal access token form without explanation. > - This change preserves sign-in intent and shows the connected account and repositories. ## Linked Issues or Issue Description Related: #12907, #12943, #12947. Existing open GitHub connection work was checked. No duplicate was found. **What happened?** After Cloud enrollment, a fresh test-drive asked for a GitHub key. Production did not advertise the managed GitHub profile. Staging did. The permissions page also omitted the authenticated username and repository names. **Expected behavior** Continue with GitHub OAuth when available. Explain unavailable sign-in and allow retry otherwise. Show the GitHub username and complete accessible repository list. **Steps to reproduce** Start a fresh test-drive. Choose GitHub and complete instance enrollment while the Cloud GitHub profile is disabled. Open an existing GitHub connection's permissions page. ## What Changed - Preserve managed sign-in intent when the gallery omits its profile. - Refresh the selected gallery entry on retry without resetting the audience. - Fetch all pages of GitHub installations and repositories. - Store only repository IDs, full names, and installation IDs in grant metadata. - Show the GitHub username, repository list, management link, and refresh action. - Discard the repository snapshot after newer installation lifecycle events. Preserve snapshots verified after delayed events. - Lock and re-read grant metadata when applying installation events or saving refreshed access. Patch only webhook fields for other events. Reject snapshots if access changed during the external fetch, using unique access revisions even when timestamps collide. - Show repository installation recovery for managed OAuth even when the app also offers an advanced PAT method. - Update tests and the GitHub connection runbook. No SQL migration is required. ## Verification - Local typecheck, build, and token gates passed. All latest-head CI gates passed, including the complete test matrix and browser suites. Greptile is 5/5 with no unresolved findings. - All 382 focused setup, permissions, metadata, service, and webhook tests passed across final runs. One socket-hang-up test passed on rerun with the full service suite. Final service, metadata, and webhook checks passed all 230 tests. - The broad local suite was stopped after failures. Seven workspace-runtime exposure and control-conflict failures reproduce on base commit `54a99d884`. The broad run also overlapped local iteration; final focused tests and clean-checkout CI are tracked separately. - Browser: a fresh production-backed instance completed enrollment, retried after profile enablement, reached GitHub consent, recovered from a missing installation, and completed OAuth. - Browser: the permissions page showed the authenticated username and the selected private test repository. A real `get_me` call returned the same account. Reading the selected repository passed; reading an unselected private repository failed with 404. - Browser: a second fresh instance completed enrollment and OAuth without a PAT form or unavailable state. Its username and repository list survived reload and refresh. A real get_me call on the final code returned the displayed account. ## Risks - Repository names are now stored in company-scoped grant metadata and shown with that credential. They are display data, not authorization data. - Large selections require more GitHub API calls. A failed later page rejects the refresh rather than reporting a partial list. - Older grants and webhook-invalidated snapshots require Refresh access to load the list. - Cloud profile enablement is separate deployment configuration. This PR does not change OAuth scopes or GitHub App permissions. ## Model Used OpenAI GPT-6 (`gpt-6-astra`) via Codex. Reasoning, code execution, and browser tools were used. The exact context window size was 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 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
856813ba3a |
fix(connections): distinguish local setup from provider handoff (#12947)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Connections give those agents access to external services. > - Connection setup first asks who may use the credential. > - Some providers need a local method selection before OAuth starts. > - The Access button said it would open GitHub even when it opened another local step. > - This pull request names the actual next action and shows the external arrow only for a provider handoff. > - Users can distinguish local setup from leaving Paperclip. ## Linked Issues or Issue Description Refs: #12943 The browser audit found a second, separate clarity problem. GitHub showed "Continue to GitHub" twice: once to open its local method selection and once to start OAuth. The first label promised the wrong action. This change fixes that label without adding or removing a setup step. ## What Changed - Use "Continue" when Access opens another local OAuth setup step. - Keep "Continue to <provider>" and the external arrow when Access starts OAuth directly. - Test GitHub defaults, pre-enrollment setup, direct Notion OAuth, and dialog behavior. - Document the two GitHub button actions. - Preserve the external-handoff arrow in the direct-OAuth Storybook fixture. ## Verification - Targeted connection tests: 114 passed. - `pnpm --filter @paperclipai/ui typecheck`: passed. - `pnpm --filter @paperclipai/ui build`: passed. - `node scripts/check-token-gates.mjs`: passed. - `git diff --check`: passed. - After the Storybook review fix: 100 connection-flow tests, UI typecheck, token gates, and Storybook build passed; visually confirmed the Gmail handoff arrow and local GitHub step labels. - Actual test-drive browser: confirmed default personal identity and Any agent; clicked Continue to the local method screen; switched PAT and OAuth; returned to Access with selections intact; cancelled without a duplicate connection. - Live OAuth, local MCP identity, and a real staging sandbox task passed during the audit. This patch does not change those paths. - Full local suite has known unrelated macOS path/runtime test failures from the audit. All CI passed on head `936ce09f4e1faaf09f9fb778c2cd4c65c2a41972`, including typecheck, build, all test shards, browser tests, and canary dry run. Greptile: 5/5; no unresolved comments. ## Risks - Low risk. This changes button text and an icon cue only. There is no new schema, permission, consent, or credential behavior. - Providers with multiple methods now say Continue before their method screen. Direct OAuth providers keep their existing wording. ## Model Used - OpenAI Codex assisted with code, tests, terminal checks, and actual browser verification. The runtime does not expose the exact model ID or context-window size, so those details are unavailable. ## 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 references) - [x] My branch name describes the change and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass (targeted tests; full-suite caveats above) - [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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
d293dd3d14 |
fix(connections): refresh expired pending enrollment links (#12943)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - Managed connections deliver credentials to an approved instance.
> - A self-hosted instance starts with a time-limited approval link.
> - The setup page cached that link and reused it after expiry.
> - This pull request lets the existing server choose a valid enrollment
link.
> - Users can recover without another setup step or a service restart.
## Linked Issues or Issue Description
Related: #12891 (one-time enrollment) and #12907 (sandbox GitHub
identity).
No duplicate open enrollment-recovery PR or issue was found.
**What happened?**
After a pending Cloud enrollment expired, Continue opened the same
expired
approval link. Cloud returned ENROLLMENT_NOT_AVAILABLE. Returning to
setup and
selecting Continue repeated the failure.
**Expected behavior**
Continue must ask the server for a valid enrollment. The server must
reuse a
live pending enrollment and replace an expired one. Existing approved
instances
must not need another approval.
**Steps to reproduce**
1. Start GitHub setup on a fresh self-hosted instance.
2. Start Cloud enrollment but leave it unapproved until the link
expires.
3. Return to step 2 and select Continue.
4. Before this change, the browser opens the expired link again.
**Paperclip version or commit**
Reproduced from master commit
|
||
|
|
3da58b185e |
fix(cli): restore test-drive credential inputs (#12898)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The CLI provides a test-drive command for a ready local test instance. > - That command must accept a provider credential before it creates the first agent. > - The command did not accept a literal key and could lose an exported key during server startup. > - This pull request accepts both credential paths and captures the CLI environment before startup. > - The benefit is a reliable one-command test drive from an existing shell. ## Linked Issues or Issue Description Refs #12894 **What happened?** `paperclipai test-drive --api-key <value>` failed because the option did not exist. An exported canonical provider variable could also become unavailable before the post-listen bootstrap read it. **Expected behavior** The command must accept a literal key when the operator requests it. The command must also use a provider variable that was present when the CLI started. **Steps to reproduce** 1. Export `ANTHROPIC_API_KEY` in the shell. 2. Run `pnpm paperclipai test-drive`. 3. Observe that bootstrap can report that no credential exists. 4. Run `pnpm paperclipai test-drive --api-key test-value`. 5. Observe that Commander reports an unknown option on the prior implementation. **Paperclip version or commit** The problem exists on `master` after #12894. **Deployment mode** Local development with `pnpm` and the embedded database. ## What Changed - Add the `--api-key <value>` test-drive option. - Keep `--api-key` and `--api-key-env` mutually exclusive. - Capture provider variables before in-process server startup changes the process environment. - Redact literal and environment-backed credentials from Paperclip errors, including custom environment-variable names with surrounding whitespace. - Scrub split and joined literal-key forms from the JavaScript `process.argv` view before telemetry, diagnostics, API work, or server startup. - Warn about process argument and shell history exposure without printing the key. - Add tests for literal keys, option conflicts, environment snapshots, argv handling, and error redaction. - Update the CLI and development documentation, including the remaining external argv exposure tradeoff. ## Verification - `pnpm exec vitest run cli/src/__tests__/test-drive.test.ts` passed 32 tests. - `pnpm -r typecheck` passed. - `pnpm build` passed. - A live literal-key smoke test created one company and one CEO agent without a provider call. - A live exported-variable smoke test created the same clean instance without credential flags. - `pnpm test:run` completed locally with 5,870 passing tests and 19 host-dependent failures in six unrelated suites. The failures came from macOS `/tmp` aliases, exhausted test ports, and existing workspace-runtime fixture assumptions. - GitHub CI passed the full build, typecheck, canary dry run, general tests, serialized server tests, and e2e matrix on clean Linux runners. - Greptile rated the exact latest head 5/5, Superagent passed, and all review threads are resolved. ## Risks - A raw value passed through `--api-key` can appear in operating-system process listings, shell history, or parent-wrapper output before Paperclip can scrub its own JavaScript argv view. The command warns about this risk and Paperclip does not print the value. - The environment snapshot contains the process environment only in memory for the life of the foreground command. - This change adds no schema migration and no REST endpoint. > 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 with GPT-5. The exact deployment version and context window are not exposed to the agent. Extended reasoning, tool use, code execution, and GitHub access were enabled. ## 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
8f0c1d4548 |
feat(cli): add isolated test-drive command (#12894)
Add a foreground-only test-drive workflow with isolated data, provider-backed CEO bootstrap, OpenCode/OpenRouter support, worktree execution setup, reuse safeguards, and delayed browser opening. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
0ffc091473 |
feat(connections): add durable GitHub identities and webhooks (#12843)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Agents need source control access for repository work > - A shared token cannot preserve the responsible person's identity or an agent's dedicated identity > - GitHub App tokens also need durable refresh, repository access checks, and webhook delivery > - Paperclip already has managed connections, encrypted grants, run secret leases, and merge-confirmation behavior > - This pull request extends those systems with GitHub identities instead of adding a parallel credential system > - The benefit is durable GitHub access with explicit identity, repository, runtime, and webhook boundaries ## Linked Issues or Issue Description No public GitHub issue describes this connection change. This description follows the feature request template. **Subsystem affected** Connected Apps, connection grants, secret resolution, native Git runtime setup, webhook processing, and the Apps UI. **Problem or motivation** Users need to connect GitHub once and let agents use the correct GitHub identity. A run should use a dedicated agent account when one exists. Otherwise, it should use the responsible person's account. The connection must survive token expiry, repository access changes, and temporary instance downtime. **Proposed solution** Add user-owned and agent-owned GitHub grants to the existing connection model. Resolve one identity for MCP, Git, `gh`, health checks, and webhook bindings. Store provider tokens in the existing encrypted secret system. Refresh expiring token pairs under the existing lease and compare-and-swap path. Register signed Cloud webhook bindings and process normalized pull request and installation events through a durable local inbox. **Alternatives considered** An organization-wide GitHub token would lose person and agent attribution. Environment variables alone would bypass the managed connection and grant model. A new GitHub-only credential store would duplicate the existing secret and access systems. GitHub App installation tokens and private-key custody remain outside this first version. **Roadmap alignment** This change implements the Connected Apps direction. It also extends the shipped MCP Tool Gateway, per-agent secret access, and action-attribution systems. It does not add a repository catalog. The open repository catalog work in [#11234](https://github.com/paperclipai/paperclip/pull/11234) is related and complementary. ## What Changed - Added agent-owned connection grants and a per-agent credential policy with company and subject constraints. - Added a managed GitHub App method while keeping the personal access token method as an advanced fallback. - Added durable access-token and refresh-token handling with proactive rotation and one automatic recovery after a provider `401`. - Added GitHub identity and installation summaries without storing repository-name lists. - Added signed Cloud webhook binding, event lease, acknowledgement, local idempotency, pull request merge processing, and installation access handling. - Added one identity resolver for MCP, native Git, `gh`, checkout, health checks, and webhook bindings. - Added a class-3 run projection for `GH_TOKEN`, `GITHUB_TOKEN`, a `github.com`-only credential helper, SSH-to-HTTPS rewrite, and GitHub noreply commit attribution. - Added personal and dedicated-agent setup choices plus identity, repository, continuity, and webhook status in the Apps UI. - Added schema migrations, tests, and connection documentation. ## Verification - The current head is fully green in GitHub CI, including build, typecheck, all serialized/general server shards, all browser shards, policy, canary dry run, review, and security checks. - Live staging proof completed with a non-expiring GitHub App user token, selected-repository installation, repository add/remove refresh, managed MCP, native `gh`, HTTPS clone/push/delete, GitHub noreply commit attribution, signed merged-PR webhook acceptance, durable Cloud-to-instance delivery, and installation-access event processing. Temporary branches and temporary repository access were removed afterward. - `pnpm check:token-gates` passed. - `pnpm -r typecheck` passed before and after the rebase onto `origin/master`. - `pnpm build` passed. - The focused connector suite passed 285 tests after the rebase. - The full stable suite passed 5,790 tests and failed 22 tests across 8 general server files. The failures reproduced as shared-runner environment issues. They included `/tmp` versus `/private/tmp`, closed database connections, and invalid high ephemeral ports. The focused connection tests pass in isolation. ## Risks - Migrations add agent grant subjects and a durable connection-event inbox. Migration numbering and safety checks pass. - A raw GitHub user token enters the agent process for Git and `gh`. Per-tool Ask-first controls cannot limit those shell operations. The UI warns users about this boundary. - GitHub App user tokens can be non-expiring. Paperclip performs a continuity check every 30 days, but provider revocation still requires a reconnect. - The webhook path accepts only signed and bounded payloads. It stores a minimal normalized record and no raw provider payload. - GitHub repository permissions remain authoritative. Removed access can make a cached repository count temporarily stale, but runtime access fails immediately. > 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.6-sol`, extended reasoning, tool use, code execution, browser control, and multi-file repository editing. The context window size was not provided. ## 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 - [ ] 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
7b094724e6 |
fix(runner): recover native sessions across restarts (#12845)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The Paperclip Runner keeps durable run and provider state outside one server process. > - A server restart can leave that runner alive or can interrupt it after a provider checkpoint. > - The old startup path used handoff intent and PID evidence, but it did not reconstruct native ownership. > - That gap could block the issue, create a replacement run, or start duplicate provider work. > - This pull request adds durable same-run recovery for coordinated and uncoordinated restarts. > - The benefit is exact recovery of the run, runner, session, provider, steering, and finalization state. ## Linked Issues or Issue Description Refs #9628. That pull request added earlier local-adapter hot-restart work. This change adds native PRP authority reconstruction and same-run provider resume. Refs #10935. That pull request handles missing hot-restart snapshots. This change also supports hard restarts with no snapshot. Refs #11624. That pull request prevents unsafe retry after an adopted legacy process exits. This change reconciles native terminal evidence before provider recovery. Refs #12070. That pull request improves process liveness checks. This change also binds recovery to a process-start fingerprint and fails closed on ambiguity. **What happened?** The server could record hot-restart intent, but startup did not rebuild native runner ownership. A live runner could not re-register its PRP authority. A dead runner could not resume the exact native and provider session on the same heartbeat run. Generic recovery could then block the issue or create replacement work. **Expected behavior** A live native runner must reconnect with the same PID and logical identities. A dead runner must resume the same durable session and heartbeat run with only a new operating-system PID. A proposed or terminal result must finalize once before any provider turn starts. Ambiguous process or session evidence must stay blocked without a signal or duplicate spawn. **Steps to reproduce** 1. Start a Paperclip Runner heartbeat and wait for an active provider turn. 2. Restart only the Paperclip server, with or without a hot-restart marker. 3. Observe that the old startup path does not reconstruct the native control-plane authority. 4. Kill both the server and runner after a provider checkpoint. 5. Observe that the old path cannot resume the exact native session on the original heartbeat run. **Paperclip version or commit** The defect was reproduced from commit `1991f31fd53e7f7794d5c2e4b93be384ade2b41d`. This branch is rebased onto the current `master`. **Deployment mode** Local development and self-hosted server deployments that use the local Paperclip Runner. ## What Changed - Added correlated hot-restart requests and version-compatible native handoff fields. - Added controller boot identity, process-start identity, controller generation, recovery state, request id, and bounded history to the native finalization ledger. - Added transactional recovery claims for live-runner reattach, dead-runner resume, and incomplete bootstrap. - Added fail-closed ownership takeover rules and process identity validation. - Added live runner adoption to the local runner transport without a duplicate spawn. - Added same-run provider checkpoint resume and legacy retry-row compatibility. - Reconciled proposed and terminal results before runner or provider recovery. - Bound the HTTP and PRP listener before startup recovery and delayed scheduling and generic reapers until classification completes. - Added restart-aware health diagnostics, run-log recovery transitions, durable runner diagnostics, and bounded shutdown finalizer draining. - Moved restart-survivable diagnostics into runner-owned, pre-redacted bounded writes; raw stdout and stderr are never persisted. - Added process-start fencing for controller, runner, and provider PIDs; startup classifies every candidate without an implicit cap. - Added crash-recoverable, contention-safe development restart-request coordination and failed-startup listener cleanup. - Added a credential-free real-process restart suite for eight restart, scale, and identity scenarios. - Documented native restart operation, persistence, diagnostics, and verification. ## Verification - The documented native restart commands passed. They ran eight real-process/database recovery scenarios and the live runner adoption transport test. - Native executor tests passed: 111 tests. - Heartbeat recovery tests passed: 124 tests. - Hot restart, health, and shutdown tests passed: 52 tests. - The broader affected server suite passed: 350 tests. - Focused native recovery and startup tests passed: 49 tests. - Runner transport and control-plane tests passed: 63 tests. - Runner-owned diagnostic tests passed for write-time bounding, credential redaction, private file modes, and raw stream non-persistence. - Development restart coordination tests passed: 11 tests. - Database migration checks and the partial-application/replay regression test passed. - Server, database, and Paperclip Runner typechecks passed. - `git diff --check` passed. - Full Paperclip PR CI passed, including build, canary, all five general server shards, all five serialized server shards, all three browser E2E shards, workspace suites, and release-registry verification. - Greptile completed at 5/5 with no outstanding findings, recommendations, follow-ups, or open review threads. ## Risks - Moderate risk. This changes startup ordering and ownership transfer for active native runs. - The migration adds nullable columns and does not rewrite existing rows. - Recovery fails closed when process or durable session identity is incomplete or contradictory. - The first implementation supports the local Paperclip Runner. Remote targets keep their existing behavior. - The real-process suite covers cleanup and asserts that no runner or provider process survives each test. > 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 with GPT-5. The runtime did not expose a more specific model revision or context-window size. Repository editing, shell execution, database tests, and real-process test execution were enabled. ## 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 |
||
|
|
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 |
||
|
|
f449b05bc5 |
feat(apps): unify permissions and action testing (#12802)
## Thinking Path > - Paperclip is the control plane for companies that use AI agents. > - Apps give humans and agents controlled access to external services. > - The existing app detail flow split permissions, tests, setup, and activity across separate pages. > - The split made access rules harder to understand and made reconnect work hard to find. > - New write actions also defaulted to Ask first, which did not match the intended connection policy. > - This pull request combines permission control and action testing, removes the setup page, and moves connection activity into Audit. > - The benefit is one clear place to configure, test, reconnect, and review each app. ## Linked Issues or Issue Description **What existing behavior does this improve?** The installed app Permissions, Test, Setup, and Activity views. **Subsystem affected** Cross-cutting. This change updates the React UI, shared app defaults, server permission behavior, tests, smoke scripts, and connection documentation. **Current behavior** App access and action testing use separate pages. The app detail view also links to a setup page after installation. Connection activity uses a separate tab. New write actions default to Ask first. **Proposed behavior** Permissions uses the connection access language from the initial flow. It includes searchable Read and Write sections, a three-state permission control, and a Test dialog for each action. Reconnect appears below a Needs attention header on Permissions and Review. Old Setup and Test links redirect to Permissions. Old Activity links redirect to the filtered company Audit feed. New write actions default to Allowed. **Reason and benefit** A person can understand and test app access without moving between several pages. Reconnect work stays visible where the person reviews the connection. Audit events use one consistent feed and filter model. New connections have the intended default policy. **Breaking changes** The Setup, Test, and app Activity tabs are removed. Existing deep links redirect to their replacement pages. Existing saved action permissions do not change. Only defaults for new write actions change. **Additional context** This builds on the managed app connection work in #12728. A search found no duplicate open pull request or issue. ## What Changed - Combined action testing with Permissions. - Added searchable Read and Write action groups. - Added Off, Ask first, and Allowed controls with tooltips. - Added an action Test dialog with agent selection, arguments, and formatted results. - Removed the installed-app Setup and Activity tabs. - Added reconnect guidance to Permissions and Review when a connection needs attention. - Routed connection activity into the company Audit feed and preserved the Apps & tools filter in streamlined Audit. - Moved connection removal to the Connectors-page management menu. - Made new write actions default to Allowed across connection creation paths. - Updated regression tests, browser suites, smoke scripts, and connection documentation. ## Verification - `pnpm check:token-gates` - `pnpm exec vitest run packages/shared/src/app-definitions.test.ts server/src/__tests__/generic-mcp-connection.test.ts server/src/__tests__/tool-access-service.test.ts ui/src/components/AppConnectionSidebar.test.tsx ui/src/pages/apps/AppDetail.test.tsx ui/src/pages/apps/AppNotConnected.test.tsx ui/src/pages/apps/AppsConnect.test.tsx ui/src/pages/apps/Browse.test.tsx ui/src/pages/apps/Connections.test.tsx ui/src/pages/apps/composio-services.test.ts ui/src/pages/audit/AuditFeed.test.tsx ui/src/pages/tools/PasteConfigTab.test.tsx` (517 tests passed) - `pnpm exec vitest run ui/src/pages/apps/app-detail/TestPanel.test.tsx ui/src/pages/audit/AuditHub.test.tsx ui/src/pages/audit/AuditFeed.test.tsx ui/src/pages/apps/AppDetail.test.tsx ui/src/pages/apps/Browse.test.tsx` (96 tests passed) - Targeted Playwright verification for connection removal, rename on Permissions, inline action testing, and Smoke Lab Audit evidence (5 flows passed) - `pnpm -r typecheck` - `pnpm build` - `pnpm test:run` completed with 5,755 passing tests and 20 unrelated macOS harness failures. The failures use `/tmp` versus `/private/tmp`, invalid ports above 65535, and workspace fixtures outside this change. ## Risks - Low migration risk. This change has no database migration. - Old app-detail URLs depend on redirect compatibility. - New connections grant write actions by default. Finalization remains configure-authorized and audited, Ask first and Off remain available per action, and existing connections keep their saved policy. > 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, exact model ID `gpt-5`. The client does not expose the context-window size. The model used reasoning, repository tools, code execution, and browser verification. ## 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
9dd6526b47 |
fix(security): harden privileged server boundaries (#12776)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The server controls secrets, host files, outbound requests, and workspace commands > - A red-team review found cases where restricted callers could cross these trust boundaries > - These cases could expose credentials or let untrusted input reach privileged resources > - This pull request applies least-privilege checks at each affected server boundary > - The benefit is safer agent execution without changing the private-instance bootstrap contract ## Linked Issues or Issue Description **What happened?** Several server paths used authorization, redaction, or content-delivery rules that were too broad. Restricted agent keys could obtain company-level operational data. Some adapter and instruction paths could reach server-owned network or file resources without the required owner approval. **Expected behavior** Paperclip must redact credential values, enforce restricted-key scopes, guard outbound network access, prevent same-origin script execution, and reserve host-level file and command controls for authorized operators. **Steps to reproduce** 1. Configure an authenticated development instance at the parent commit. 2. Exercise the affected APIs with a restricted agent key or a non-instance-admin company user. 3. Observe that the parent commit returns privileged data or accepts a privileged operation. 4. Repeat on this branch and observe a redacted response, a safe download, or an HTTP 403 response. **Paperclip version or commit** The findings reproduce from commit `39898ab22` and are fixed by this pull request. **Deployment mode** Authenticated self-hosted server and local development modes. **Installation method** Built from source with pnpm. ## What Changed - Redact generic secret `value` and `token` fields recursively in structured logs. - Classify exact and separator-suffixed `KEY` environment names as secrets in company exports. - Limit restricted self-identity responses and protect company run, log, and secret catalog APIs. - Route HTTP adapter requests through DNS-pinned SSRF protection with exact private-origin allowlisting. - Download HTML, SVG, and other script-capable assets with `nosniff` and a sandbox CSP. - Require instance-admin access for external instruction roots and exports that read them. - Block agent-authenticated host command persistence across supported workspace runtime shapes. - Apply the central runtime-management decision before workspace command controls. - Keep the documented first-user instance-admin claim contract unchanged. - Add regression tests and server-owner configuration documentation. ## Verification - `pnpm -r typecheck` passes. - The Node 24 remediation suite passes with 365 tests. It skips 25 environment-gated tests. - `pnpm build` passes under Node 24. - `git diff --check` passes. - The full local runner reaches known macOS-only general-server harness failures before the serialized route lane. The Linux PR matrix is the authoritative full-suite gate. ## Risks - Restricted agent keys now receive HTTP 403 responses from company-wide run, log, and secret catalog endpoints. - Script-capable assets now download instead of rendering inline. - External instruction roots now require instance-admin access. - Private HTTP adapter endpoints now require an exact origin in `PAPERCLIP_HTTP_ADAPTER_PRIVATE_ENDPOINT_ALLOWLIST`. - Public HTTP adapter endpoints remain enabled. Redirects and metadata or link-local targets remain blocked. - No database migration is required. > 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. The exact serving snapshot and context-window size are not exposed. The model used tool-enabled reasoning, repository access, code execution, and 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
0798c77fde |
Secure Cloud canonical runtime identity (#12766)
Accept and persist Cloud-signed canonical runtime identity before activation, then route absolute self-URLs through the durable runtime identity provider. Co-Authored-By: Codex <codex@openai.com> |
||
|
|
0f94521017 |
fix(runner): restore local session and task integrity (#12721)
## Thinking Path > - Paperclip is the control plane for agents that perform work. > - Paperclip Runner connects durable provider sessions to individual task runs through PRP. > - Provider continuity and per-run authority are different lifetimes. > - The existing implementation mixed those lifetimes and lost event metadata between provider frames, runnerd, persistence, API sanitization, and the task thread. > - That caused failed continuation, missing progress and Plans, duplicate replies, hidden failures, and unsafe recovery. > - This repair gives every heartbeat fresh authority, preserves qualified provider-session continuity, and restores one lossless presentation path without changing direct adapters. ## Linked Issues or Issue Description **What happened?** A second native heartbeat could reuse tickets, leases, command receipts, sequence state, and run identity from the first heartbeat. Provider phase and item identity could be lost before the UI read them. Redaction could corrupt protocol discriminators while still missing malformed credential tails. The task thread could fold progress into the final response, hide failures, or show more than one final answer. Native Codex also exposed approval modes that do not yet have a durable approval bridge. **Expected behavior** Each heartbeat uses a new PRP authority epoch. Codex and OpenCode preserve exact qualified provider sessions; ACPX emits an explicit continuity event when its qualified process-replacement policy is used. Every accepted provider event is presented, classified as internal, or surfaced as unsupported. The task page shows chronological progress, reasoning summaries, activity, Plans, interactions, terminal failures, and exactly one final reply. Direct adapters retain their existing path. **Steps to reproduce** 1. Enable the unified experimental Paperclip Runner setting. 2. Create a local native Codex, OpenCode, ACPX Claude, or ACPX Codex agent. 3. Run response, Plan, structured-question/resume, restart, cancellation, and failure scenarios. 4. Reload the task while active, waiting, failed, and settled. 5. On the old implementation, observe stale run authority, missing classifications, incomplete output, or duplicated/folded replies. **Paperclip version or commit** The repair is based directly on `master` at `87d05e194b643810d16d20612115acd01d735d43`. **Deployment mode** Local development with the embedded database. Related work: Refs #12616, #12646, #12666, #12685, and #12700. ## What Changed - Rotates PRP control-plane, outbox, ticket, lease, command, receipt, and sequence authority for each heartbeat while carrying forward only a validated provider-session identity. - Reads `control-plane-state.json`, validates both durable schemas and lifecycle values, resumes coherent current runs, archives qualified settled authority, and quarantines malformed or mismatched scoped state without moving ambiguous live legacy state. - Preserves Codex provider phase and stable item identities so commentary remains progress and only `final_answer` becomes final. - Adds raw OpenCode HTTP/SSE boundary coverage and canonical reasoning lifecycle mapping. - Makes ACPX normalization lossless for visible reasoning, tool lifecycle metadata, stable bounded identities, Plan revisions, structured requests, failures, and qualified process replacement. Only the compatible terminal assistant message is promoted as final. - Applies schema-aware redaction before generic JWT-shaped detection and scans every diagnostic string leaf. Malformed raw/escaped quoted credential tails are redacted in both server and durable Rust state. - Restores snapshot-style chronological task presentation, expandable tool activity, inline Plan cards, visible waiting/resume/cancel/failure states, and exactly one final answer. - Makes `never` the only qualified native Codex permission mode and rejects unsupported persisted native modes with remediation. OpenCode and ACPX policies remain intact. - Keeps the unified experimental Runner setting as the only enablement flag. Onboarding and direct Codex, Claude, and OpenCode stay on their legacy execution/finalization paths. - Adds cross-language goldens, authority/recovery/fault coverage, exact response/count assertions, and native plus legacy acceptance scenarios. ## Verification - Pull-request GitHub Actions run Rust formatting/tests, TypeScript checks, server/UI tests, builds, protocol drift checks, browser E2E, and security scans. - A separate workflow-only validation ref is pinned directly on this PR head and runs the 35-cell paid local matrix: three core scenarios plus structured-question resume and restart/resume for native Codex, native OpenCode, ACPX Claude, ACPX Codex, and direct Codex/Claude/OpenCode. Run: https://github.com/paperclipai/paperclip/actions/runs/33682434315 - Acceptance requires exact single visible replies, monotonic sequences, matching envelope discriminators, one semantic terminal, one run terminal, no unresolved interaction, no duplicate mutation, no secret leakage, provider continuity, and zero native rows for direct adapters. - Per maintainer direction, tests are running in GitHub Actions rather than on the slower local host. Only formatters and static diff checks were run locally. ## Risks - Recovery from old or partial filesystem state is sensitive. The repair fails closed, preserves active or unverifiable authority, and quarantines only state whose scoped ownership is safe to move. - Provider event formats can change. Closed validators and boundary goldens turn new or malformed events into visible diagnostics instead of silent drops. - Shared task presentation could affect direct adapters. Runtime-fact gating plus the direct-adapter matrix protect the existing path. - Managed and remote providers are not qualified here. Shared code continues to compile and fail safely, but live qualification is deferred. > 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 based on GPT-5. The exact deployed snapshot and context-window size are not exposed to this task. It used agentic reasoning, repository inspection, code editing, Git, parallel subagents, and GitHub Actions. ## 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 and contains no internal Paperclip ticket id - [ ] I have run tests locally and they pass (intentionally deferred to GitHub Actions) - [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 risks above - [ ] All Paperclip CI gates are green - [ ] The paid local-provider matrix is green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge |
||
|
|
8c3b8c432a |
Simplify app connections and enable managed Google access (#12728)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The Apps subsystem gives humans and agents governed access to external tools. > - The current connection flow hides Apps behind an experimental gate and repeats setup text. > - Google sharing choices and generic MCP permissions do not use one consistent opening model. > - Self-hosted installs also need a safe default origin for managed OAuth without a manual config file. > - This pull request makes Apps available, simplifies connection setup, and applies one governed permissions model. > - The benefit is a shorter connection flow that works on a clean self-hosted install. ## Linked Issues or Issue Description **What existing behavior does this improve?** This improves the Apps connection setup flow, managed Google connection flow, generic MCP connection flow, navigation, and runtime origin discovery. **Subsystem affected** Cross-cutting. This changes `ui/`, `server/`, `packages/shared/`, connector documentation, and browser tests. **Current behavior** Apps require an experimental switch. Setup pages repeat titles and explanatory copy. Connection names require manual input. Google credential sharing does not always offer both personal and organization access. Generic MCP providers do not start with the same permission choices. Managed OAuth needs a public URL setting even when the request already has a safe HTTPS origin. **Proposed behavior** Apps are available by default. Setup asks only for required permissions and sharing choices. Paperclip creates conflict-free connection names. Google apps and generic MCP providers use the same human and agent access model. Managed OAuth derives a validated same-origin HTTPS URL when no explicit public URL is set. **Reason and benefit** A clean self-hosted install can connect a managed Google app without hidden setup. Humans can share a service account with their organization. The shorter flow reduces duplicated choices and setup errors. **Breaking changes** The Apps experimental switch is removed. Existing connection APIs remain compatible. New connections can receive a numeric suffix when a name already exists. No duplicate or related public issue was found. ## What Changed - Removed the Apps experimental gate and the breadcrumb that leaves the Apps section. - Simplified all connection setup pages and moved optional provider requirements into one small link. - Added consistent human and agent access choices for Google apps, Zapier, and generic MCP connections. - Added organization sharing to Google Workspace credentials while keeping personal access available. - Generated connection names automatically and resolved name conflicts with numeric suffixes. - Derived a validated public HTTPS origin from the request for config-free managed OAuth. - Updated connector contracts, tests, browser coverage, and authoring documentation. ## Verification - `pnpm check:token-gates` - `pnpm -r typecheck` - `pnpm build` - `pnpm exec vitest run server/src/__tests__/tool-access-service.test.ts server/src/__tests__/generic-mcp-connection.test.ts` (273 passed) - Targeted UI/service regression suite (308 passed) - Six targeted Playwright connection journeys on a fresh onboarding instance (6 passed) - Fresh-install browser proof through Tailscale HTTPS: enrolled with Paperclip Cloud, connected managed Google Drive, and completed a real read operation. - [Exact-head CI run](https://github.com/paperclipai/paperclip/actions/runs/33669760711): all 23 matrix jobs passed, including build, typecheck, server, serialized, canary, and all browser shards. - Greptile 5/5 on `0ae2a859f269984ee950d0af231a5b09a06f3dfd`, with no unresolved review threads. ## Risks Apps are now visible to all operators. The removed experimental flag no longer hides unfinished app definitions. Managed Google availability still depends on the Cloud profile rollout and active instance enrollment. Automatic conflict handling changes only the display name of a newly conflicting connection. > I checked [`ROADMAP.md`](ROADMAP.md). MCP Tool Gateway and Apps are shipped. Connected Apps is planned, and this change improves the existing shipped connection flow. ## Model Used OpenAI Codex, GPT-5, with reasoning, browser control, tool use, and code 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
fdf8c8464d |
feat(runner): add managed provider backends (#12699)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The Paperclip Runner provides durable, provider-neutral agent execution. > - The current stack supports qualified local providers but omits the managed provider paths from the integration branch. > - Claude Managed Agents and AWS AgentCore need explicit profile qualification, durable recovery, usage accounting, and cleanup controls. > - This pull request adds those managed backends as the third part of the Runner parity stack. > - The benefit is managed execution without weakening the default-off Runner rollout gate. ## Linked Issues or Issue Description **Subsystem affected** Cross-cutting: Runner, server orchestration, database profiles, CLI, and adapter configuration UI. **Problem or motivation** The current Runner stack cannot select or execute the managed Claude Agents API or AWS Bedrock AgentCore Harness backends. It also lacks qualified profile storage and recovery checks for those remote resources. **Proposed solution** Add qualified managed and remote profiles, API and CLI management, exact provider selection, durable lifecycle handling, cumulative usage accounting, bounded cleanup, and retention acknowledgement. Keep `enableNativeRunner` default-off. **Alternatives considered** A direct copy of the old integration branch was rejected because its provider contracts, model values, credential flow, and migration history no longer match the current base. A single large parity pull request was also rejected because stacked review keeps each subsystem bounded. **Roadmap alignment** This continues the existing Runner architecture and rollout work. It does not introduce a separate execution system. **Additional context** This pull request is based on the merged #12691 and #12685 stack. It also closes the delayed security-review findings reported on #12691 by binding qualified ACPX and OpenCode launch artifacts to the bytes actually executed. A GitHub search for managed agent, AgentCore, and Claude managed work found no duplicate public issue or pull request. ## What Changed - Add Claude Managed Agents and AWS AgentCore provider executors to runnerd. - Add qualified managed and remote profile storage, routes, OpenAPI contracts, CLI commands, and migration 0237. - Validate profile ownership, enabled state, exact qualified revision, model, agent version, and secret binding before persistence and recovery. - Persist durable provider session and owned skill state for restart-safe cleanup. - Reconcile uncertain create responses and delete remote sessions before owned skills. - Track cumulative provider usage and enforce positive session spend caps. - Recover interrupted AgentCore usage at the next turn boundary by charging the prior invocation ceiling exactly once; keep the session gated until an explicit monotonic budget raise. - Isolate AgentCore AWS configuration from host profiles and credential-process/SSO configuration while preserving workload identity. - Require OpenCode 1.18.17 and fixed build-owned provider-pack artifact paths; remove the ambient executable override. - Snapshot and content-verify ACPX and OpenCode commands, scripts, and provider executables before launch. Linux executes sealed inherited descriptors; macOS uses authenticated private snapshots with retry-safe rematerialization at the spawn boundary. - Persist canonical ACPX and OpenCode launch-profile digests, reject drift across fresh recovery, and make recovery failures sticky. - Close and journal unsafe ACPX active-turn recovery before any provider bootstrap or reconnect. - Add managed provider fields to the Runner configuration UI and permission projection. - Preserve the default-off `enableNativeRunner` experimental flag. ## Verification - `pnpm -r typecheck` - `pnpm build` - Focused managed server, database, CLI, Runner TypeScript, Rust, Claude, AgentCore, ACPX, OpenCode, process-supervisor, and durable-recovery tests passed. - `cargo test -p paperclip-runner-core --lib --locked` (160 tests) - `cargo check --workspace --all-targets --locked` - Native Codex integration tests passed (60 tests); native provider tests passed (7 tests); server native-runtime tests passed (87 tests). - Verified-launch replacement, nested-spawn retry, exact-version, profile-drift, sticky-failure, and no-bootstrap active-recovery tests passed. - `git diff --check` - The PR changes 91 files. `pnpm-lock.yaml` is unchanged. The Rust workspace lockfile adds the approved `rustix` dependency used for safe descriptor handling while `#![forbid(unsafe_code)]` remains enabled. ## Risks - The provider APIs can change while they are in beta. Exact qualification and fail-closed recovery checks limit drift. - Remote cleanup can fail after a partial create. Durable ownership inventories and retry-safe deletion preserve recovery state. - Migration 0237 adds profile tables. The generated migration and snapshot pass the repository migration checks. - Managed execution can incur provider cost. Positive default spend caps and explicit retention acknowledgement limit accidental use. - An interrupted AgentCore invocation without final metadata is conservatively charged to its active session ceiling. This can overstate cost, but cannot undercount it; later work requires an explicit budget increase. - Linux qualified launches use sealed memory descriptors. macOS lacks executable-descriptor APIs, so the runner uses owner-only private snapshots and minimizes linked-path lifetime; hostile same-UID processes remain outside the documented local-host trust boundary. - The global Runner feature remains default-off. > 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, with tool use, code execution, and subagent review. ## 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 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 |
||
|
|
8f9f850c20 |
fix: limit plan-to-auto transition to plan confirmation (#12695)
<!-- This pull request uses ASD-STE100 Simplified Technical English. --> ## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The issue thread controls plan review and agent work modes. > - A user can accept a full plan or confirm a smaller checkbox action. > - Only full plan acceptance must start automatic agent work. > - The current transition did not check the interaction kind. > - This pull request limits the transition to an accepted plan confirmation. > - The benefit is a safe and clear start of agent work after plan approval. ## Linked Issues or Issue Description **What happened?** An accepted confirmation that targeted a plan could change an issue from planning mode to standard mode. This included a checkbox confirmation. A checkbox action is not approval of the full plan. **Expected behavior** Only acceptance of a current full-plan confirmation starts automatic agent work. Other interaction kinds and rejected confirmations keep the current work mode. **Steps to reproduce** 1. Put an issue in planning mode. 2. Create a checkbox confirmation that targets the current plan revision. 3. Accept the checkbox confirmation. 4. Observe that the issue enters standard mode before this fix. **Paperclip version or commit** The problem was present on `master` before this change. **Deployment mode** The problem is in the core server logic and is not deployment-specific. ## What Changed - Require a full `request_confirmation` interaction before plan acceptance starts automatic work. - Add service tests for acceptance, rejection, stale interaction kinds, and unchanged standard-mode behavior. - Check the route activity log for the planning-to-standard mode change. - Document the plan acceptance transition in the V1 contract. ## Verification - `pnpm exec vitest run server/src/__tests__/issue-thread-interactions-service.test.ts server/src/__tests__/issue-thread-interaction-routes.test.ts` passes 140 tests. - `pnpm -r typecheck` passes. - `pnpm build` passes. - `pnpm test:run` was also started. Unrelated workspace-runtime tests failed because fixed local runtime ports were occupied or offset on the shared host. The same failures reproduce alone. The changed test files pass alone. ## Risks - Risk is low. The change adds one interaction-kind guard to the existing transition. - A full accepted plan confirmation still changes planning mode to standard mode and an eligible review issue to todo in one transaction. - Checkbox confirmations, questions, rejection, and standard-mode issues keep their previous 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 with GPT-5, reasoning, tool use, and code execution. The runtime does not expose the exact model suffix or context window. ## 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 Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
4b6de5327e |
Remove cheap model profiles (#12683)
## Thinking Path > - Paperclip manages agents that use different model providers and adapters. > - Paperclip must keep agent execution rules clear and predictable. > - The cheap-model profile added a second execution mode across adapters, task recovery, APIs, and the UI. > - That mode increased configuration and recovery complexity. > - This pull request removes the cheap-model profile as a product feature. > - The benefit is one model-selection path for normal work and recovery work. ## Linked Issues or Issue Description **What existing behavior does this improve?** This change simplifies model selection across agent configuration, task execution, recovery, and adapter capabilities. **Current behavior** Paperclip exposes cheap-model profiles in adapter metadata, agent runtime configuration, task overrides, recovery rules, APIs, and the board UI. Recovery work can select a different model profile from the agent's configured model. **Proposed behavior** Paperclip uses the agent's configured model for normal work and recovery work. Status-only recovery stays limited to coordination work. The API rejects legacy model-profile configuration. A migration removes stored model-profile values from existing agent, issue, and historical revision records. **Reason and benefit** One model path reduces configuration, API, UI, and recovery complexity. It also prevents status recovery from becoming a separate product-level model-routing feature. **Breaking changes** This change removes model-profile fields and adapter capability metadata. Existing stored model-profile values are removed by an idempotent migration. The validators reject new legacy profile values with clear errors. ## What Changed - Removed model-profile types, adapter capabilities, API fields, and model selection logic. - Removed cheap-model controls from agent and task UI surfaces. - Kept status-only recovery limited to coordination context while normal continuations use the configured agent model. - Added an idempotent migration that removes stored model-profile values from agents, issues, and configuration revisions without changing issue update timestamps. - Updated tests and product documentation for the single-model behavior. ## Verification - `pnpm check:token-gates` passes. - `pnpm -r typecheck` passes. - `pnpm build` passes. - `pnpm test:run` completed with 5,607 passing tests and 8 environment-sensitive failures in unrelated fixed-port and database-deadlock suites. The same failures repeated in an isolated rerun. CI is the final clean-room result. ## Risks - This is an intentional breaking change for clients that send model-profile fields. - The migration changes legacy agent, issue, and configuration-revision JSON. It is idempotent and preserves unrelated fields and issue update timestamps. - The change is cross-cutting because the removed feature existed in adapters, shared contracts, the server, plugins, and the UI. > 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 with `gpt-5`. Reasoning and tool use were enabled. The runtime did not expose the context-window size. ## 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) - [ ] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [ ] 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
1ab159d3a7 |
feat(apps): consolidate connector management (#12684)
Completes the post-managed-OAuth connector lifecycle, Paperclip Cloud provisioning defaults, governed test flows, and consolidated Apps UI.\n\nCo-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
141f202e40 |
Clean up experimental settings features (#12681)
## Thinking Path > - Paperclip is the open source app that people use to manage AI agents for work. > - Instance settings control optional product features and developer tools. > - The experimental settings page mixed active experiments, internal tools, and old recovery controls. > - Some workspace links also used the selected company instead of the workspace owner. > - These problems made settings hard to scan and could send users to the wrong company route. > - This pull request removes old controls, groups developer settings, and resolves workspace links from workspace data. > - The benefit is a smaller settings surface and correct workspace navigation. ## Linked Issues or Issue Description **What existing behavior does this improve?** This improves the instance experimental settings page, task watchdog controls, dependency wake recovery, and execution workspace routes. **Current behavior** The settings page shows old recovery controls and mixes product experiments with internal developer settings. Task watchdogs require an extra feature flag. Some direct workspace links use the current company prefix instead of the company that owns the workspace. **Proposed behavior** Remove the old task recovery experiment and its unused API surface. Make task watchdog controls available without the removed flag. Put worktree execution and managed environment controls in the developer section. Resolve direct workspace links from the workspace owner and reject a company prefix that does not own the workspace. **Reason and benefit** The smaller settings page is easier to understand. The server keeps only the dependency wake backstop that it still uses. Workspace links open under the correct company route. **Breaking changes** This removes the experimental issue graph recovery preview and run endpoints. It also removes the task watchdog feature flag. Task watchdog data and dependency wake behavior remain available. ## What Changed - Removed the old task watchdog and issue graph recovery feature flags. - Removed the old issue graph recovery preview, run controls, API contracts, and unused recovery implementation. - Kept resolved dependency wakes as the scheduler backstop. - Grouped product experiments and Paperclip developer settings on the instance settings page. - Made task watchdog controls available without an extra experimental flag. - Added owner-aware redirects and company checks for execution workspace routes. - Hid the false stopped-state badge while a workspace has no active runtime state. - Updated focused server and UI tests for the new behavior. ## Verification - `pnpm check:token-gates` - `pnpm -r typecheck` - `pnpm build` - `pnpm test:run` completed with 5,620 passing tests and four failures in unchanged workspace runtime port tests. The same four failures repeat when the two files run alone. - The complete GitHub CI matrix passed, including all server, serialized server, build, canary, and end-to-end jobs. ## Risks - Clients that call the removed experimental recovery endpoints must stop calling them. - The route checks depend on workspace detail access. An unknown or cross-company workspace returns the global not-found page. - There are no database migrations, lockfile changes, workflow changes, or design image changes. > 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 with GPT-5. The exact deployment ID and context window are not exposed. Reasoning, tool use, and code execution were enabled. ## 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
ed3559dd21 |
feat(server): split the Sentry DSN into front-end and backend variables (#12678)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Paperclip reports server and browser errors through optional Sentry monitoring > - One environment variable sends both error types to one Sentry project > - Operators need separate control for browser and server error data > - This pull request adds specific variables and keeps the existing variable as a fallback > - The benefit is separate monitoring without breaking current deployments ## Linked Issues or Issue Description **What existing behavior does this improve?** The Sentry configuration for server and browser monitoring uses one environment variable. **Subsystem affected** Cross-cutting (multiple of the above) **Current behavior** `SENTRY_DSN` supplies the server and browser clients. Both clients therefore report to the same Sentry project. **Proposed behavior** `SENTRY_DSN_FRONTEND` supplies the browser client. `SENTRY_DSN_BACKEND` supplies the server process. `SENTRY_DSN` remains a fallback for either component. **Reason and benefit** Operators can send browser and server errors to separate Sentry projects. Operators can also activate only one component. **Breaking changes** None. Existing deployments can continue to use `SENTRY_DSN`. ## What Changed - Add `resolveSentryDsns(env)` and use it in the server and browser configuration paths. - Add precedence, empty-string, fallback, and route tests. - Update the README, observability guide, and stale code comments. - Log one warning when the server uses the legacy fallback without exposing a DSN value. ## Verification - `pnpm vitest run --project server sentry-dsn` — 8 tests pass. - `pnpm vitest run --project server auth-routes` — 21 tests pass. - The earlier run of the three targeted suites passed 40 tests. - `tsc --noEmit` passes for the files in this diff. - All required GitHub Actions checks pass, including the full continuous-integration suite. ## Risks The main risk is an incorrect environment variable precedence rule. Unit tests cover specific values, empty strings, and legacy fallback behavior. The existing `SENTRY_DSN` path remains compatible. ## Model Used OpenAI Codex — GPT-5, current runtime, tool use and code 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |