mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-29 21:07:40 +01:00
60b8089a44b4eaa37e627adbfdf2f130bda13335
196
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
60b8089a44 |
fix(runner): trust managed Cloud sandbox images (#18066)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Cloud selects and updates the sandbox image used by its agents. > - Runner admission also required saved qualification for the exact snapshot and configuration. > - An image update left the old record stale and stopped work before runtime startup. > - This pull request trusts the image selected by Cloud and uses the real runtime startup check. > - Agents can continue after an image update without an operator running a separate qualification test. ## Linked Issues or Issue Description **What happened?** A managed Cloud image update could cause `sandbox_snapshot_qualification_required` before provider work began. Runner discovery also fell back to Legacy when saved platform qualification was absent. The agent Test action could require a separate qualification request even when discovery already offered Paperclip Runner. **Expected behavior** A managed Cloud image can start without a saved qualification record. Runtime startup and the handshake report actual compatibility failures. Custom images keep their existing qualification rules. **Steps to reproduce** 1. Use Paperclip Runner on a Paperclip-managed Cloud sandbox. 2. Save qualification for its current snapshot. 3. Update the platform-selected snapshot and leave the old record in place. 4. Start a task. Before this fix, admission rejects the stale record before starting the provider. Related work: Refs #17445, Refs #17724, Refs #17448. These changes cover saved-computer qualification and setup tests. This fix removes the qualification prerequisite only for managed Cloud images. ## What Changed - Use one managed-image policy in runner selection and lease admission. Require the active Cloud configuration to provision the provider. Active captured custom images are excluded. - Use the current Cloud image and ignore missing, stale, revoked or valid saved qualification records for that image. - Reuse the existing provisioned-runner selection path. Keep adapter availability checks and the Legacy choice for managed sandboxes. - Read custom-image metadata directly during discovery without resolving provider credentials. - Use the existing template-matching rule for captured images. Ignore outdated captures, preserve qualification for matching custom captures, and fall back to Legacy discovery for malformed saved capture config. - Skip the separate qualification request when discovery already offers Paperclip Runner as the default. Test checks the actual runtime. - Add regressions for image updates, provider failures, custom images, self-hosted environments and company access. Update the development and verification guides. ## Verification - Before the fix, managed-image discovery regressions returned Legacy, and the rendered Test action called the separate qualification endpoint. - The original runtime source fails four of the five managed-image regression cases. The fixed runtime passes all five, including provider startup error propagation. The baseline check uses the original module source through a temporary Vitest transform and the same database-backed tests. - All 603 focused tests pass: 231 runner selection, 185 environment runtime, 10 snapshot qualification, 168 rendered agent form and nine form source controls. Discovery controls cover unavailable credentials, stale managed markers without an active provisioner, outdated captures, matching custom captures and malformed saved config. The outdated-capture regression fails before the fix and passes afterward. - `node scripts/check-maps.mjs` and `pnpm check:token-gates` pass. - Full `pnpm -r typecheck` and `pnpm build` pass. All five focused files passed together on `8275bbe72bb4d91fb3a02fb0658f0846b2abc966` (`codex/simplify-managed-runner-readiness`, Node 24.19.0, macOS ARM64). - The full local `pnpm test:run` suite is still in progress. Hosted CI is waiting at `ci / gate / Select trusted runner`; the separate `review` workflow is queued. Greptile is 5/5 on the current head, and both review threads are resolved. This PR is not yet verified by full CI. - Live fixed-source Daytona acceptance is not verified. This workspace has no Daytona API key or image configuration. The earlier deployed recovery is not evidence for this source change. ## Risks - Managed Cloud now trusts its selected image. A bad image can fail at real runtime startup instead of a saved qualification gate. - Company access, credentials, runtime integrity and handshake checks still apply. Self-hosted sandboxes, custom environments and active captured custom images keep their qualification and immutable snapshot binding. - No schema change or data migration is required. Existing qualification records can remain in place. ## Model Used - OpenAI Codex, GPT-6 family, with reasoning, tool use and code execution. The exact model ID and context window 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 - [ ] 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> |
||
|
|
c4b6168e08 |
fix(server): disclose assigned tool search page bounds (#18056)
<!-- entire-trail-link-start --> https://entire.com/gh/paperclipai/-/trails/187/changes/paperclip/187 <!-- entire-trail-link-end --> ## Thinking Path > - Paperclip is the control plane for AI agents at work. > - Native agents find connected app tools through the assigned-tool search tool. > - Large catalogs require small pages and an offset for the next page. > - The input schema enforces a maximum of 20 results, but its descriptions omit that number. > - Providers can render the integer field as a plain number and hide its numeric bounds. > - This pull request puts the existing range and default in both descriptions. > - Agents can choose a valid page size before they make a search call. ## Linked Issues or Issue Description **What happened?** An agent can request `limit: 50` for `paperclip_search_assigned_tools`. The tool rejects the call with `invalid_tool_call` at `/properties/limit/maximum`. Its model-visible description does not state the accepted range. **Expected behavior** The tool description and the `limit` description must state the range of 1 to 20 and the default of 5. Agents can use `nextOffset` to read more results. **Steps to reproduce** 1. Inspect the assigned-tool search description in a provider tool list. 2. Render the integer schema as a TypeScript number field. 3. Request `limit: 50` without a visible page-size bound. 4. Observe the validation error. Retry with a valid size and offset. ### Hypothesis and thesis for a fix The numeric schema is correct, but the descriptions omit the page limit. Put the existing range and default in text that all providers can see. Keep the strict validation in the assigned-tool discovery owner. This should reduce avoidable retries. It does not guarantee that every model call will be valid. ## What Changed - State the accepted range and default in the search description and the `limit` property. Add the existing default as schema metadata. - Test the tool listing and calls through the real HTTP MCP bridge for both compact delivery paths. - Document the page size and offset procedure in the Runner README and verification maps. ## Verification - Red: the two new bridge tests fail against the unchanged implementation because the listing omits the numeric guidance. - Green: all 37 tests in `server/src/services/native-runtime/assigned-mcp-tools.test.ts` pass after the change. The tests cover default pages, a 20-result page, offset continuation without duplicates, and rejection of 21 and 50. Existing tests cover grants, revocation, modes, approvals, aliases, and schema chunks. - Current head `7d658d0c4e4d9db3feb53a5c508214440ff058c4`: 37/37 focused tests pass locally. Greptile is 5/5 with no unresolved threads. Current-head CI is green, including typecheck, build, unit tests, Runner checks, and all browser shards ([CI run, attempt 2](https://github.com/paperclipai/paperclip/actions/runs/40733284523/attempts/2)). Browser shard 7 initially failed in a newly merged agent YAML editor test when its clipboard read included the whole page. The single retry passed without a code change; the exact cause is unconfirmed. The original failure remains in [the CI log](https://github.com/paperclipai/paperclip/actions/runs/40733284523/job/122975224906). - Run the focused suite from `server/`: `pnpm exec vitest run src/services/native-runtime/assigned-mcp-tools.test.ts`. - `node scripts/check-maps.mjs` and `git diff --check` pass. - The bridge uses real local HTTP. The app gateway uses synthetic descriptors. No deployed build or live model improvement is claimed. - Full local verification is incomplete. Recursive typecheck and server typecheck require `cargo`, which this workspace lacks. A direct server TypeScript check was killed by the workspace. The full test suite had no final verdict before the resource stop. CI must supply the remaining verification. ## Risks Low risk. This change describes existing limits and adds default metadata. It does not change search execution, page caps, gateway access, revocation, approvals, or audit. Models can still send invalid calls. This change has not measured their future retry rate. ## Model Used OpenAI Codex, GPT-6 family, with tool use and code execution. The exact provider model ID and context window are not exposed to 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, its capabilities, and unavailable model metadata - [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 bug report fields - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] The public branch name describes the change and has no internal task ID - [x] I have run the focused tests locally and they pass - [x] I have added tests for the reported failure - [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 reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
75754ffb7a |
fix: offer setup instead of Run for unfinished agents (#17976)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - An agent can have a saved record before its setup is complete. > - This record stays paused with the setup reason and cannot run. > - Its shared action controls still offer Run beside Finish setup. > - Run then produces a generic refusal instead of taking the user to setup. > - This change makes Finish setup replace Run for that state. > - The user returns to the saved agent and can run it after setup completes. ## Linked Issues or Issue Description **What happened?** The header of a saved agent with unfinished setup offers Run. Clicking it produces "Agent is not invokable in its current state." Finish setup is a separate control that the user must discover. **Expected behavior** Show one Finish setup action in place of Run and Resume while the setup hold is present. Open the existing setup record with its selected runner. Restore normal controls when setup finishes. **Steps to reproduce** 1. Start creating an agent and save it before setup completes. 2. Open the agent from the roster to view its header. 3. Click Run and observe the generic refusal. Related: #17965 fixes the managed Runner connection-test result. This change fixes the controls for a saved setup record. No open duplicate was found in the title search. ## What Changed - Replace Run with one Finish setup action for a unfinished setup record. - Use the existing paused-state fallback when lifecycle details are absent. - Keep the saved agent ID and runner selection in the setup route. - Check unsaved changes before leaving the detail page. - Refresh pause reason and time with lifecycle state so completing setup in another tab restores Run without overwriting editable configuration. - Keep setup available when a caller hides Run or disables work actions. - Extend the agent action tests, onboarding browser journey and feature map. ## Verification - Red: three component regressions fail before the fix. The old UI keeps Run, lacks setup without lifecycle details, and skips the navigation guard. - Three more regressions fail before the preparation-state fix. Preparation, verification and pause transitions retain Finish setup; terminal states cannot reopen setup. - Green: 211 focused tests pass across agent actions, duplication, detail pages and saved setup. The final control suite passes 36 tests. - A real QueryClient, lifecycle hook and action-control regression fails before the pause-field refresh fix, then passes after it. The short-URL editable snapshot stays unchanged while the UUID lifecycle query restores Run. - UI typecheck and production build pass. Token and map checks pass. - The real Chromium onboarding journey passes on final source `67c4c59f6fbfc5bc8eca8f70e12b8dc1c3763f4f`: no Run or Resume, one Finish setup after reload, and the same saved agent reopens. The first attempt could not initialize the disposable PostgreSQL instance at the local shared-memory limit; no app assertion ran. After removing only a verified detached segment from this task’s completed browser run, the unchanged journey passes. No staging deployment is claimed. - A separate local integration branch combines this PR with the final write-recovery fixes from #17960. Its 36 action-control tests and the real onboarding browser journey pass too. This integration preview is not pushed to the PR branch. - All hosted CI gates pass on the final commit, including typecheck, tests, build and E2E. Apex is 5/5 with no unresolved findings. ## Risks - The change uses the existing setup pause reason through preparation and verification. Terminating and terminal records cannot reopen setup. Manual pauses retain Resume, and ready agents retain Run. - The API remains authoritative if state changes while the page is open. No admission, permission, account or credential rule changes. - The browser journey stops at setup configuration. It does not claim provider execution or deployment acceptance. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, repository inspection, tool use and code execution. The session does not expose its exact serving 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> |
||
|
|
21137db805 |
fix: make Check now work for retained monitors on blocked tasks (#18061)
## Thinking Path > - Paperclip lets people manage agents and inspect their work. > - Task monitors schedule checks of work that is still pending. > - A task can retain a monitor after it becomes blocked. > - The UI still offered Check now, but the server rejected the task status. > - The UI also claimed that an automatic check would run on the next tick. > - This change admits an explicit human check through the normal execution gates and shows that automatic checks are paused. > - People can request the check without changing task status, and skipped checks no longer report success. ## Linked Issues or Issue Description **What happened?** A blocked task with a retained monitor showed Check now and an overdue countdown. Clicking the button failed because manual checks required an in-progress or in-review task. The endpoint also returned success when admission skipped a check. **Expected behavior** A human can request one check through normal admission. Automatic checks stay paused while the task is blocked. A check that cannot start reports a conflict. **Steps to reproduce** 1. Schedule a monitor on an agent-owned task. 2. Let the task become blocked while it retains the schedule. 3. Open the task and click Check now. Related: #14909 addresses scheduled-retry promotion. This PR addresses retained task monitors. **Paperclip version or commit** Base: |
||
|
|
d30c8f42b8 |
feat(ui): keep writes durable through temporary disconnects (#17960)
<!-- entire-trail-link-start --> https://entire.com/gh/paperclipai/-/trails/123/changes/paperclip/123 <!-- entire-trail-link-end --> ## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - People save tasks, write documents, make decisions and send board messages. > - A disconnect can hide a response after the server accepts a write. > - Recovery must keep the original account, task and request key. > - The merged connection foundation in #15754 handles reads and shared outage state. > - This change adds bounded write recovery and explicit actions when recovery stops. ## Linked Issues or Issue Description **What happened?** Temporary failures could lose edits, report accepted writes as failures, or require people to copy and send input again. A retry could target a newly selected task or account. Restoring attachments could create a second task. **Expected behavior** Keep the draft, its owner and its target. Retry only operations with a server contract that prevents duplicate writes. Verify uncertain results. Show conflicts and permanent failures, with an explicit resend or cancel action. **Steps to reproduce** 1. Save a task title during an outage, then open another task before recovery. 2. Restore a task creation that needs files, selecting those files in another order. 3. Lose a document or decision response, then interrupt the verification read. 4. Switch accounts while a create, upload or connected-channel publication is pending. 5. Type and erase a new-task draft before the first account lookup completes, then reopen it. This PR carries the write layer from #15769 and its review fixes. It targets master after #15754 merged. Related test cleanup #16952 already covers the unchanged copy-link toast test; this PR does not duplicate that work. ## What Changed - Add bounded autosave and submit jobs for supported writes, with pending, conflict and manual retry states. Retain admitted autosaves after navigation and preserve newer task revisions. - Keep each job with its original account, task and operation. First account resolution adopts admitted startup work; a later account change cancels old work. Remount inline and document editors when their owner or document subject changes. - Preserve task-creation keys and immutable request snapshots through file reattachment. Restore generated document keys before comparing reselected files. Reject changed requests instead of creating a second task. - Check the original account scope before creates and each upload. Save successful upload receipts before stopping on an account change. Identify attachments by content digest and metadata. - Verify uncertain document and decision results. Replay only plain, keyed comments automatically; combined reassignment, reopen and run-setting changes require receipt reconciliation or cancel. Settle each request once when a receipt races its retry. - Scope drafts and connected-channel publication reads to their owner. Keep unowned older records unread and unreplayed, with an explicit confirmed discard action after Activity inspection. Preserve typing through the first session lookup, keep erased text erased, and report browser persistence only when storage succeeds. - Wait for the first account lookup before sending startup status changes or decisions. Retry failed required lookups with a fixed limit and surface exhaustion to the original action. Preserve uncertain comment keys on account cancellation. Check the account generation before a comment retry calls its sender and again immediately before POST after asynchronous preparation. Retire only that request’s optimistic echo on completion. - Return an ordinary comment’s accepted same-company, same-task, same-user receipt before workspace reopening, task status changes or wakeups. Reused keys with changed text still conflict. Complete reference and activity records through the same finalizer for initial sends and accepted retries. It locks the task before its comment, matching task and company deletion, comment removal and tombstoning, rejects removed or tombstoned comments, repairs references and inserts a missing activity record in one transaction, and publishes after commit. - Remove reader-only record and comment-body size caps so accepted browser writes remain readable, including JSON-escaped comment requests in local and session storage. Update four existing Storybook fixtures to use owned draft keys. - Document the write contracts and add regression and real browser recovery coverage. - Add the exact reviewed-save recovery regression for both composer implementations and reloads. Align receipt completion, both comment deletion methods and company deletion with task deletion by locking tasks first. Cover real task and company deletion races. ## Verification - The exact reviewed-unknown-save regression fails in all four cases on original commit `1ed0af4186`. It passes with this PR for both composers, before and after reload. Cancel keeps the text and uploaded receipt. The retained draft sends, and the next message also sends. Run `pnpm exec vitest run --project @paperclipai/ui ui/src/components/composer-recovery.test.tsx`. - The new real PostgreSQL task-deletion race fails with SQLSTATE `40P01` on parent commit `f3253a00c4`. The company-deletion race also fails with `40P01` on `e8cf0e02dd`. All six receipt tests pass after the final lock-order fixes. They cover company deletion, task deletion, comment removal, tombstoning, concurrent cross-task references and interrupted reference repair. Run `pnpm exec vitest run --project @paperclipai/server server/src/__tests__/issue-comment-receipt-postgres.test.ts`. - The full UI run passed 9,656 of 9,659 tests across 816 files. Three cases failed under that run: two large-tree timeouts and one plugin-panel assertion. All 67 tests in those two files passed in an isolated rerun. These failures remain recorded; this does not claim a clean full UI run. - `pnpm -r typecheck`, `pnpm build`, token gates and map checks pass on the final change. The local full repository test command was started, then stopped when the delivery moved to this existing PR. Fresh PR CI must provide the full-suite gate. - A local Storybook walkthrough used the real rich editor. Cancel kept the restored text, Send cleared it after the simulated save, and a new draft enabled Send again. Storybook simulates submission; it is not staging acceptance. - Earlier verification on `f3253a00c4` recorded five browser journeys for title saves, cached-task offline recovery, startup recovery, accepted comment replay and session lookup failure. Those results remain prior-head evidence. No new staging deployment is claimed. - On `e8cf0e02dd`, all CI checks passed after one browser-shard rerun. Its first failure copied page text instead of YAML in an unrelated agent-configuration test. On final commit `35131d4380`, Greptile is 5/5 with no unresolved review threads. The first CI attempt has two failures outside this diff: runner close-attachment suspension and scheduled-retry teardown. The scheduled-retry file passes all 14 tests in isolation; the isolated runner test still fails locally. The single standard CI rerun passed both jobs, and the aggregate verification gate passed. All CI checks are green on `35131d4380`; Apex is 5/5 on that same commit with no unresolved findings. ## Risks - Automatic replay requires server duplicate prevention or result verification. Uncertain combined mutations require receipt observation or cancel and a fresh intentional send. - Old unowned form drafts remain stored but are not assigned to an account. Unowned channel records can be retired after Activity inspection; this never cancels an accepted remote update. - Browser storage and hashing can be unavailable. Storage failure is reported honestly. Without a digest, replay can duplicate an upload rather than silently drop a selected file. - Detached autosaves remain bounded and check account ownership on each attempt. Conflicts or exhaustion retain the draft for explicit recovery. - No schema, credential or agent permission change is included. This PR does not claim staging deployment or original-task acceptance. ## Model Used Anthropic Claude Opus 5.5 (`claude-opus-5-5`) produced the original implementation with tool use. OpenAI Codex, GPT-6 family, assisted with restoration, integration, verification and review fixes. This Codex session does not expose its exact serving 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: devinfoley <139239+devinfoley@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: Amy (Opus) <claude@users.noreply.github.com> Co-authored-by: Dotta <bippadotta@protonmail.com> |
||
|
|
a2fbce9305 |
Fix plugin session and directory reuse on follow-up turns (#18045)
## Thinking Path > - Paperclip preserves task state when agents receive follow-up work. > - Plugin computers keep their process state outside the controller. > - A local receipt proves that a previous plugin run suspended. > - A cold resume left that receipt in place after the session became live. > - The next warm follow-up rejected the stale receipt as an identity mismatch. > - A separate follow-up path also treated a fresh task directory as a Git worktree. > - This PR consumes the obsolete receipt after admission and preserves the bound directory on follow-up. ## Linked Issues or Issue Description Related: #17820. This change retains the controller restoration added by #18018. **What happened?** A plugin session resumed from a suspended checkpoint and completed a turn. Its next warm follow-up failed with `runner_state_identity_mismatch: prior_owner_terminal_state_indeterminate`. The journal had the completed run's identity. The local suspension receipt still had the preceding run's identity. Two separate task histories showed this sequence. After a fresh retry completed in a repository-free plugin directory, an ordinary follow-up could instead fail with `The selected plugin environment does not support Core Git worktree preparation.` The saved task settings contained only `mode: isolated_workspace`, which introduced the default Git strategy on the next admission. **Expected behavior** Keep the same admitted provider session during warm follow-ups. Reuse the saved plugin task directory without Core Git preparation. Retain ownership checks and explicit strategy settings. **Steps to reproduce** 1. Complete a warm plugin task and let its session suspend. 2. Resume the checkpoint and complete another turn. 3. Send a follow-up while that session remains warm. 4. Separately, complete a fresh retry in a repository-free plugin directory and send an ordinary follow-up. **Paperclip version or commit** Both regressions reproduce against base `820c45846` with the added tests. **Deployment mode** Hosted plugin execution. Local reproduction uses the real filesystem and a disposable PostgreSQL 18 database, with synthetic provider execution. ## What Changed - Remove the local plugin suspension receipt after provider recovery and durable run admission publish a live session. Admission still checks the receipt first. Normal suspension writes a new receipt. - Recognize a saved fresh plugin directory through its company, task, workspace, owner, attempt and path. Use the existing directory-selection path. Explicit strategy settings still apply. - Add cold-to-warm, database-backed workspace-selection and ownership regressions. Update execution semantics and session verification recipes. ## Verification - Red: the cold-to-warm regression failed on unchanged executor code with `prior_owner_terminal_state_indeterminate` on the follow-up. - Red: the PostgreSQL regression selected a Git strategy on unchanged environment-selection code. The explicit-strategy denial case already passed. - Green: all 95 tests in `workspace-preparation.test.ts` and `provider-fresh-workspace.test.ts` pass against a disposable local PostgreSQL 18 database, selected with the existing `PAPERCLIP_WORKSPACE_PREPARATION_TEST_DATABASE_URL` test seam. - Green: 92 focused executor cases pass, including plugin checkpoint recovery, warm rotation and denial cases. The full `plugin-runner-task.test.ts` suite also passed (38 tests). - Green: direct server check, `node node_modules/typescript/bin/tsc -p server/tsconfig.json --noEmit`. - Green: `node scripts/check-maps.mjs`, `git diff --check`, and a local diff scan for secrets, personal data and live identifiers. - Full local native suites: 988 of 1,004 cases passed. Sixteen integration cases could not start their bundled PostgreSQL cluster. The failure persisted outside the sandbox. These cases are not claimed as passing. An earlier sandboxed attempt also denied process and loopback operations; those denials disappeared when run outside the sandbox. - The first broad local commands could not locate Cargo on `PATH`. Rust is installed under `~/.rustup`; its Cargo executable was verified. Per the requested scope, subsequent local verification stays targeted to changed TypeScript paths; no Rust source changed. CI Typecheck + Release Registry and Rust verification passed on the initial commit. The complete repository test suite was not run locally. - Review regression: an explicit agent-level Git strategy reproduced the incorrect directory fallback before correction. After including the raw agent strategy in the existing check, all three targeted cases (implicit, task-level explicit, agent-level explicit) pass. The server TypeScript check passes after this correction. - CI on `a81668c4b`: the first workspace-a 2/2 attempt failed in unchanged UI `AgentActionButtons.test.tsx` (`calls clearError and refreshes agent-related queries`, zero mock calls). [Original failed job](https://github.com/paperclipai/paperclip/actions/runs/40717870938/job/122921463517). That shard passed on `294c5dfc3`. The failure is retained here. The UI shard passed on final commit `687000287`; no unrelated UI edits or local UI suite runs were added. - CI also exposed three existing local-directory recovery failures on `a81668c4b`: the review correction applied the raw agent strategy guard to local directories. [Original failed server job](https://github.com/paperclipai/paperclip/actions/runs/40717870938/job/122921463229). Narrowed that guard to adapter-managed directories, preserving local recovery behavior. All 20 targeted cases (three plugin selection cases and 17 local recovery scenarios) pass afterward, and server TypeScript verification passes. - Final commit `687000287d3339b7e15e35d95515b3c75c273d7a`: [hosted CI is green](https://github.com/paperclipai/paperclip/actions/runs/40720169342), including the corrected server shard, all other server/workspace shards, Runner checks, typechecking and build. All 55 non-skipped PR checks pass. Greptile scores this exact commit 5/5, with no unresolved review threads. GitHub reports no merge conflicts. - Pre-merge hosted acceptance was requested. The maintained deployment CLI stopped during artifact discovery: no published private Cloud composition exists for `687000287`. The current private build requires canonical Core master readiness and standard-image provenance. The Core-only branch preview omits the private computer plugin needed for the journey. No campaign or tenant update was started; private-preview deployment support is a separate prerequisite. No live deployment or provider acceptance run is claimed. ## Risks The receipt is removed only after the existing runtime publishes an admitted session. Earlier admission failures keep their proof. A later normal suspension creates a new receipt. The change preserves existing identity, lifecycle and controller checks. Directory selection remains limited to the exact bound, active, repository-free plugin recovery directory. Foreign owners, changed paths, wrong attempts and explicit Git strategies do not gain this fallback. No schema, API, credential, permission or fleet-default change is required. Existing failed runs and recovery holds remain history. This PR does not edit quarantined state or replay an interrupted task. Rollback restores the previous code and can reintroduce the two admission failures. ## Model Used OpenAI GPT-6 through Codex, with reasoning, tool use and code execution. A more specific 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> |
||
|
|
b14e1ecaf8 |
feat: add a complete agent YAML configuration editor (#18036)
<!-- entire-trail-link-start --> https://entire.com/gh/paperclipai/-/trails/175/changes/paperclip/175 <!-- entire-trail-link-end --> ## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Operators configure each agent through several settings tabs. > - Operators also need one complete, editable configuration document. > - The document must retain each resource service's access and validation rules. > - This pull request defines the `paperclip/v1` Agent YAML format and adds an Advanced editor. > - The editor previews changes, rejects stale core writes, and explains partial saves. > - Operators can edit agent settings in one place and verify the saved state after reload. ## Linked Issues or Issue Description Refs #2219. Related settings work: #10974. **Problem or motivation** Agent configuration spans profile, runtime, instructions, skills, tools, channels, permissions, secrets, keys, and revision history. Operators cannot inspect and edit those settings as one versioned YAML document. **Proposed solution** Add an Advanced agent tab with a YAML editor. Define a shared document schema. Read and write resources through their existing APIs. Separate editable settings, explicit commands, and read-only observed state. **Alternatives considered** A raw agent-row editor would omit related resources. A generic database update would bypass resource ownership. The editor therefore uses the existing resource contracts and records partial results when a later request fails. **Roadmap alignment** This extends the shipped agent configuration capability. It relates to easy AGENTS.md configuration, multi-harness teams, governed tool access, and secrets management. Stored credentials remain redacted. This format is an editable settings view; it does not add company portability or provider consent. ## What Changed - Add the `paperclip/v1` Agent document schema and format documentation. - Add the Advanced route, sidebar entry, YAML editor, validation, change summary, save progress, and reload recovery. - Cover core settings, instruction files, skill pins, tool installs/profiles/policies, channels, permissions, secret operations, API keys, and revision restore. - Add private-keyed configuration revisions checked under the agent write lock. Read the current key through its owner so file-based rotation does not require restarting the server. Preserve unchanged secret markers at their original paths. - Retain drafts and returned credentials after partial saves. Require reload before retrying commands. Prevent duplicate submissions. Keep new key tokens visible through rename and disable saves with an empty change plan. - Send only changed channel settings. Require explicit intent for shared profile edits. Load destination instruction files when changing their location. - Update Storybook fixtures, verification maps, and regression tests. Add browser acceptance through real APIs and PostgreSQL. ## Verification - `pnpm -r typecheck` passes. - `pnpm build` passes. - The focused UI suite passes all 50 tests. The API/revision helper suites pass all 93 tests. - All 65 lifecycle tests pass with a dedicated PostgreSQL database. They exercise real row locks, redaction, revision history, audit, and company access. - All six browser acceptance cases pass. They check saved settings and clears, secret redaction, key creation/revocation, stale drafts, lost-response recovery, instruction relocation, revision restore, and key-token retention through rename. The tests use real resource APIs and storage. The MCP target uses the existing local provider fixture. No model run or provider login is claimed. - Signing-key regressions cover both environment changes and real in-place key-file rotation. The protected database save/fencing cases pass after removing the cache. A local measurement of 1,000 file-backed revision calculations took 48 ms. - `pnpm check:token-gates`, `node scripts/check-maps.mjs`, and Storybook catalog checks pass. - The full [PR CI run](https://github.com/paperclipai/paperclip/actions/runs/40725425470) passes on `34ed97bbf9`: all 48 jobs, including all eight browser shards. Greptile is 5/5 on this commit, with no unresolved review threads. This final commit refreshes CI after a runner-routing fallback; its source tree matches `fb4cf488cf`. - Paperclip Review and Superagent Security Scan ended neutral because their external agents did not complete a valid assessment/receipt. Superagent passed on `fb4cf488cf`, which has the identical source tree. One request to retry the final scan returned HTTP 404. Neither check reports a code finding. - The local full-suite attempt was blocked by host System V semaphore exhaustion. Acceptance and lifecycle verification used an isolated PostgreSQL 18 container. Earlier CI runners were interrupted. A local combined run hit hook/test timeouts; the full 88-test route file passed after the builds finished. The final full CI run passes. Earlier failure logs and browser traces remain retained outside the repository. To run the browser regression: ```sh pnpm exec playwright test --config tests/e2e/playwright.config.ts tests/e2e/agent-configuration.spec.ts ``` ## Risks - Multi-resource saves are sequential. Earlier operations can remain saved if a later operation fails. The editor reports the completed steps and requires reload. - Core settings and managed instruction files have atomic revision/hash checks. Other unversioned resource writes and external supporting files retain a race window after preflight. - Shared profile definitions affect other bindings. The editor requires `updateSharedDefinition: true` for those edits. - The editor follows native service normalization and experimental settings. Canonical reload can add generated access profiles or mask environment values. - New editor dependencies require the repository's normal automated lockfile update. This pull request does not edit the lockfile or add a database migration. ## Model Used OpenAI Codex, GPT-6 family. The exact current model version was not exposed. The work used reasoning, repository tools, code execution, and browser automation. Earlier work in this chat used the configured Codex model before a model switch; its exact model ID and context window were not exposed. The current context window size is also 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> |
||
|
|
567c043b17 |
feat(server): expose bounded hot-upgrade readiness (#18037)
## Thinking Path > - Paperclip coordinates agent work and keeps its authority in the server. > - Remote native runners can preserve execution through a server replacement. > - Deployment operators need evidence that current runs support that recovery. > - Process-local drain counters do not establish this fact. > - This PR adds an optional, operator-only readiness observation from existing records. > - A deployment consumer can use that report while the existing runtime retains recovery authority. ## Linked Issues or Issue Description Refs #17439. **What happened?** A deployment cannot distinguish recoverable remote native executions from runs that require a task drain. The existing status endpoint reports only process-local counts. **Expected behavior** An instance operator can request a bounded readiness report without stopping admission or exposing checkpoint material. Missing ownership or persistence evidence must prevent readiness. Ordinary status reads must keep their current cost. **Steps to reproduce** Run a remote native task. Read the task-drain status. It reports active work but supplies no recovery eligibility. Deployment code therefore has no affirmative signal to select an active-run handover. ## What Changed - Add `GET /api/instance/task-drain?upgradeReadiness=1` for instance administrators and existing Cloud control callers. - Return aggregate eligibility from current run identities, controller leases and bound opaque checkpoint headers. Unknown work, pending admission and incomplete reads prevent a positive report. - Bound the explicit read to 1,001 rows, encrypted headers of at most 256 KiB each and 8 MiB total, and a two-second SQL statement timeout in a read-only transaction. Keep ordinary status reads in memory. - Add PostgreSQL, count-transition and route authorization tests. Update the API contract, operator docs and access maps. ## Verification - All seven readiness cases pass against an isolated PostgreSQL 18 fixture. They cover missing checkpoints, legacy adapters, missing process/session identities, foreign owners, expired leases, missing lease tokens, failure state and in-flight work. The positive SQL fixture uses the real Runner checkpoint writer and encryption. Regular sandbox workspace identity and plugin environment-lease identity are tested with independent IDs. Stopped/released/undispatched plugin tasks and every mismatched identity field are rejected. Local/legacy/malformed/oversized or mismatched headers are rejected. A held PostgreSQL table lock proves the two-second cancellation budget, rollback/connection release and unrelated query responsiveness. - All 123 focused readiness, instance-settings and Cloud control assertion tests pass, including operator-only access and no readiness read on ordinary status requests. Runner’s 168 checkpoint tests pass. Runner and server typechecks pass after review fixes. - Workspace typecheck, full build, module-boundary and map checks passed locally before the master rebase. Current-head GitHub CI is now green, including typecheck, build, all grouped/serialized server and Runner tests, browser shards, policy and review-dispatch checks. Greptile completed cleanly at 5/5 for `f15fb0c7e9dfb975090cd5d791a1c8e6701275f8`; all actionable threads are resolved. - The broad local test run was stopped after the macOS embedded PostgreSQL fixture failed to bootstrap. The SQL test was then run on the isolated PostgreSQL fixture. No assertion or timeout was weakened. One unrelated existing route test exceeded its 15-second limit under concurrent local builds; it passed on one isolated retry and the subsequent whole route suite passed. - Hosted active-run upgrade acceptance has not run. This PR supplies an observation; it does not change rollout policy or establish live continuity by itself. ## Risks This is an instance-wide observation, so company members and agent keys must not receive it. A readiness snapshot can age as work changes; shutdown and startup retain their existing execution authority and fencing. The report does not validate a replacement artifact or authorize a schema migration. It decrypts only bounded headers through the checkpoint owner and delegates format/identity inspection to Runner; full journal restoration and physical sandbox authentication remain with recovery. No migration, recurring query, new checkpoint write or wire protocol change is included. The additive Runner header inspection contract reuses its existing parser. ## Model Used OpenAI Codex, based on GPT-6, with reasoning, source inspection, tool use and code execution. The host does not expose the exact serving 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 and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass for the affected contracts; the broad-run limitation is recorded 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> |
||
|
|
820c458465 |
fix(runner): restore per-turn controller checkpoints before resume (#18018)
## Thinking Path > - Paperclip coordinates agents and preserves their work between turns. > - Remote native sessions save controller checkpoints in the database. > - External persistence leaves a small identity marker on local disk. > - A later `per_turn` continuation must restore that checkpoint before it reads the controller identity. > - The restore path handled warm sessions only, so valid per-turn continuations failed before provider execution. > - This PR restores the referenced checkpoint and retains the existing ownership and lifecycle checks. ## Linked Issues or Issue Description Related: #17439 added external controller persistence and the warm restore path. #18011 repairs warm preparation and fresh bootstrap checks; it does not cover ordinary per-turn continuation. **What happened?** A remote OpenCode run completed with `per_turn` lifecycle and saved its controller checkpoint in the database. Its next turn reused the normalized session. Admission read the remaining external-persistence marker as a full controller file and failed with `runner_state_identity_mismatch: durable_identity_unreadable`. The prior run's complete checkpoint and harness backup still existed. The failure occurred before provider work started. **Expected behavior** Restore the exact prior controller checkpoint before identity inspection. Then apply the existing company, task, session, prior-owner and suspended-state checks before a provider can start. **Steps to reproduce** 1. Complete a remote native OpenCode task with `per_turn` lifecycle and external controller persistence. 2. Send a follow-up that resumes the same saved session without a session reset. 3. Observe admission reject the valid external controller marker before provider execution. **Paperclip version or commit** Observed at `40c1ab36cdac70c85dc8fe5e912431834fdb691b`. The same warm-only restore remains on current master. **Deployment mode** Hosted Linux with Daytona and native OpenCode. The original model was `openrouter/deepseek/deepseek-v4.1-flash-1017`. ## What Changed - Restore external controller state for ordinary remote per-turn continuations through the existing checkpoint loader. - Bind that read to the current company and task, the marker's run, and the expected normalized session. - Keep local, warm and restart-recovery paths, prior-owner checks and harness backup checks intact. - Refresh a prior-run projection from the latest checkpoint after a rejected active-owner attempt. Keep current-run full state and the existing legacy file-backed fallback intact. - Add restoration and denial regressions, execution documentation and session verification recipes. ## Verification - Red: the real controller generated an external marker; a valid per-turn OpenCode continuation failed with the exact `durable_identity_unreadable` error before tool-authority construction. The repair passed the same case and its ownership guards. - Review regression red/green: a real controller advanced its checkpoint after an active-owner rejection. Before the follow-up fix, a later valid continuation retained a null attach seed. After the fix, it restored the newer attach template and prepare command. Legacy full-file roots with no database checkpoint retain their existing behavior. - At current head `1f6589233e6121d082a0c0c4444ea895b6e8cd7c`, 86 focused executor cases and all 14 execution-driver cases pass. Coverage includes checkpoint restoration, direct/backup suspension, Codex, legacy files, warm admission and canonical bootstrap, missing or malformed evidence, wrong bindings, active/foreign owners and unsuspended runners. Tests stop before provider launch. - The real PostgreSQL encrypted-checkpoint integration passes, including normalized-session refusal before write and stale-writer fencing. Independent source review found no actionable safety defect. - `node scripts/check-maps.mjs`, `git diff --check`, full `pnpm -r typecheck` and `pnpm build` pass on current head. - The local full suite did not complete: native PostgreSQL startup failed under the host sandbox, an initial Docker rerun lacked migrations, and the migrated retry crossed the review-fix revision change. Logs are retained; that mixed-revision run was stopped and its owned database removed. Full test evidence comes from current-head CI. - Current-head CI passes: 53 successful checks, two intended Storybook skips, none pending or failing. Greptile is 5/5 on that exact head with no open review threads. The only manual merge conflict with #18011 was in the verification recipes; both recipes and the unchanged per-turn restore helper are preserved. **Live continuation acceptance remains unverified, so this PR stays draft.** Two disposable OpenCode/Daytona attempts never reached turns two and three: - At `72b49208b1`, the first turn executed tools and produced the exact 33-byte workspace note, but exceeded its four-minute settlement deadline. The first completion lacked a registered attachment; the second decorated a typed attachment reference with filename/size/hash text. The strict UUID parser rejected that reference before checking a valid criterion reference. The scoped attachment, asset and publication receipt exist. Replaying the actual guard rejects the original input before a database lookup; correcting only that reference passes against the recovered row and receipt. This did not show a publication-persistence or controller defect. The task remained unsettled. - At `1f6589233e`, a separately approved replacement used a temporary prompt-only fixture change requiring exact `deliverable:<attachmentId>` references, with metadata in `verification.detail`. Production code, grading and deadlines were unchanged; the fixture patch was removed afterward. This attempt had no recorded provider authentication, harness-ready, model, tool or result event. Ingress acquisition took 84.072 seconds; transport connection took 205.835 seconds within the 239.832-second failed native execution. A local settlement GET also timed out after 30 seconds. The underlying startup stall is unresolved; these observations do not establish a remote provider outage. Final recovery was blocked with `ambiguous_remote_recovery_evidence`; no successful settlement or continuation is claimed. Both attempts used a Darwin arm64 source host with Node 26.4.0, isolated PostgreSQL 18, a Linux x64 runner and OpenCode 1.18.34. The representative qualified model was `openrouter/deepseek/deepseek-v4-flash-0731`; the original incident used `openrouter/deepseek/deepseek-v4.1-flash-1017`. The controller defect occurs before provider work. Runtime artifacts came from immutable build `e7ea2e2961`, whose Runner package source is identical to the candidate. The current-source manifest, artifact, distribution, asset and all 110 archive-hash checks passed. Each attempt had $10 company/agent model budgets and zero automatic workflow/task retries. Accounting was incomplete; zero recorded spend is not proof of zero cost. Earlier setup failures are also retained: host PostgreSQL bootstrap denial, cached-pack compatibility admission before provider work, and an [official artifact build](https://github.com/paperclipai/paperclip/actions/runs/40696838122) that stopped during an unrelated Pi npm install at its 300-second bound. No manifest or integrity guard was weakened. Owned local processes and databases are stopped, and the temporary fixture patch is removed. Standard fixture cleanup had left one replacement sandbox started; it was stopped and deleted through the SDK. Every owned sandbox was then verified absent with a final 404 readback. Resource cleanup does not establish successful task finalization. An earlier head retained one [voice-recovery timing failure](https://github.com/paperclipai/paperclip/actions/runs/40695892339/job/122843005098): a deadline test observed two failed-provider inspections instead of one. A single isolated shard rerun passed all 1,579 tests without a source change. Its timing explanation remains an inference. The current reconciled head passed without a retry. ## Risks Restoration writes a local projection before the existing admission checks. The encrypted checkpoint loader validates company/task/run and normalized session before writing. A later ordinary continuation refreshes a prior-run projection so rejected admission cannot freeze an active owner's older checkpoint. Active, foreign or unsuspended prior owners still cannot start a successor. Missing or malformed evidence remains blocked. The change adds no retry, credential, provider binary or lifecycle-policy change; it preserves the existing legacy fallback. This PR does not deploy the repair or recover the original hosted tasks. ## Model Used OpenAI GPT-6 through Codex, with reasoning, tool use, code execution and collaborating agents. The session exposes GPT-6 as its model version; a more specific model ID and context-window size 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 `#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> |
||
|
|
25f1070fbd |
fix(runner): preserve checkpoint proof across warm preparation (#18011)
## Thinking Path > - Paperclip coordinates agent work and preserves its execution state. > - Native Runner checkpoints preserve authority across controller changes. > - Warm sessions also need checkpoint writes while their successor prepares. > - External persistence replaces the local state file with a marker. > - Two existing checks treated those valid states as lost ownership or prior activity. > - This PR uses the existing preparation lease and canonical controller state to keep those checks accurate. > - The result is safe warm-session retirement and fresh-session startup on reused sandboxes. ## Linked Issues or Issue Description Related: #17439 and #17320. The open #17401 changes the recovery welcome window and does not cover these paths. **What happened?** A configuration change could fail before the next provider turn with `runner did not durably suspend before checkpoint`. The task already pointed to its preparing successor, but that successor did not yet have a native coordinator. The old completed runner's maintenance checkpoint was rejected. A separate fresh session on a reused sandbox could fail with `resumed_unavailable`. Checkpoint registration had replaced the full local state file with an external-persistence marker. The bootstrap check still required the old full-file format. Process supervision then reported unconfirmed termination before launch. **Expected behavior** Retire the completed warm runner under the same process's live preparation lease. Admit a fresh remote session only when the registered controller proves exact identity, no prior activity and pending bootstrap commands, and the remote session directory can be claimed atomically. **Steps to reproduce** 1. Complete a native warm turn with external checkpoint persistence. 2. Change configuration so instruction preparation must retire that session, then submit a follow-up. 3. Separately, admit a fresh native session on a reused sandbox lease after external checkpoint registration. **Paperclip version or commit** Reproduced in the checkpoint implementation introduced by #17439. Fixed against current master. **Deployment mode** Source checkout tests and a hosted Docker/Daytona incident. No deployment or original-task retry is part of this PR. ## What Changed - Accept completed-run maintenance under the exact successor's live, same-process preparation lease only before a native coordinator exists. - Preserve original controller generation, accepted-result, no-new-work, company and task checks. - Pass the registered controller through the existing connection callback and read its current canonical state for untouched-session proof. - Keep marker-only, identity, activity, backup and atomic remote-directory guards. - Add regressions and update execution semantics and session verification recipes. ## Verification - Warm retirement red: the real Postgres writer rejected the preparing successor's `runner.suspend` checkpoint with `native_runner_checkpoint_owner_lost`. - Warm retirement green: 14 Postgres ownership cases pass, including stale/foreign/expired owners, conflicting native authority and new provider work. - Bootstrap red: real controller registration and external persistence caused the resumed and replacement positives to fail. Six external negative cases passed. - Bootstrap green: all 34 bootstrap cases, the bootstrap-state predicate and 13 connection-driver cases pass (48 total). - `node scripts/check-maps.mjs` and `git diff --check` pass. - Full `pnpm -r typecheck` and `pnpm build` pass. - Full local `pnpm test:run` remains partial/interrupted. The default attempt could not initialize embedded Postgres on this Mac. A dedicated Postgres 18 attempt ran for 17 minutes without a completed file result before interruption; the generic helper separately confirmed unsupported embedded Postgres (`initdb` failed after five attempts) and ignores the external database URL. The generic probe skipped one test. Setup and interrupted-run logs are retained; neither is claimed as a behavioral red or a full local pass. - Real source-hosted Codex/Daytona acceptance was attempted at `6ce7fcacc4` with `gpt-6.1-sol`, `xhigh`. The actual task stopped before provider work at `runner_ingress_auth_failed`, with zero authenticated connections and zero source events. A separate environment-qualification handshake reached challenge/response; that does not prove task authentication. The three-turn warm reuse, configuration retirement, useful output and reload workflow remains unverified, so this PR stays draft. - The live attempt used the cached Linux amd64 Runner binary `7437a4e32a099180889be534fcfb2a086046514490c1448aba46c55848983ed8` from the immutable Daytona image. The current staging binary could not be copied because SSH timed out, and the configured current EXE image returned registry 403. No compatible current local or CI-downloadable artifact was available. Earlier setup failures and cleanup receipts are retained; no provider success is claimed. Disposable test resources were cleaned up. - Exact-head Greptile completed at 5/5 with no open feedback: https://github.com/paperclipai/paperclip/pull/18011#issuecomment-6469515952. All current-head CI checks pass: 53 successful checks and two intended Storybook skips. ## Risks The preparation fallback affects maintenance checkpoints only after an accepted result. An existing native coordinator prevents that fallback. Stale controller generations, expired or foreign preparation leases, wrong tasks and new provider work remain denied. The bootstrap check retains the live controller object and reads current state each time. It does not trust a marker or restore local state beneath a live controller. Pending turns, prior events/connections, backups and existing remote directories retain recovery gates. No schema, provider binary, credential, permission or lifecycle-policy change is required. ## Model Used OpenAI GPT-6 through Codex, with reasoning, tool use, code execution and collaborating agents. This session does not expose a more specific 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> |
||
|
|
83709f75eb |
fix(ui): hide task row retry status labels (#18017)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Task lists and the inbox help people scan their work. > - Shared task rows show system interruption messages beside task titles. > - These messages add detail that the person cannot act on from the row. > - This pull request removes the three system interruption labels from those rows. > - People can still open the task to inspect progress and use Retry. ## Linked Issues or Issue Description Refs #16965, which introduced these labels. Related recovery report: #17386. This change only removes row text and does not resolve that report's retry behavior. **What existing behavior does this improve?** The shared task rows in task lists and the inbox. **Current behavior** Rows show “Retry available,” “Thinking,” or “Trying again soon” beside the title for unresolved system interruptions. **Proposed behavior** Omit all three labels from shared task rows. Keep the existing system-interruption guard so the row does not show a legacy recovery chip in their place. Keep task status, other badges, and retry controls inside the task. **Reason and benefit** People can scan task titles with less incidental execution text. **Breaking changes** The three row labels disappear. APIs, recovery behavior, and task conversation controls stay the same. ## What Changed - Remove the system interruption text from every shared task-row presentation. - Cover working, scheduled-retry, and failed interruptions in both row presentations, including a legacy recovery action that must stay hidden. - Record the expected row behavior and verification states in the task feature map. ## Verification - Passed: token gates, feature-map contract and reference checks, and Git diff whitespace checks. - Passed: 83 component tests in `IssueRow.test.tsx` and `Inbox.test.tsx`, including the new regression cases; full `pnpm -r typecheck`; full `pnpm build`. - The full local `pnpm test:run` was attempted and stopped after 16 database-dependent failures. An independent disposable `initdb` reproduced `FATAL: could not create semaphores: No space left on device`. The host has exhausted its macOS System V semaphore capacity. All required CI test lanes passed on the final commit and provide full database-suite coverage. An earlier attempt also found an unbuilt plugin SDK; building that existing dependency repaired collection before this database failure. - Review the working, scheduled-retry, and failed interruption branches. Each returns no system label. The existing guard still suppresses legacy recovery chips. - Independent source review found no actionable code issues. Regression cases check title navigation, removal of the three labels, and suppression of replacement recovery chips. - All required CI gates passed on commit `dd1d7b08dbba8a10a95c5d24c4aea64479befe95`: typecheck, general and serialized tests, browser suites, build, canary, and Runner checks. - Greptile reviewed that commit at 5/5 with no open findings. The optional Paperclip review also returned 5/5 with no findings; its check status is neutral. ## Risks - Low risk. This removes row text only. Task status, recovery records, other badges, and task-level retry actions keep their current behavior. ## Model Used OpenAI Codex, GPT-6 family. This session does not expose an exact model ID or context-window size. The assistant used reasoning, shell tools, and subagents for source review and validation. ## 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> |
||
|
|
39279aa34f |
feat(ui): shared error, connectivity and query foundation for disconnects (#15754)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The board reads API data and keeps the current task on screen. > - A restart or temporary network failure can interrupt those reads. > - Separate page error handlers can hide cached data or expose raw server codes. > - The app needs one connection state, readable error copy and a consistent read policy. > - This change provides that foundation and moves affected read surfaces onto it. > - The dependent write layer in #17960 preserves edits and submissions across the same failures. ## Linked Issues or Issue Description **What happened?** Temporary API failures could replace loaded content with errors. Different surfaces handled the same outage differently. Some showed raw server codes. A successful query to an unrelated service could also falsely report that Paperclip had recovered. **Expected behavior** Keep cached content visible. Show one connection banner during sustained trouble. Confirm recovery through the Paperclip health probe or its WebSocket. Retry transient reads and show readable errors for permanent failures. **Steps to reproduce** 1. Open a populated task or workspace page. 2. Interrupt API requests with a 503 or a dropped connection. 3. Keep an unrelated external request in flight. 4. Confirm that cached content remains and that the external result cannot clear the outage. 5. Restore the API and check that reads refresh. The write layer first merged into this feature branch in #15769 now has its own dependent PR, #17960. This PR contains the shared foundation and read changes. Merge this PR first. ## What Changed - Classify API errors and provide readable error copy, including non-JSON proxy responses and Retry-After handling. - Use one connection store and health probe with bounded backoff. Confirm recovery from the server health probe or live-updates WebSocket. - Pause reads while disconnected, retry transient errors, and refresh active reads after recovery. - Keep cached data visible through shared query views and affected page, panel and plugin read surfaces. - Add one app-level connection banner and support the pending-write count consumed by the dependent write layer. - Add a query-error rendering guard. Call it directly from the existing CI step. Update development documentation. ## Verification - Historical-chat lookup now follows the same ready/stale roster state as rendering. Three regressions fail before the fix; the six new cases pass after it, including working Retry, fresh data, no-cache error, permanent 403 and company isolation. All six focused query/recovery suites pass 200 tests. Final-commit CI passes and Apex is 5/5 with no unresolved findings. Canary Dry Run initially refused a preview version that was already on npm. It passed after one rerun with fresh registry metadata; no check was disabled. - Integrated current master and retained both transcript interest registration and connectivity reporting on socket open. The seven focused recovery/query suites pass 288 tests, and UI typecheck and production build pass. All 9,451 UI tests across 799 files pass on the merge commit. Final-commit CI passes and Apex is 5/5 with no unresolved findings. - Current head `70d9335d732219352ef0f98414439766bbcb33df`: all hosted CI checks pass. Apex is **5/5** on that head with no unresolved findings. The branch has no merge conflict. GitHub still requires code-owner approval. - The foundation passes 9,430 UI tests in 804 files. After integrating current master page paths, 190 focused page tests pass. - Two unrelated-success regressions fail before the latest fix. With the fix, 62 focused UI tests, all six guard tests and UI TypeScript pass. - The composed foundation and write layer pass **9,505 UI tests in 808 files**, UI TypeScript, a production UI build, and query-error, token and map guards. - A real Chromium journey on the composed source injects a 503 during title save. The loaded task stays visible; one reconnect banner appears; the edit saves after recovery; another task stays unchanged; the saved title survives reload. - Full recursive local checks were not repeated because Runner compilation exhausted local disk during another repair. Hosted checks must pass before merge. No new staging deployment is claimed. - Latest review follow-up: a cached CaseDetail now survives a failed HTTP 429 refresh. Its page regression fails before the fix and passes after it. Eighty focused foundation tests, UI TypeScript, build and guards pass after that change. - Earlier CI evidence is retained: several foundation jobs received a runner shutdown signal together. The write-layer head also failed an unchanged Runner descriptor close test with `provider_transport_failed`. The same Runner source passed that suite in the foundation run. New CI runs cover the updated heads; no check or assertion was weakened. ## Risks - Shared retry defaults change the time before transient read errors appear. Permanent errors still fail promptly. - ApiError.message now contains readable copy. Callers that compare raw codes must use ApiError.code. - Cache success can come from another service or local data. It must not confirm Paperclip recovery. - Durable writes are reviewed separately in #17960. This PR does not change database or mutation contracts. ## Model Used Anthropic Claude Opus 5.5 (`claude-opus-5-5`) produced the original work with tool use. OpenAI Codex, GPT-6 family, assisted with restoration, integration, tests and review fixes. The Codex session does not expose its exact serving 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: devinfoley <139239+devinfoley@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: Amy (Opus) <claude@users.noreply.github.com> |
||
|
|
c9213d1be4 |
fix: send saved queued messages after Stop (#17959)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - People can save follow-up messages while an agent runs. > - Stop preserves those messages and stops the active execution. > - The queue removed its delivery controls when that execution ended. > - Native admission also refused an explicit resend of older queued input. > - This change adds Send for a stopped queue and records fresh board intent. > - The saved message can continue through normal cleanup and admission checks. ## Linked Issues or Issue Description **What happened?** A person queued a message with a screenshot while an agent was starting. Steering was not yet available. They stopped the run. The message remained visible, but no control could send it. Native queue delivery also rejected this transition. **Expected behavior** A stopped queue offers Send. The click preserves message IDs, content, attachments and original authors. It starts at most one eligible continuation. Stop remains effective until the person gives new direction. **Steps to reproduce** 1. Start a native task and queue a second message. 2. Stop the active run before it consumes that message. 3. Open the task after cleanup. Observe the saved message with no send control. Refs #16965 for the queue-control change and #15015 for stopped conversation recovery. No open repair for this exact transition was found. ## What Changed - Show Send for a saved deferred queue with no active run. - Accept the existing board queue action for a stopped native target. Keep live native interruption restricted. - Use the server-recorded click time to authorize older native messages. Reject stale, malformed and wrong-actor intents. - Reuse normal queue dispatch, revision checks, cleanup proofs and execution admission, including a failed native predecessor after a verified Send. - Ignore a fully committed, successful recovered export when admitting a fresh message, while retaining the wait for results still committing. - Honor an applied `/new` conversation boundary while retaining native execution holds until the existing stop and cleanup checks verify them. Workspace holds also survive reset. Check the newest failed or cancelled native execution even when older recovery actions exist. - Keep native automatic delivery separate from the explicit Send action. Update execution and access documentation. ## Verification - Meaningful regressions failed before the fixes: stopped queues lacked Send, native admission refused fresh intent, cleanup and dispatch receipts were missing, deferred rows disappeared, live plan Interrupt rejected its own receipt, and Agent Chat `/new` inherited an old non-workspace execution hold. - Six assembled-wakeup cases fail before the reset cleanup fix. All 11 reset/history cases pass after it: live processes, missing identity, quarantined cleanup, remote leases and live controllers remain held; verified cleanup proceeds and retires the hold. Two more cases fail before the fallback fix and pass after it: Send verifies a stopped or live native predecessor despite a later reset receipt and no recovery record. - **525 server tests pass** across seven queue admission, route, dispatch, envelope, provenance, blocker and conversation files. **343 queue/thread UI tests** also pass. Server/UI TypeScript, token and map guards pass. The final scoped server typecheck also builds native Runner successfully. - The latest regressions prove that completed recovered exports permit fresh input, and clearing conversation history still requires old native stop and cleanup verification; an unsafe workspace still blocks after `/new`; failed native Send reaches actual continuation dispatch with the original queued comment. A result still being committed remains deferred. History plus a newer Stop cannot hide a missing process/controller/lease receipt. - The real Chromium Stop/Send journey passes on current head `75fa5e7222c59f43ff7ac326e81093bc9da28330`: queue a follow-up, Stop, reload, explicitly Send, then verify exactly one useful response and no live run. Earlier browser journeys cover legacy Interrupt, interruption during a write and Stop followed by a new direction. These use an isolated app/database and controlled ACP fixture, not an external AI account or a staging deployment. - Negative cases retain actor, company, issue, assignee, queue and cancellation-receipt bindings; cleanup/process/workspace/controller holds; approvals; pause and budget gates. Typed responses keep their original resolver and immutable result. - Full local recursive typecheck stopped in unchanged Rust Runner compilation with ENOSPC, so the chained full tests/build did not run. All hosted CI gates pass on final commit `75fa5e7222c59f43ff7ac326e81093bc9da28330`, including typecheck, tests, build and E2E. Apex review on that commit is 5/5, with no unresolved findings. Earlier unrelated CI failures involved PostgreSQL fixture-cleanup deadlock and an unchanged decision-expiry deadline assertion; the latter's 20 cases pass locally without source changes. No assertions or limits were weakened. Local resource cleanup was limited to this task's verified completed test processes and rebuildable npm caches. ## Risks - Send can authorize a new turn for a saved message after Stop. A Send click must be newer than the stopped execution; a live plan Interrupt is bound to the cancellation receipt produced by that same click. It does not imply that cleanup finished or that an external action is safe to replay. - The existing endpoint and intent format are reused. No schema or credential change is required. Live native steering and legacy interruption keep their existing paths. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, repository inspection, tool use and code execution. The session does not expose the exact serving 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> |
||
|
|
f52da40f08 |
fix: resume queued turns after maintenance (#17967)
Keep an accepted turn's starting input in task history, show its admission wait, and resume existing queued runs promptly when maintenance ends or expires. Verified with behavioral red/green regressions, real PostgreSQL and process execution, browser/native Runner acceptance with a deterministic provider, workspace typecheck, production build, and current-head CI/review. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
09ad9adce2 |
feat(server): adopt running remote agents through durable controller checkpoints (#17439)
## Thinking Path > - Paperclip must keep admitted remote work alive while its main server is replaced. > - Runner owns recovery mechanics and exposes opaque checkpoints through #17097. > - The server owns company scope, encryption, Stop, tool authority and execution ownership. > - A successor must prove current ownership before it adopts the original execution. > - Checkpoint bursts must also leave capacity for normal requests and lease renewal. > - This PR persists and adopts that authority through the existing runtime boundaries. ## Linked Issues or Issue Description **What existing behavior does this improve?** Remote agents retain the original execution during a bounded main-server outage. **Current behavior** A server restart can lose the controller's local state and connection. An unsafe replacement could repeat a turn or an uncertain mutation. Checkpoint writes in the request pool can also delay ordinary requests during an aligned burst. **Proposed behavior** Restore encrypted control records from Postgres and adopt the original runner under a fenced lease. Recover known tool receipts through current tool authority. Give control checkpoints a shared pool capped at two connections per database owner. Depends on #17097. Successors are #17455 and #17456. Qualification and presentation remain separate review slices. ## What Changed - Add company/run-bound encrypted checkpoint records and migration 0394. Keep the SQL idempotent after renumbering against current master. - Recover startup and expired ownership through native runtime and heartbeat. Preserve the sandbox lease, admitted runner artifact, harness configuration, native session and active turn. - Keep Stop, finalization, preparation ownership and stale-writer fencing transactional. Preserve graceful detach and natural crash takeover. - Recover committed tool receipts through the existing authority. Reauthorize reads and hold uncertain mutations. - Bound startup retention with the existing coordinator and preserve zero idle scans. - Share at most two checkpoint connections per database client. Keep application and liveness capacity separate. Close the checkpoint pool during shutdown; late writes cannot reopen it. - Count SQL across both application and checkpoint clients. Prove request/liveness progress, command recovery and failure after pool shutdown with real Postgres. ## Verification Project creation recovery now uses the existing project activity receipt owner. It retains authenticated input normalization, fingerprint checks and current run authority after the receipt lock. An absent receipt returns no result before mutation. The new lost-HTTP-response and no-effect regression uses real API routes and Postgres. The seven transport cases pass locally. This Mac skips all 20 database cases. On current source `5de803c2cd`, Linux [job 122593415890](https://github.com/paperclipai/paperclip/actions/runs/40620576702/job/122593415890) executes all 20 project-tool cases successfully (9.480 seconds), including the committed-project lost-response regression. Its shard passes 1,627 cases with three unrelated skips. Server typecheck passes. The transport regression initially has two failures; a subsequent incorrect expectation about schema defaults was corrected before the final pass. Ordinary execution adds no checkpoint writes or recurring work. Current candidate `5de803c2cd` includes the project-creation receipt recovery fix and master `2cd747d1b6`. Migration 0394 retains the prior idempotent checkpoint DDL. Every master SQL file and journal entry is preserved. Snapshots 0390–0394, migration checks and server typecheck pass. The ordinary warm-turn regression fails on its second turn before `a219ab51ad`. After correction, three completed warm turns select the correct prior checkpoint and preserve the original session. All 288 provider-wiring cases pass. The control plane, external persistence callback, identity rotation and filesystem are real; the backend and database-load seam are scripted. The 13 warm admission/configuration variants also pass after final master integration. This does not qualify an underlying harness. At current source `5de803c2cd`, Linux [job 122593415907](https://github.com/paperclipai/paperclip/actions/runs/40620576702/job/122593415907) passes all 940 native-session-executor cases (61.431 seconds), including the warm external-checkpoint behavior; the shard passes 2,358 cases with one skip. Current [Runner job 122593415475](https://github.com/paperclipai/paperclip/actions/runs/40620576702/job/122593415475) passes the native recovery lane: 115 passes and five container-only skips, including the encrypted restore guard, fresh preparation (63.189 seconds), blocked claim lock (1.226 seconds) and recovery beyond 101 blocked owners (3.897 seconds). The first lane passes 2,215 cases with one skip. The SQL cost test reports zero idle and streaming SQL for both output volumes; this is component evidence, not a production capacity claim. At prior candidate `1ff7bb44f4`, Linux job 122549307215 passes all 938 native-executor cases, including the three-turn external-checkpoint regression. Job 122549306469 passes the native recovery lane with 115 passes and five container-only skips, including the encrypted-restore session guard, fresh preparation (63.664 seconds), claim-lock contention (3.961 seconds), and 101-owner recovery (3.824 seconds). This Mac skips the real-Postgres suite. The earlier full local executor attempt has 921 passes and 16 failures during embedded-Postgres initialization before assertions. The original fixture collisions and their corrections remain recorded. At earlier candidate `8fbe62b41d`, server shard job 122535673841 has 3,876 passes, one failure and one skip in an unchanged expiry-worker retry/drain timing test. The same server/database tree on qualification source `b64cac6951` passes all 20 expiry cases and all 3,877 shard cases. The single diagnostic retry, job 122541891915, passes all 20 expiry cases and all 3,877 shard cases (one skip). No assertion was weakened. The original failure remains recorded and its exact timing race is not proven. All Actions checks and legacy status passed on `8fbe62b41d`, with completed Greptile 5/5 and no open feedback. The next candidate `1ff7bb44f4` also passed all Actions checks and Greptile 5/5. Its Paperclip Review remained queued before the new master conflict required integration. The new candidate needs fresh exact-head CI and reviews; old checks do not qualify it. Migration generation is checkpoint-only, all master SQL and journal entries remain unchanged, and migration checks, server typecheck and all 13 warm-owner variants pass after integration. The first migration check was blocked by TSX sandbox IPC; its permitted repeat passes. The first warm-test command used an incorrect path and ran no tests; the corrected command supplies the 13-case receipt. All 16 database pool-lifetime/options/teardown cases pass after granting loopback permission; the first batch had two EPERM failures and 14 passes. Earlier semantic-tool/HTTP recovery, adoption, encryption-batch, zero-streaming-write and idle-SQL receipts remain source-attributed in the [qualification record](https://github.com/paperclipai/paperclip/blob/2ff66f57da0da35bac1c19a2366ea4b84d87a986/doc/plans/2026-10-22-hot-upgrade-qualification.md). That record retains earlier assertion, setup and cleanup failures and their corrections. No failed gate is waived. The historical 300-session component campaign passes four after phases: steady read p99 is 107–108 ms at 500 reads/s and 100 writes/s; aligned-burst read p99 is 103–105 ms after the bounded pool, versus 584–689 ms before. This comparison isolates the persistence corrections. It does not measure the final stack's hosted active-agent capacity. The hosted zero-agent API pair leaves SQL and CPU essentially unchanged, but both arms fail absolute latency gates and candidate peak cgroup memory fails its gate. The active-agent/viewer matrix, different-artifact upgrade and rollback remain open. Run `PAPERCLIP_TEST_DATABASE_URL=<owned-disposable-postgres> pnpm --filter @paperclipai/server exec vitest run src/services/native-runtime/native-runner-restart-recovery.integration.test.ts`. Previous head `f2db8a6568` had one failed workspace setup gate: [job 122555672441](https://github.com/paperclipai/paperclip/actions/runs/40608984238/job/122555672441) passes all 4,169 UI tests and 285 CLI cases (one skip), but the company import/export suite reaches its 30-second health deadline during doctor startup. Its output does not reach the server-start step. The CLI, server, database, shared, adapter and plugin trees are identical on qualification source `a866619d7b`, whose [job 122555886663](https://github.com/paperclipai/paperclip/actions/runs/40609057937/job/122555886663) passes that fixture and all 286 CLI cases. The one diagnostic retry, [job 122561057225](https://github.com/paperclipai/paperclip/actions/runs/40608984238/job/122561057225), passes the formerly failing fixture and all 286 CLI cases. All Actions checks and legacy status on `f2db8a6568` pass. Its exact-head Greptile completed at 5/5 with no open feedback. The current integrated head requires fresh checks and a completed Paperclip Review before merge. The original failure remains recorded; its exact timing cause is unproven. A repeated failure requires investigation and repair rather than another retry. All current-head CI, legacy status, exact-head completed Greptile 5/5, resolved feedback and ordinary GitHub merge eligibility remain required before merge. The latest integration preserves master’s published Copilot v70 profiles and every published migration. Checkpoint migration `0394_conscious_whizzer.sql` was generated with `pnpm db:generate` and retains the prior idempotent DDL. The Runner vendor rebuild and replay parity checks pass. Server typecheck and all 13 warm-owner variants pass after that rebuild. The imported report-lock patch is byte-identical to master; its intentional patch-context whitespace is retained, and the feature delta passes whitespace checks. No hosted experiment was run. ## Risks The pool adds up to two active connections per instance, shared across agents. Checkpoint delivery can wait behind that bound; it still requires its commit. Steady component-test Postgres CPU rises by about 1.7 percentage points of a two-CPU allocation. These corrections do not remove the stack's control and renewal writes. The migration and key must survive replacement. Fresh-database tests and local load do not establish different-artifact hosted upgrade or rollback continuity. ## Model Used OpenAI GPT-6 through Codex, with reasoning, repository tools and code execution. The runtime does not expose a more specific 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 - [ ] 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 - [ ] All Paperclip CI gates are 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
3f8149066c |
Fix connection controls for inherited hiring environments (#17944)
<!-- entire-trail-link-start --> https://entire.com/gh/paperclipai/-/trails/106/changes/paperclip/106 <!-- entire-trail-link-end --> ## Thinking Path > - Paperclip lets people hire agents and select execution environments. > - The name and adapter dialog saves an inactive draft before model connection. > - That draft can inherit its environment through a null defaultEnvironmentId. > - Managed-only and forced Kubernetes policy resolve that inheritance to an environment ID. > - The readiness gate compared the stored null with that ID and treated the selection as unsaved. > - This change accepts unchanged inheritance and keeps preparation and save-failure gates. > - People can select auth, open Advanced, and test a saved account before finishing setup. ## Linked Issues or Issue Description **What happened?** The Connect a model screen disabled all auth controls for a draft from the name and adapter dialog under managed-only or forced Kubernetes policy. Reloading did not recover it. The draft had no explicit environment, which is a valid inherited selection. **Expected behavior** Keep connection controls usable once the draft and environment are ready. Test the saved agent against its resolved environment before hiring finishes. Continue to block tests during preparation or an unsaved environment change. **Steps to reproduce** 1. Enable managed-only execution with a valid instance default, or force Kubernetes. 2. Open New agent, enter a name, and choose Claude or Codex. 3. Reach Connect a model with the saved draft's defaultEnvironmentId still null. 4. Try the saved subscription, API-key tile, or Advanced gateway. This follows #17761. The roadmap and related PR search found no existing fix for this readiness regression. ## What Changed - Accept the inherited selection when neither the draft nor the user specifies an environment. - Retain the existing preparation, loading, selection-save, and connection-test gates. - Cover Claude and Codex under managed plugin, managed sandbox, and forced Kubernetes policy. - Extend preparation coverage to both explicit and inherited environments. - Add the inherited-draft journey to the feature map. ## Verification - Hosted reproduction on Core |
||
|
|
b5b9491f95 |
test(heartbeat): cover first resume with default workspace settings (#17948)
## Thinking Path > - Paperclip manages AI agents and their tasks. > - Task continuations reuse provider sessions when effective configuration is unchanged. > - Repository projects can inherit isolated workspace defaults from a storage plugin. > - Initial workspace binding must not change those defaults. > - PR #17924 fixes policy resolution after binding. > - Its regression supplied an explicit task strategy. > - This pull request also tests unset task settings and an explicit isolated mode. ## Linked Issues or Issue Description Refs #17924 and #17447. **What happened?** On Core revision `e71a23c01c8af0e0b4cc5ac983d86886ba324239`, the first continuation of a task with an inherited repository workspace reset its provider session for `workspaceConfig`. The workspace was reused and its configuration fingerprint did not change. Session preparation runs before workspace binding. The first run resolved the storage plugin's effective project policy. After binding, `!boundSourceWorkspace` skipped that resolver and parsed the raw policy instead. This dropped inherited provider and strategy fields from the session fingerprint. The persisted change from unset task settings to `reuse_existing` and `mode: isolated_workspace` exposed this path; redundant task mode values are already normalized. **Expected behavior** Initial binding and two unchanged continuations retain the session and workspace. Real effective policy changes still reset the session. Explicit task settings and source-free tasks retain their behavior. **Steps to reproduce** 1. Configure a default storage plugin with isolated Git worktrees. 2. Create a repository project with no explicit project policy. 3. Start a task with unset workspace preference and settings. 4. Continue the task twice. **Paperclip version or commit** The runtime fix is already merged in #17924 at `0b65926822aacde48729f4b82a5c333f4cadf375`. This PR adds regression coverage on that fix. It does not duplicate or relax runtime freshness checks. ## What Changed - Run the existing repository heartbeat regression with unset settings, an explicit isolated mode, and an explicit strategy. - Assert that binding persists the expected workspace preference and mode. Each case checks two unchanged continuations and a real policy-change reset. - Make synthetic storage inspection return the branch prepared for that workspace, so generated default branch names pass the existing branch validation. - Update the session verification recipe. ## Verification - All 240 tests pass across `heartbeat-session-preparation.test.ts`, `heartbeat-workspace-session.test.ts`, `project-workspace-provider.integration.test.ts`, `plugin-workspaces.integration.test.ts`, and `plugin-fresh-workspaces.integration.test.ts`. Run them from `server/` with `node ../node_modules/vitest/vitest.mjs run src/__tests__/<file>`. - Restoring the benchmark revision's `!boundSourceWorkspace` condition makes the unset-settings case fail on its first continuation: the dispatched provider session is null. Restoring #17924 makes the complete eight-case session suite pass. - `node scripts/check-maps.mjs` and `git diff --check` pass. - Full `pnpm -r typecheck` and `pnpm build` were attempted. Both stop at Runner Rust checks because this host has no `cargo`. Full `pnpm test:run` was started, then interrupted before its first group completed. It is not counted as a pass; complete suite coverage is left to CI. A separate server typecheck also stops at the missing Runner Rust toolchain. - Initial local attempts found stale cross-checkout dependency links and sandbox restrictions on PostgreSQL/IPC. Isolated workspace links and permitted local PostgreSQL resolved those prerequisites. The first new fixture attempt failed branch validation because inspection returned a hardcoded branch; the fixture now reports its prepared branch. - Greptile scores current head `5185e5e6443e0432b205a8ef63c5c878b9b74bdf` 5/5. Its check concluded success and found no actionable issues. CI is still running. - Tests use real PostgreSQL and heartbeat persistence with synthetic provider execution. No live deployment or TTFT result is claimed. ## Risks Low risk: this PR changes tests and the verification recipe only. Runtime behavior, authorization, and configuration freshness remain owned by the existing implementation. The local full checks are incomplete as stated above. The benchmark deployment needs a revision containing #17924 to receive the runtime fix. ## Model Used OpenAI GPT-6 through Codex, with repository inspection, code editing, and local test execution. The exact serving model ID and context window 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 - [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 - [ ] 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> |
||
|
|
d40f9ac377 |
fix: enforce first-task completion decisions and retain E2E evidence (#17940)
## Thinking Path > - Paperclip lets people delegate work to agents and approve proposed work. > - The onboarding first task asks for scope, proposes a task, and waits for a human decision. > - An answer to its opening question supplies scope. It does not approve a proposal. > - Task creation already checks the saved proposal decision. > - Native completion used the general completion policy and could mark the onboarding parent Done without that decision. > - This PR checks the trusted decision before completion feedback and again when the native status is committed. > - The first task stays in review until a saved human decision permits closure. Ordinary completion and acknowledged refusal keep their current behavior. > - The Product E2E guard also retains closed scalar evidence so future failures show which boundary condition was observed. ## Linked Issues or Issue Description Refs: #17914. Profile compatibility follow-up to #17922. **What happened?** A native onboarding run can submit a valid low-risk Done result after only the opening answer. The native finalizer then marks the first task Done even though no human has accepted or rejected a proposal. **Expected behavior** The opening answer must not permit completion. A trusted saved proposal decision must permit it. A saved rejection permits acknowledgment and closure, but does not authorize new work. A later pending proposal must keep the task in review. **Steps to reproduce** Create a server-owned onboarding first task with an answered opening question, no proposal decision, and a valid low-risk completion contract. Pass a Done result through native completion feedback, the control-plane port, and the finalizer. Before this fix, the persisted status is Done. The regression expects In review. Ordinary completion and acknowledged rejection pass as controls. ## What Changed - Share the trusted latest-proposal and human-response checks with completion admission. Keep task creation acceptance-only. - Refuse premature native completion feedback. Keep an already saved premature result in review during finalization. - Check the decision again under the existing task and run locks before committing Done. - Cover accepted decisions, saved refusals, forged context, pending or changed proposals, and a real database race. - Retain a closed scalar receipt when the existing E2E pre-acceptance guard fails. Validate and display it without task content, IDs, filenames, or raw rows. Preserve the original failure, blocked dependents, and historical reports. - Include the evidence module in the journey definition hash. Bind the receipt to its exact failure code and check its closed keys against the full type. - Repair base-branch profile drift found by the full harness check: include the active Copilot v66 fixture in image hashing and update stale Pi version/hash expectations from #17922. Keep all older image inputs and strict hash checks. - Update the onboarding feature and agent access maps and E2E evidence documentation. ## Verification - Semantic regression before implementation: one failure and two passing controls on PostgreSQL 18. The failed assertion observed Done instead of In review. - The local database uses an owned disposable container with an immutable image digest. Actual migrations, feedback, control-plane port, finalizer, and status commit run against PostgreSQL. A temporary test adapter replaces only the embedded database transport because this host has exhausted its PostgreSQL semaphores. - Native control-plane suite: 55 tests passed, including 17 new controls. Existing task-creation admission: 25 passed. Existing completion feedback: 19 passed. - Credential-free E2E support: 206 Vitest suites passed, 4,407 tests passed, and two skipped. All 137 Node support checks passed. Harness typecheck passed. - The failure-receipt regression had 11 failed assertions before capture was implemented. Two failure-code binding assertions fail without their gate. Eight placement/binding cases first validate the receipt-free control, then reject the misplaced receipt. - The untouched base reproduced the three profile compatibility failures. The narrow repair passed all 83 affected tests before the full harness run. - Private workflow preparation and credential-free onboarding preview: nine compatibility checks passed. Ownership, recovery, evidence, shared-contract and workflow compatibility: 77 passed. The actual provider preview also confirms immediate success deletion, earlier declared failure eligibility, limits, and zero retries without credential access. Map checks and git diff checks passed. - Required repository typecheck passed for the product fix. The combined branch build passed. The local full repository suite was stopped after repeated PostgreSQL startup failures; a separate initdb probe confirmed host SysV semaphore exhaustion. No shared IPC resources were changed. [Hosted CI](https://github.com/paperclipai/paperclip/actions/runs/40591020873) passed the full database suites, typecheck, build, runner checks, serialized suites, and browser shards on final head `1ac4c23605a03bfd1f1f8a017b14ce29fda85f6b` (55 success, two expected skips, one advisory neutral). - Independent source review approved the product guard, atomic race regression, evidence contract, and maps with no actionable findings. Both automated reviews are 5/5 on final head `1ac4c23605a03bfd1f1f8a017b14ce29fda85f6b`; prior findings are fixed and resolved. Final CI is green and the PR is conflict-free. - No Cloud workspace, provider call, release publication, or deployment is part of this verification. These tests do not identify a historical Cloud failure or qualify live onboarding. - Local dependency installation uses the existing CI-generated lockfile from #17811. No lockfile change is included. ## Risks - Existing onboarding runs without a trusted saved proposal decision remain in review even when the agent reports success. This is the intended approval boundary. - Decision changes can race completion. The status commit checks the decision under its existing locks and uses the existing status-race recovery path. - A saved refusal permits closure only. Creation admission still rejects it. - Evidence readers reject malformed receipts and unrelated failure codes. The version-1 key registry is checked against every receipt field at compile time. Existing attempts do not gain evidence after the fact. ## Model Used OpenAI GPT-6.1 Sol (`gpt-6.1-sol`), ultra reasoning, through Codex. Used repository inspection, code execution, and collaborating coding agents. The runtime did not report a 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 references) - [x] My branch name describes the change and contains no internal ticket 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> |
||
|
|
0b65926822 |
fix(heartbeat): preserve inherited policy after workspace binding (#17924)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Follow-up runs restore saved sessions when execution configuration is unchanged. > - A project can inherit workspace policy from its storage plugin. > - The initial run resolves those defaults before it binds a workspace. > - The first bound follow-up skipped that resolution and changed the session fingerprint. > - This pull request resolves the same effective policy before and after binding. > - Unchanged follow-ups keep their saved session and workspace. ## Linked Issues or Issue Description **What happened?** A repository-backed project with no explicit workspace policy inherits an isolated Git worktree policy from its storage plugin. After the first run binds a workspace, the next run parsed only the raw project policy. It dropped the inherited provider and strategy fields. Core treated this representation change as a `workspaceConfig` change and discarded the saved session, although the workspace had not changed. **Expected behavior** Binding a workspace must not change the effective project policy. Real policy changes must still invalidate session compatibility. The workspace must keep its recorded storage owner. **Steps to reproduce** 1. Install a default project storage plugin with isolated Git worktrees. 2. Create a project with a repository and no explicit workspace policy. 3. Run a task, then submit its first follow-up. 4. Observe a session reset for `workspaceConfig` despite an unchanged workspace. **Paperclip version or commit** Reproduced on master `50b932a142216331b8d476042b454bc123739c40`. Related: #17447 fixed the separate source-free project case. A duplicate PR search found no matching repository-backed fix. ## What Changed - Resolve effective project policy for bound repository-backed workspaces through the same company-scoped resolver as initial admission. The source-free project guard remains. - Add a PostgreSQL heartbeat regression covering initial binding, two follow-ups, a real policy change, and retained provider ownership. - Settle the synthetic adapter fixture as Done and reopen each explicit follow-up. This prevents an automatic review-path recovery from hiding the first bound admission. - Add the verification recipe to the session feature map. ## Verification - The new regression fails before the production change: the first explicit follow-up receives `sessionId: null` instead of the saved session. - All six tests in `server/src/__tests__/heartbeat-session-preparation.test.ts` pass after the fix. - A targeted run across that file and `project-workspace-provider.integration.test.ts` passed 17 cases, including inherited policy, model changes, incompatible explicit policy, provider availability, no fallback after disablement, and retained local/plugin ownership. - Commands: from `server/`, `node ../node_modules/vitest/vitest.mjs run src/__tests__/heartbeat-session-preparation.test.ts`; targeted controls used the same runner with `-t 'inherited|effective model|retains both plugin and local workspace ownership|never falls back|unavailable|explicit settings|compatible explicit'`. - `node scripts/check-maps.mjs` and `git diff --check` pass. - Initial fixture attempts hit source-binding, provider-execution, missing working-directory, and branch-inspection guards. The fixture was corrected; those guards remain unchanged. An automatic review recovery also hid the initial transition until fixture settlement was corrected. - Tests use real PostgreSQL, real policy resolution, and heartbeat persistence. Provider execution is synthetic; a temporary local working directory replaces environment realization for the test adapter. - Current head `4d21b5180960659576e5950e906056fa4dabb54c` removes two comments after standard review; executable code is unchanged from the locally verified commit. Standard Greptile scores this head 5/5 with no unresolved threads. GitHub CI is now green on this head: 54 successful checks and two intentional Storybook skips. Standard Greptile and Apex both score this head 5/5. Apex found no actionable issues; no unresolved threads or merge conflicts remain. - CI job [workspaces-b](https://github.com/paperclipai/paperclip/actions/runs/40564712367/job/122406649223) was interrupted by a runner shutdown signal at 19:09:39 UTC. Its available log shows no test assertion failure; completed groups passed. The serialized server shard [1/9](https://github.com/paperclipai/paperclip/actions/runs/40564712367/job/122406648374) also received a runner shutdown at 19:12:03 UTC; its final test summary reports 532 passing tests and no failed assertion. Both interrupted jobs passed in the failed-jobs-only rerun, and the final verify aggregate passed. The first retry request was rejected while the containing run was still active; it was accepted after the other jobs settled. - Local verification is targeted as requested. Full test, build, and typecheck coverage is delegated to GitHub CI. No live deployment or latency claim is made. ## Risks Bound repository runs now read the current storage-plugin defaults through one provider-list query. An ambiguous or incompatible effective policy can fail admission instead of being skipped. Existing plugin preparation still uses the recorded workspace owner, so a changed default does not move existing storage to another provider. Explicit policy changes still rotate the session. No schema or API changes are included. ## Model Used OpenAI GPT-6 through Codex, using repository inspection, code editing, shell tools, and targeted test execution. The exact serving model ID and context window 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 - [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> |
||
|
|
f60ac29cf1 |
fix(runner): migrate Grok Build with native reasoning effort (#17922)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Harness selection maps supported agents to Paperclip Runner. > - The native Runner already supports Grok Build, but its migration mapping excludes Grok. > - Grok agents also have a thinking-effort setting that the native execution contract does not carry. > - This pull request adds the migration path and preserves explicit Grok effort through startup and resume. > - Operators can upgrade an existing Grok agent without silently losing its model, account, or effort. ## Linked Issues or Issue Description **What happened?** Existing Grok Build agents have no Runner selector or upgrade action. Adding only the mapping would route conversion through the Codex fallback and lose Grok execution semantics. Native execution also ignores the legacy reasoning-effort field. **Expected behavior** A qualified Grok agent can explicitly upgrade. The saved model, account, instructions, history, and supported effort remain intact. Unsupported legacy settings fail before saving. The provider must acknowledge the selected effort before inference. **Steps to reproduce** 1. Open the runtime page of an existing Grok Build agent on a qualified Linux x64 or macOS ARM64 computer. 2. Observe that the Runner selector and upgrade action are absent. 3. Compare the native execution input with the saved legacy reasoning-effort setting. Related work: #13882 introduced native Grok Build. #15422 covers the earlier default-runner work. This change extends the current shared selection contract. ## What Changed - Add the Grok harness mapping, qualified platform limits, upgrade action, and company-scoped computer qualification. - Translate Grok settings to ACPX without changing the selected account or explicit model. Resolve the legacy default model to the native default. Preserve the effective legacy search policy. Reject incompatible command, argument, permission, and turn-limit settings. - Add native execution input v10 for explicit Grok effort and search policy. Preserve historical schemas. Enforce disabled search through Grok requirements and bind it across startup and recovery. - Apply and verify ACP `reasoning_effort` before prompting. Bind the value to provider descriptors, checkpoints, runtime identity, and resume checks. - Use the Grok catalog and effort choices in the task composer. Apply task model and effort overrides while retaining the agent account and search policy. Update runtime controls, portability/default handling, documentation, and capability maps. - Advance Pi and Copilot source attestations for changed shared transport and recovery code. Keep historical identities intact and update all Rust integration fixtures. ## Verification - Migration and review regressions were reproduced before the fixes. Coverage includes the Grok mapping, default model, explicit effort, implicit search policy, task overrides, and incompatible legacy settings. The broad migration, route, immutable-input, and composer check passed 478 tests. The final catalog and task-input check passed 135 tests. - Runner startup, recovery, search policy, and profile checks passed 361 tests, with one platform skip. The final source-identity, search-admission, and transport event-pump check passed 89 tests. - All 757 Rust workspace tests passed for the broad implementation. After the final source attestation update, all 55 ACPX profile/session tests passed. - `pnpm -r typecheck` and `pnpm build` passed for the implementation. Server and Runner typecheck passed after the final production change. Server `tsc --noEmit` passed after the final test-fixture change. Docker context integrity, token gates, maps, generated protocol data, and replay goldens passed. - The v10 startup fixture initially used an ambient local Grok login and failed on CI. An explicitly empty credential home reproduced all four failures. The fixture now supplies a synthetic key and a private empty home. A separate case checks that missing credentials fail closed. All seven selected Grok v10 and Claude v9 startup cases pass without host credentials. - The full local suite could not complete because embedded PostgreSQL failed before database-backed fixture setup. The broad executor-suite attempt hit the same limit and was stopped. Neither attempt is counted as passing. Current-head CI must verify those paths before merge. - Earlier CI found missing Rust input fields, stale source attestations and exact fixture pins, a missing Docker context entry, and an outdated import expectation. Those failures were fixed and checked locally. The CI logs retain the original failures. - Different earlier CI runs also failed unchanged cleanup pagination, device-login timeout, and chat lost-response recovery cases. Later attempts passed the cleanup and login cases without changes to those implementations. Their causes remain unproven. The original evidence remains in [the first run](https://github.com/paperclipai/paperclip/actions/runs/40563402840), [the login run](https://github.com/paperclipai/paperclip/actions/runs/40571128328), and [the chat run](https://github.com/paperclipai/paperclip/actions/runs/40573072163). A passing retry does not establish a root-cause fix. - Both reviews rate current head `16fba9b4cdf12bc7945e6628912e79da42959f35` 5/5. All current-head CI gates pass in [run 40576580699](https://github.com/paperclipai/paperclip/actions/runs/40576580699). All 60 check runs completed cleanly, including the four intentional skips and the neutral 5/5 Paperclip review. The legacy security status is successful. No review threads remain unresolved. - Staging migration and a real shell task are pending deployment. This PR does not claim full Grok provider qualification. Reviewers can verify the operator path by upgrading a qualified Grok agent, checking its saved model and effort, and running a shell task through native execution. ## Risks - Explicit effort and search policy require the matching Runner and sidecar build. Older immutable execution inputs keep their existing schemas. - Providers that omit or reject the selected effort fail before a prompt. Unsupported effort does not fall back silently. - Existing agents retain their saved runner until an explicit change. New Grok agents use native execution only on qualified platforms. - Grok token and cost reporting remain unverified, as before. ## Model Used OpenAI Codex, GPT-6 family. The exact serving model ID and context-window capacity are not exposed in this session. Used reasoning, source editing, shell 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 and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and the focused suites pass; the full local suite has the environment limitation recorded 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> |
||
|
|
50b932a142 |
fix(server): require approval before onboarding task creation (#17914)
<!-- entire-trail-link-start --> https://entire.com/gh/paperclipai/-/trails/78/changes/paperclip/78 <!-- entire-trail-link-end --> ## Thinking Path > - Paperclip manages agent work and human decisions. > - Onboarding asks the first agent to propose a task before it starts work. > - The first-task skill requires human acceptance before task creation. > - The native tool could create and schedule that task without acceptance. > - REST task creation had the same gap. > - This change checks saved acceptance in the shared creation transaction. > - Valid approvals and ordinary delegation keep their existing behavior. ## Linked Issues or Issue Description **What happened?** An agent could create a task from the canonical onboarding first task before the user accepted its proposal. A real journey caught this after the agent read the first-task skill. A local database regression reproduces the missing check in the native tool and both REST creation endpoints. **Expected behavior** New task creation must wait for saved human acceptance of the latest ordinary proposal. A different parent or a standalone task must not bypass that check. **Steps to reproduce** 1. Bind an authenticated agent run to a server-created onboarding first task. 2. Leave its proposal unaccepted. 3. Call native `create_task`, `POST /api/companies/:companyId/issues`, or `POST /api/issues/:issueId/children`. 4. Before this fix, creation succeeds. After this fix, it is denied before a child or wake is committed. **Paperclip version or commit** Reproduced on `3be54534c24fc279533ff421e62a77ad15b72954` before the fix. ## What Changed - Add a shared check for new task creation from an authenticated onboarding run. - Read the latest ordinary confirmation across both confirmation kinds under the source task lock. - Require a human card decision or validated conversational acceptance. Require the current revision for a saved plan. - Preserve ordinary delegation, committed replay, and dispatch recovery. - Add database regressions and update execution and onboarding map documentation. ## Verification - Real PostgreSQL regression before the fix: 17 failures and four passing approval/delegation controls. No skips. - Exact published source: 102 tests passed across admission, conversational confirmation, and project tools, including all 25 admission regressions. Real Linux PostgreSQL, no skips. - `pnpm build` and `pnpm -r typecheck` passed locally. - Map checks and `git diff --check` passed. - `pnpm test:run` was attempted locally. Existing suites failed because the host exhausted PostgreSQL semaphore sets. The remaining owned test process was stopped; its failed log is preserved. No unrelated database was stopped. Current-head Linux CI passed, including build, typecheck, and browser E2E. The first CI attempt lost runners; its evidence is preserved, and interrupted jobs passed one CI rerun. - The live Cloud attempt remains failed. Local tests do not qualify Cloud onboarding, artifact delivery, or native tracing. No deployment or model retry is part of this change. ## Risks A stricter creation check could reject a valid approval. Tests cover direct, conversational, checkbox, dismissed-card, and clock-skew cases. The check applies only to new tasks from the canonical onboarding run. It does not change existing task updates, execution policy, or wake recovery. ## Model Used OpenAI GPT-6 through Codex, with tool use and code execution. The session does not expose a more specific serving 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> |
||
|
|
6e781e0ab2 |
fix(connections): preserve removed grants when saving installs (#17906)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - Connections give agents access to external tools through access
profiles.
> - Operators can remove a broad app profile and keep a limited profile.
> - Saving a connection's agent list restored the broad profile to
existing installation targets.
> - Those restored grants could permit write tools that the limited
profile omitted.
> - This pull request grants the app profile only to new installation
targets.
> - The benefit is stable permission choices when an operator edits an
installation list.
## Linked Issues or Issue Description
**What happened?**
`PUT /api/tool-connections/{connectionId}/installs` attached the app
profile to every target in the submitted list. An existing target
received the profile again if an operator had removed it. Adding an
agent, removing another agent, or saving the same list could therefore
restore broad tool permissions. The activity log recorded each restored
binding as `tool_connection.install_access_extended`.
**Expected behavior**
Targets that remain installed keep their saved profile assignments. A
removed app-profile assignment stays removed. New installation targets
receive the current app-profile defaults. Removing an installation still
removes its install-derived binding.
**Steps to reproduce**
1. Install a connection with read and write tools on two agents.
2. Give one agent a read-only profile and remove its broad app-profile
assignment.
3. Save the installation list, add an agent, or remove the other agent.
4. Check the first agent's permission to use the write tool.
Before this change, the write tool becomes allowed again. After this
change, it stays denied.
Related: #17422 adds an agent-edit permission check to direct profile
bind and unbind operations. This PR preserves removed assignments during
installation-list updates. The duplicate search found no open PR for
this defect.
## What Changed
- Attach app-profile bindings only for new installation targets.
- Preserve removed grants for existing agent and company installations.
- Keep legacy connection-wide include cleanup on every non-empty
installation save, including saves with no added targets.
- Add six PostgreSQL regressions. All six use the real install HTTP
route with a local operator fixture.
- Check effective read/write decisions, saved assignments, new-agent
defaults, uninstall cleanup, legacy-rule cleanup, and access-extension
audit records.
- Document the behavior in the connector runbook and both access maps.
## Verification
- Red: all four new regressions fail before the fix. The policy returns
`allow_profile` where the tests require `deny_default`.
- Review regression: the two legacy-rule cases fail before the review
correction. The original four cases still pass.
- Green after review: all six regressions and five existing
profile-precedence tests pass after the correction.
- Command: `pnpm exec vitest run
server/src/__tests__/tool-connection-installs.test.ts
server/src/services/tool-profile-binding-precedence.test.ts`.
- The local regression used `PAPERCLIP_TOOL_ACCESS_TEST_DATABASE_URL`
with a separate, fully migrated PostgreSQL 17 test database. Embedded
PostgreSQL could not start because the host had reached its semaphore
limit. Skipped tests were not counted as a regression pass.
- `pnpm -r typecheck` and `pnpm build` passed for the initial fix.
Server `tsc --noEmit` also passes after the review correction.
- `node scripts/check-maps.mjs`, `node
scripts/check-module-boundaries.mjs`, and `git diff --check` pass.
- `pnpm test:run` was started, then stopped after 16 tests in the
native-session suite failed during embedded PostgreSQL startup. A
focused rerun of its `collect` case confirmed the database startup
error. Direct `initdb` output reported `could not create semaphores: No
space left on device`. The full local suite is incomplete. All six new
regressions executed against the separate test database and passed.
- [Initial-fix
CI](https://github.com/paperclipai/paperclip/actions/runs/40541191695)
passed at `23253ee332b90f142e48df3f553aeaaa7f6fa298`. Greptile gave that
commit 5/5. Ponytail found the legacy cleanup gap; this revision
restores that cleanup and adds both regression cases.
- [Current-commit
CI](https://github.com/paperclipai/paperclip/actions/runs/40547366181)
passes for `729c487cf2ffaae261a820de0cf9a033a0365fd4`, including type
checks, build, test shards, and both `ci / verify` and `ci / e2e`
aggregate checks.
- The first CI attempt hit a 30-second module-import timeout in the
unchanged `issue-agent-mutation-ownership-routes.test.ts` suite. All 179
tests passed locally. One [job
retry](https://github.com/paperclipai/paperclip/actions/runs/40547366181/job/122349226221)
passed without a code change. The cause of the import slowdown was not
established. The failed attempt remains recorded in CI history.
- Greptile and Ponytail both give the current commit 5/5 with no
actionable findings. Ponytail confirms the legacy cleanup finding is
fixed. The review thread is resolved, and the PR has no merge conflicts.
Ponytail's advisory check has a neutral conclusion with a 5/5
assessment.
## Risks
- New installations retain the current app-profile defaults. Removing
and then reinstalling a target is a new installation.
- A repeated installation save no longer restores a missing profile
assignment. Operators must use an explicit profile assignment when they
want to restore that grant.
- Existing unwanted grants still require a separate access review and
repair. This PR does not change stored grants, reconnect identity
behavior, or the default access model.
- No database migration or API schema change is required.
## Model Used
- OpenAI GPT-6 in Codex, with reasoning, repository tools, and code
execution. The session does not expose the exact routed 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>
|
||
|
|
585b4e6af8 |
fix(chat): preserve deferred Retry source batches (#17883)
## Thinking Path > - Paperclip manages agent work through tasks and governed execution. > - Connected conversations retain the source and authority for each request. > - Task Retry pins the full saved GitHub input batch before it waits for cleanup. > - Resuming that wait could append an independent board queue after authorization. > - Dispatch then rejected the changed batch before the provider started. > - This pull request keeps the authorized batch intact and restores certified undelivered input from historical failed attempts. > - Each board message retains a separate turn and its own admission checks. ## Linked Issues or Issue Description **What happened?** A deferred GitHub task Retry could consume a separate board message while promoting its saved receipt. The new run then failed with `chat_failed_run_retry_not_authorized`. A second Retry could also fail because the historical run retained the mixed batch. **Expected behavior** Retry must preserve the source batch it authorized. Separate board input must keep its own execution path. Historical input may be restored only when durable evidence proves that the rejected attempt never started a provider. **Steps to reproduce** 1. Retain ten authorized GitHub requests behind a failed native turn. 2. Start task Retry while the predecessor still lacks its exact termination receipt. 3. Save an independent board message. 4. Complete cleanup and resume the same Retry receipt. 5. Observe the mixed batch rejected during dispatch. Retry that failed attempt to reproduce the second refusal. Refs #17725 for the existing saved-input Retry contract. This change repairs the later queue merge and its retained failed state. Related #17878 covers snapshot continuation and later turns in recovered directories; its workspace repair can be reviewed independently. ## What Changed - Keep deferred chat Retry promotion scoped to its exact receipt. Ordinary board Retry coalescing retains its existing behavior. - Let a new explicit task Retry restore a historical mixed batch only after strict never-started, source, ownership, allocation, board-comment and prior-delivery checks. - Preserve failed-run history and original budget-skipped receipts. Record restored queue ownership in activity. - Add production queue and HTTP-route regressions. Update the execution contract and verification maps. ## Verification - Before the repair, the deferred ten-input batch failed before identity initialization. The same regression now reaches the real initializer with the exact GitHub batch. The independent board message then reaches its own initializer in a separate turn. - Before historical recovery, ordinary task Retry refused the persisted mixed failed batch. The repair passes that case without changing the failed run. HTTP duplicate requests retain one Retry owner. An additional compatibility probe restored the old queue candidate predicate and removed all historical mixed-state fixture writes: the real producer created the exact batch and the complete historical HTTP recovery case passed (1/1). The fixed-source historical fixture now uses the production serializers. - The affected Retry group passes 86 cases on commit `325c00158df5569f5b42731cda4ecc4584909d99`, including already-coalesced external receipts. Refusals cover edited sources, active controllers, unresolved allocations, changed receipts, foreign external receipt ownership and prior delivery of either board or GitHub input, including immutable budget-skipped receipts. - Full workspace `pnpm -r typecheck` and `pnpm build` pass with these source changes. Map, module-boundary and diff checks pass. - Full local `pnpm test:run` was started. The host cannot create additional PostgreSQL semaphores; database-dependent suites fail or skip at startup. The affected database group runs against a separate migrated PostgreSQL 17.10 test database with Node 24.22.0 on macOS arm64. - The regression deliberately stops after the real identity initializer to avoid provider allocation. It proves HTTP, queue, source authorization, identity and separate continuation behavior. It does not claim a live model result, GitHub publication, deployment or recovery of the original hosted task. - Current head `325c00158df5569f5b42731cda4ecc4584909d99`: all checks are terminal with no failures or pending checks; required `ci / verify` and `ci / e2e` pass. Conditional Storybook checks are skipped. Greptile and Paperclip each reviewed this exact commit at 5/5. Both earlier review threads are resolved. Paperclip retains one optional robustness suggestion for batch ordering; the verified historical producer order remains a strict recovery contract. ## Risks Restoring input could repeat work if the prior turn had executed. The existing strict bootstrap proof rejects provider output, native state, process or controller evidence, and allocations. Restoration also checks current external authority, unchanged board revisions and other run history. An uncertain executor remains held. No migration, provider fallback or relaxation of dispatch validation is included. ## Model Used OpenAI Codex, based on GPT-6, with reasoning, repository inspection, code editing and test execution. The exact runtime model ID and context-window size are not exposed in this session. A separately shared regression supplied independent reproduction evidence. ## 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 (affected database regressions; full local suite has the host limitation described 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> |
||
|
|
2f3516f6fd |
fix(github): authenticate external contributor lookups (#17902)
## Thinking Path > - Paperclip manages AI agents and their access to external services. > - A GitHub bot connection can add external contributors by username. > - The lookup sent an anonymous request even when the bot had an App installation. > - Anonymous requests share the server IP quota and can fail for a valid username. > - This pull request uses the selected bot installation for the lookup. > - It also gives users clear errors without exposing credentials or provider response text. ## Linked Issues or Issue Description **What happened?** The Access tab could reject a valid external contributor username with a generic GitHub error. The lookup did not use the connected bot's identity. **Expected behavior** The lookup uses the selected bot's active App installation. It returns the numeric user identity or a clear account, rate limit, or installation error. **Steps to reproduce** 1. Configure a GitHub review bot and open its Access tab. 2. Exhaust the server IP's anonymous GitHub quota. 3. Look up a valid external contributor username. 4. Observe the generic rejection even though the bot has an installation. The original provider HTTP status was not retained. Source inspection proves the anonymous request. The historical cause remains unconfirmed. **Paperclip version or commit** The defect is present at `eda2a03bfe5213ffef2fbbdefdf572be775f1e14`. **Deployment mode** Server deployment with an active GitHub App bot connection. ## What Changed - Pass the endpoint ID from the existing authorized lookup route. - Issue a short-lived installation token with metadata read permission. - Reject inactive connections and invalid installation IDs without an anonymous fallback. - Distinguish missing accounts, rate limits, and installation access failures. - Add 25 lookup tests and update the connector guide and both access maps. The GitHub management service owns the provider behavior. The shared route only passes its authorized endpoint ID. The request body and response shape stay the same. ## Verification - Passed: [full CI](https://github.com/paperclipai/paperclip/actions/runs/40535979115) on `38d1ebcebb08553f159b3b81ee1bb31d1fbbba8e`, including typecheck, build, server and workspace tests, Runner checks, serialized suites, eight E2E shards, and the final verification gate. - Passed: Greptile 5/5 for the same head, with no open review threads. - Passed: 25 lookup regression tests on the final test fixtures. - Passed: 91 tests across five GitHub service suites before the fixture-only change. - Passed: `node scripts/check-maps.mjs` and `git diff --check`. - The tests exercise actual GitHub request construction with provider response fixtures. They assert the installation identity, metadata-only token request, request count, and sanitized error details. - `pnpm build` and `pnpm -r typecheck` could not complete because this environment has no Cargo executable. - Two standalone server TypeScript attempts were killed. The second ran after the full suite was stopped, with a 5120 MiB Node heap limit. The 8 GiB container recorded two OOM kills. Neither attempt produced a typecheck verdict. - `pnpm test:run` was started, then interrupted after resource exhaustion. Its first server phase did not produce a final verdict. These local attempts remain incomplete. Full CI later passed for the same head. A live authenticated bot lookup remains unverified. - The initial frozen install stopped on an existing patch configuration mismatch. Installation then succeeded with lockfile writes disabled. No dependency or lockfile changes are included. - GitHub documents installation-token support for [Get a user](https://docs.github.com/en/rest/users/users#get-a-user) without extra user permissions. ## Risks - The lookup now requires an active bot connection and a saved installation ID. - GitHub rate limits can still occur. The error keeps the retry metadata and tells the user to retry. - No database migration or permission-policy change is included. - This PR does not prove that a deployment contains the fix. ## Model Used OpenAI Codex, GPT-6 family, with code editing, tool use, and test execution. The recovered implementation was assisted by `gpt-6.1-sol`. This session does not expose its exact model ID or context window limit. ## 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> |
||
|
|
663fe667d6 |
fix(recovery): reconstruct missing native workspace obligations (#17877)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - A failed native run can still own prepared files in a remote sandbox. > - Cleanup must preserve those files before another executor can start. > - Older failure producers can omit the preservation record. > - A saved message then waits for cleanup without a recovery owner. > - This change reconstructs that record during user continuation and orphan cleanup. > - The existing worker saves the files, verifies stop, and returns input to normal admission. ## Linked Issues or Issue Description **What happened?** A failed native run retained a prepared workspace and an active sandbox lease. It had no file-preservation obligation. Cleanup protected the files. The next user message waited for a stop receipt that no worker owned. **Expected behavior** A new message registers the missing maintenance work at once. Existing orphan cleanup recovers historical saved input. Ordinary Retry remains available. Saved input can start once, after verified preservation and containment. **Steps to reproduce** 1. Persist a failed native run with an exact prepared remote workspace and its active lease. 2. Leave its finalizer terminal and unowned. Omit the workspace recovery record. 3. Send a user comment or run orphan cleanup. 4. Observe that no preservation worker starts and the comment remains deferred. **Paperclip version or commit** Reproduced on `bd382eee536f4ada680072b1cc19100163c3d04a`. **Deployment mode** Native Runner with a remote sandbox. Local verification uses disposable PostgreSQL 18 and real temporary workspace files. Refs #17788 and #17800. Those fixes preserve future deadline failures and register historical preservation on Retry. This change adds automatic recovery for new and saved messages. Refs #17839 for the separate restart-failure producer repair. ## What Changed - Register missing preservation before an authenticated continuation waits for remote cleanup. - Reconstruct the same exact-source obligation during the existing orphan lease sweep. - Notify the existing preservation worker in the registration transaction. Do not add a timer or history scan. - Test ephemeral and reusable sources, live owners, active executors, mismatched sources, rollback, lock contention, Retry and saved-input delivery. - Document the recovery contract and feature-map behavior. ## Verification - Red: both new orphan-recovery cases fail on unchanged production code. Four ownership and source negative controls pass. - Red: a new comment starts no preservation work without the admission repair. - All 461 test cases across five affected suites pass across the local runs. One existing 30-second timing case timed out under concurrent verification; its isolated rerun passed with the same deadline and assertions. - The three final-head entry journeys pass again: HTTP Retry, HTTP comment creation, and historical saved-input recovery. - `pnpm -r typecheck` and `pnpm build` pass on final head `8fab8b2ba9049f640fd884094a2007a69465e6da`. The affected server typecheck and build also pass. - The integration journey holds the provider stop reply, checks that no successor starts, preserves real files and newer host edits, and checks one saved-input successor. - Module-boundary checks, map checks and `git diff --check` pass. - Native macOS PostgreSQL cannot start because host semaphore capacity is exhausted. Database verification uses separate disposable PostgreSQL databases for each suite. An earlier shared-database attempt caused fixture interference and is not counted as a pass. - Greptile gives 5/5 with no findings or unresolved threads on `8fab8b2ba9049f640fd884094a2007a69465e6da`. All final-head GitHub checks are settled: 55 passed, two Storybook checks skipped, and one neutral Paperclip review. Full CI test, build, typecheck, Runner and browser lanes pass. No full local `pnpm test:run` pass is claimed. The fix is not deployed. This PR makes no claim of a live hosted model turn or recovery of the original incident. ## Risks - Registration grants maintenance authority only. Existing coordinator, descriptor, allocation, stop, file-receipt and execution gates remain effective. - A locked source remains held. Its one-second lock timeout does not prevent an unrelated source from registering recovery. - New preservation writes wake existing work. Settled sources produce no new recurring work. Historical discovery uses the existing orphan cleanup lifecycle and its backoff. - Provider lifecycle is simulated in local integration. PostgreSQL, HTTP routing, file export/merge, the worker and queue admission are real. - No schema, credential, model, trust, retry-budget or assignment change. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, repository inspection, tool use and code execution. The runtime does 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> |
||
|
|
b8f6d9b23f |
docs: clarify delegated connection feature and access maps (#17882)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The feature and agent access maps describe user journeys and their permission boundaries. > - PRs #17737 and #17739 added delegated connection setup across several existing areas. > - The maps include those operations, but some recipes and board-only statements are stale. > - This PR adds usable setup recipes and corrects the access descriptions. > - The benefit is a clearer verification path that preserves human and agent authority boundaries. ## Linked Issues or Issue Description Refs: #17737, #17739. Related: #17862 changes connection setup advice and catalog choices. This PR only clarifies the existing maps. **Issue type** Outdated and missing documentation. **Where is the issue?** The paired connection setup, app permissions, chat channels, model accounts, and gateway maps under `maps/`. **What's wrong?** Delegated setup guidance sits under Gotchas without a matching driving recipe. Some model-account text still groups supported account sign-in with board-only host controls. A few callback, privacy, and native admission descriptions omit important limits. **Suggested fix** Add the missing recipes. State the current route and service boundaries. Keep existing capability IDs and distinguish source review, fixture tests, and live provider proof. ## What Changed - Add paired entry points and driving recipes for delegated setup, permission changes, and managed AI sign-in. - Describe Google consent restoration, GitHub requested credential fields and saved rotation, and Vercel personal credential attribution. - Correct the Vercel callback state checks and chat conversation/test-status privacy scope. Name the separate GitHub registration handoff endpoint. - Replace blanket board-only AI login wording with the specific managed-account and host/session boundaries. - Link the five access maps to shared native admission and work-mode limits. State the permitted self-targeted policy administration boundary. ## Verification - `node scripts/check-maps.mjs` passed: 35 paired areas and 192 stable capability IDs. This checks structure and references. - `node scripts/storybook-catalog.mjs` passed. Generated output remains ignored. - `git diff --check` passed. - Eleven selected cases in `server/src/__tests__/connection-management.integration.test.ts` passed on source `db70c5acd9`, the unchanged base of this documentation commit. They use a fresh PostgreSQL database, actual agent keys/run JWTs, human sessions, and deterministic provider fixtures. The other 61 cases were not selected. - The selected cases cover connection/profile creation, Google saved choices, native API entry points, Slack caller/target policy, GitHub import and identity confirmation, durable gateway authority, AI accounts/pools, saved human handoffs, revocation, scope, trust, and Ask/Plan denial. - Read-only source reviews checked all five areas. The disposable database was removed after the run. - Full workspace typecheck, build, and test sweep were not rerun for this Markdown-only change. Live provider login and browser journeys were not run. Per-operation source-only/not-run labels remain unchanged. ## Risks Low risk. Incorrect documentation could misstate a permission boundary or imply broader verification. The changes cite the owning routes and services and retain fixture and live-provider limits. No runtime, schema, lockfile, or workflow files change. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, repository tools, code execution, and read-only source-review agents. The session does not expose a more specific 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 — existing fixtures verify this documentation-only change - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green — CI is running and Paperclip Review is queued on the current head - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups — exact head `4d16f101968d6908f90f72b6ff6ecbb79037f168` - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
bd382eee53 |
fix(recovery): explain retained source verification failures (#17773)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Workspace recovery must prove the identity of retained work before it uses an allocation. > - The verifier rejects several different contracts with the same `source_binding_invalid` code. > - A saved Retry can therefore stop before file preservation without enough evidence for a safe repair. > - Operators need a bounded observation of the selected source without another attempt or weaker guards. > - This pull request records closed failure reasons and adds an explicit read-only inspection on the run page. > - The benefit is a precise next diagnostic step while the saved work, intent, and ownership fences remain intact. ## Linked Issues or Issue Description Refs: #17741, #17053. This is a diagnostic follow-up. It does not change recovery admission or the retained-source acceptance policy. **What happened?** A retained-source recovery exhausted in `verify_execution` with only `source_binding_invalid`. Run and task diagnostics could not distinguish an invalid reference, lease policy, source binding, or reopened allocation. The normal recovery-actions read can also revalidate recovery state, so it was not a safe substitute for a current read-only inspection. **Expected behavior** Record an allowlisted reason at the rejected guard. Allow a reader to inspect one exact task/run/action without changing its attempts, saved input, receipts, or ownership. Clearly separate the recorded failure from current identity observations. **Steps to reproduce** 1. Prepare a terminal native run with a retained-source action and a lease policy of `reuse_by_environment`. 2. Attempt source verification. The guard must still reject that policy. 3. Open the failed run and choose Inspect recovery, then Inspect current source. The diagnostic should name `lease_policy_not_retained` and the allowlisted policy. ## What Changed - Split existing source-binding guards into closed reason codes. Keep each acceptance predicate and physical recovery action unchanged. - Persist validated, path-free reason/policy detail with future system recovery failures. Keep historical generic records compatible. - Add an explicit query on the existing task recovery-actions GET. Exact company/task/run/action selection bypasses read revalidation. Run selection lists at most 20 actions; inspection stops before per-lease lookup when a record has more than eight sources. - Add a manual inspection control on native export-failure run pages. Keep resolved retained actions inspectable. Show recorded failure and current recorded-source identity separately. - Update execution semantics and feature/access recipes. The shared type is the normalized server/UI contract; it contains no provider payload or secret. ## Verification - RED: the prior verifier failed both reason assertions for rejected warm policy and foreign-run lease binding. GREEN: the final focused source/HTTP, system-state, and UI suites pass 23 tests. The UI follow-up passes 8 tests after the review fixes. - HTTP tests prove exact selection, cross-company denial, resolved-action access, reused-allocation rejection, redaction, and unchanged actions, runs, leases, tasks, wakeup receipts, workspace operations, and activity. A nine-source case proves bounded inspection while the existing worker verifier still accepts all nine valid sources. - Review follow-up: show allowlisted saved detail beside a changed current observation, preserve all listed actions, and follow exact-action selection in verified/limited/error tests. The prior component fails the saved/current drift regression in an in-memory RED control; the current component passes. UI typecheck/build pass again. - `pnpm -r typecheck` and `pnpm build` pass. Token gates, maps, module boundaries, and `git diff --check` pass. - Rebased onto master `46de15ff4b` without conflicts. Range-diff proves both diagnostic commits are unchanged. On new head `a7e2bc87fcea75e76b6b736304d1287257f71174`, all 23 focused tests, full typecheck/build, token gates, maps, and module checks pass again. Both fresh reviews are 5/5 with zero unresolved threads. Final exact-head GitHub status is CLEAN: 55 success, 2 skipped, 1 neutral, no pending checks or failures. The [ci / verify aggregate](https://github.com/paperclipai/paperclip/actions/runs/40387002325/job/121802415824) passed in eight seconds. All test/build/typecheck/E2E lanes passed. - Existing full workspace recovery suite: 56/56 pass (103.5 seconds) before the byte-equivalent rebase. `pnpm test:run` hit repeated embedded PostgreSQL initialization failure before database-suite assertions and was stopped. No full local suite pass is claimed. The owned external `_test` database provided the focused HTTP/source verification. The prior browser attempt also stalled at Network.enable before its click; that attempt did not establish browser acceptance. - Current-head local browser acceptance passes through the actual run page: Inspect recovery lists the exact action, Inspect current source shows recorded generic failure separately from the current rejected policy, and reload resets inspection to the explicit control. Explicit selection works again after reload. The app used isolated data, an empty inherited environment, a paused synthetic agent, and no provider credentials. Final state remains failed/exhausted with zero attempts, zero wakeup receipts, zero workspace operations, and unchanged original generic failure. The local app and temporary tab were stopped. This proves the diagnostic journey, not the deployed source's actual lease policy or its recovery. - Final merge verification at `a7e2bc87fcea75e76b6b736304d1287257f71174`: GitHub reports CLEAN and mergeable. Both repository-required checks, `ci / verify` and `ci / e2e`, pass, as does the exact-head Greptile check (5/5, zero unresolved threads). The separate [Entire trail](https://entire.com/gh/paperclipai/paperclip/trails/7) has no recorded reviewer approval; no such approval is claimed. It is not a configured GitHub merge gate. - Initial local setup failures were distinct from product assertions: localhost sandbox EPERM required scoped local access; a browser harness import path was corrected. A test UUID type inference error and historical native-export UI selection gap were corrected before the green run. The live task remains blocked; this diagnostic does not claim it recovered. ## Risks - This change improves evidence. It does not prove provider termination, local descriptor integrity, or successful file preservation, and it does not repair the original source. - Current inspection spans multiple database reads. It is an observation, not a historical cause or execution authority. It performs no provider/filesystem calls and starts no retry or executor. - The optional persisted detail is backward compatible. Unknown values and extra fields are excluded. Oversized source lists remain uninspected through this explicit diagnostic path; physical recovery rules do not change. ## Model Used OpenAI Codex based on GPT-6, with code execution and browser tools. The exact serving model ID and context window were 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> |
||
|
|
0c9d10d695 |
feat(connections): complete saved setup guidance and coverage maps (#17739)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Product and agent access maps describe the same capability IDs. > - Agent connection management changes the callable operations and permission boundaries. > - Reviewers need an operation inventory that distinguishes API access, human handoffs, and fixture evidence. > - This pull request adds saved setup screens and updates the maps for #17737. > - The benefit is that users and contributors can inspect the coverage and remaining boundaries. ## Linked Issues or Issue Description **Subsystem affected** Product and permission documentation, saved authentication setup UI and consent metadata, and product/agent access maps. **Problem or motivation** The current maps describe board-only management paths. They need to match delegated connection management and distinguish administration from ordinary tool execution. **Proposed solution** Record route operations, required grants, responsible-user limits, transport, saved authentication handoffs, provider-fixture evidence, and explicit local-operator boundaries for every connection family. **Roadmap alignment** This is the documentation companion to #17737. It covers existing Connected Apps, governed MCP gateways, chat channels, and personal/shared AI accounts. It uses existing server setup operations and adds their saved handoffs to the existing UI. ## What Changed - Show saved AI sign-in and connection setup handoffs in the existing UI. - Open GitHub import and rotation links at the required human step. Resume a committed rotation after reload without asking for another secret. - Restore saved Google service choices for the addressed user while preserving newer consent. Successful direct/cloud consent records its own timestamp, independently of refresh or lease writes; existing refresh paths preserve it. - Update product, implementation, and permission-default documentation. - Reconcile app permissions, connection setup, chat channels, profiles/gateways, and model account coverage. - Use matching capability IDs in the product and agent access maps. - Label source-reviewed operations separately from fixture-tested operations and live provider setup. - Preserve catalog creator attribution under the responsible user, with the actual agent still recorded. This follow-up moved from the implementation to keep both reviews below 100 files. This companion now changes 38 files, including the preserved Vercel personal-credential and OAuth callback attribution follow-ups alongside consent and catalog ownership. - Name the addressed-human browser-session and consent step for Slack managed authorization and installation. Preserve source-only evidence for those individual operations. ## Verification - Current companion head: `04d40cdd605452d91cf4931476eb292a210825af`, including implementation `2ecd6451d0` and master `ea727dc3c2`, 38 files. All intended companion files survive: 35 are byte-identical to the previous companion; two chat maps and qualification add current evidence. Exact-head Superagent passed and Paperclip Review supplied an actual neutral5/5 assessment with no findings and explicit no-independent-runtime/live/current-CI verification limits. Exact-head Greptile also completed at5/5 with no findings; both formerly failed shards and their verification aggregate passed on attempt2; full exact-head Linux CI workflow40446969603 completed SUCCESS. All current checks and statuses are terminal clean, with no unresolved findings. This PR remains dependent on #17737 and needs fresh checks after its required post-squash replay. The preceding 605 head’s reviews are historical after this update. Older b0ea Linux workflow success after its single rerun also remains historical. - Earlier preserved-stack verification passed **2,165 tests**: 70 assembled-server actual-auth scenarios, 27 OpenAPI contracts, 2,022 native API tests and 46 saved GitHub wizard cases in fresh PostgreSQL. The parent also passed **141 existing gateway/policy tests**. Workspace typecheck/build, maps and token gates passed. The initial typecheck IPC denial and all material intermediate regressions remain in the qualification record; no full local sweep or live provider setup is claimed. - Operation maps now cover issuer/target gateway policy intersection and post-approval revocation, bounded activity pagination through private-only windows, and native local-login encrypted receipts. The companion preserves the Vercel OAuth callback ownership change with its existing credential ownership follow-up. - Parent CI has one retained connection-intent e2e failure from a periodic-recovery timing race. GitHub refused the first job-rerun attempt while its workflow was nonterminal. Once completed, the single failed-job rerun was accepted as attempt 2 and passed, including the full parent Linux workflow. - Companion Linux server shard 4/12 retained a cleanup-idleness timeout in `login-cleanup-work.test.ts` (active work was still 1 after its five-second wait). The same unchanged cleanup suite passed all 16 cases in the parent Linux job 121950185096 and all 16 cases locally against a fresh disposable PostgreSQL database. Relevant cleanup/reaper/scheduling runtime code is unchanged. The single unchanged-code failed-job rerun was accepted as **attempt 2** on the previous `b0ea3c940f` head (workflow 40431671705). The failed shard and complete Linux workflow passed on attempt 2; no additional unchanged-code rerun was used for this failure. The first local attempt failed the existing dedicated `_test` database-name guard before running tests; the correctly named fixture passed without weakening the guard. - **Earlier 82 GitHub UI tests passed**. All three new replacement cases were red before the fix. A confirmed unchanged generation preserves the earlier copy; a changed or unreadable generation blocks copying and reconnecting. An explicit status check can restore the copy when it is still current. All earlier import, rotation, verification, and retry states remain covered. - The complete stack passed **82 API/OpenAPI tests** in fresh PostgreSQL, including 55 scenarios with real agent keys, run JWTs, human sessions, production defaults, persistence, and deterministic providers. The parent also passed **60 Copilot installation tests**, preserving published v62 and binding combined guidance as v63. - **Earlier 10 focused Google/OAuth tests passed**: eight picker cases and two local-HTTP protocol cases proving consent metadata survives concurrent token refresh. The refresh and legacy UI cases were red before the fix. These protocol fixtures use the existing injected board actor and do not count as agent-authenticated proof. - Workspace typecheck/build passed after the consent change; normal migration generation reported no SQL changes for the additive JSON metadata. The parent's latest caller-authorization correction passed server typecheck/build. Map validation and token gates passed. Maps cover 35 areas and 192 capability IDs. The specification names migration `0380_broken_aqueduct.sql`. - The test-call operation maps now record the full caller/target tool access decision (profiles, policies, and explicit grants), credential identity for every auth label, approval, and rate checks. The profile-only precondition was removed after the new permitted-access cases failed; those cases and the no-auth identity regression now pass. Saved test status requires its originating principal and current linked-task access; actual key/JWT privacy-denial evidence is recorded. - Tool-connection activity is now operation-verified: 100 events over two tasks require two capability decisions and at most two run captures (previously 100/102), preserve private-event filtering, and deny the next request after audit revocation. The regression was red before the fix. - Cloud enrollment creation and callback entries now name instance-administrator and company/principal checks. The callback is a browser return with HTML or a 303 redirect. Status reads retain their separate board-actor rule. - Operation maps identify the API, transport, authorization, evidence, and human/operator boundaries. Structural checks do not establish live provider behavior. Earlier failures and fixture corrections remain in `doc/plans/2026-10-13-connection-api-parity.md`. - An earlier companion head (`26edbe17`) received an actual Paperclip Review assessment of 5/5 with no actionable findings, published with neutral status. That review did not run tests or confirm CI, and it is historical for this new head. The prior incomplete execution result is not counted as a passed assessment. Fresh review remains pending. The duplicate enrollment findings have explanatory replies and are resolved. - The latest implementation correction passed all 55 actual-auth scenarios and 27 OpenAPI contracts (separate commands). It repairs unavailable old credential material, preserves fresh import versus configured reconnect links, and distinguishes credential field sets/completion modes in handoff keys. The new fresh-link and collision cases were red before the fix. All 41 GitHub wizard tests now pass, including filling the fresh saved handoff and asserting App import rather than reconnect; UI typecheck, maps and token gates also pass. Qualification retains the earlier failures and an incorrect OpenAPI filename that selected only the integration module before the correct separate contract run. - Configured GitHub credential-entry links carry canonical requested fields and all/any mode. The form displays and submits those values through human reconnect while retaining other saved credentials. Two webhook/client-secret cases were red before the fix; combined all/any and legacy-link cases also pass. The current UI fixes the old |
||
|
|
0cb3fc7db5 |
fix(runner): retain ACPX transport failure details (#17837)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Paperclip Runner reports provider failures to the execution and recovery services. > - Those services read the terminal event's structured `error` field. > - The ACPX transport-failure path wrote its code and message only at the top level. > - The session facade therefore replaced that cause with `error: null` and the generic message "Provider turn failed". > - This pull request uses the existing structured error contract while retaining the old fields. > - Recovery can retain the actual redacted cause without reopening the failed provider or assuming a retry is safe. ## Linked Issues or Issue Description **What happened?** A native ACPX run can lose its failure details between runnerd and the session facade. The transport-failure producer emits a failed turn with top-level `code` and `message`. The facade reads `error`. The server receives a generic provider failure and cannot use the original cause to explain or classify recovery. **Expected behavior** Retain the transport code and redacted cause in the structured terminal error. Keep failed sessions closed, provider termination unproven, and automatic replay disabled. **Steps to reproduce** 1. Open a native ACPX session and start a turn. 2. Send malformed activity from the sidecar after it acknowledges the turn. 3. Poll the native provider events. 4. Observe that `turn.failed.error` is absent even though the producer has a transport code and cause. Refs: #16366, #17543. Those changes cover legacy process-session diagnostics and session-ensure errors. This change repairs the native ACPX polling terminal contract. ## What Changed - Add the existing transport code and redacted message to the terminal event's structured `error` field. - Mark that error as non-recoverable. Keep the previous top-level fields for existing readers. - Add a real sidecar fault fixture and a native-provider regression. It checks one failed terminal, retained error details, a closed session, and no provider reopening. - Document the failure contract and verification scope in execution semantics and the recovery map. ## Verification - Red: the new fault test failed because the structured transport error code was null on the original code. - Green: all 26 native-provider integration tests pass with the fix. - Three session-facade terminal tests and three native-runtime provider-failure classification tests pass. - `pnpm -r typecheck` and `pnpm build` pass. - Hosted test partitions, native Runner checks, typecheck, build, browser shards and canary passed. Two final aggregate jobs received no runner for several minutes. The first CI attempt was cancelled after saving its status, and only those two cancelled jobs were resubmitted. Both aggregate jobs passed on attempt 2. The current head has 55 successful checks, four expected skips and successful Snyk status. - `git diff --check`, `node scripts/check-module-boundaries.mjs`, and `node scripts/check-maps.mjs` pass. - The full local Vitest suite is not run for this patch. The local filesystem fell below 500 MiB free during verification. The preceding full-suite attempt crashed embedded PostgreSQL; focused checks and CI are used without claiming that attempt passed. - Live incident: verified the exact predecessor sandbox was destroyed and workspace recovery completed. An audited user retry through the normal task-retry service started one new native run. That attempt preserved the original question but failed before provider startup with a missing workspace-sync descriptor binding. The startup race is fixed separately in #17838. A later audited retry completed successfully, saved its useful answer and restored its workspace. The agent API handoff failed; an audited operator repair through the normal issue service completed the required user assignment in Review without repeating the comment or provider work. This verifies recovery admission on the existing deployment; the new Runner change is not deployed yet. - Evidence limit: the historical terminal had `error: null` and its raw sidecar frame was not retained. Fault injection proves this producer defect and the same loss of diagnostics. It does not establish which transport fault caused the historical turn to end. ## Risks - Recovery now receives a specific transport failure code. The error remains non-recoverable and `providerTerminalObserved` remains false. Stop proof, effect reconciliation, workspace preservation, retry limits, and normal execution authority still govern any successor. - This change preserves diagnostics. It does not make a malformed or lost provider connection healthy. - No schema migration, credentials, provider selection, or model settings change. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, source inspection, tool use, and code execution. The runtime does 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> |
||
|
|
94819b6ded |
fix(recovery): preserve live heartbeat preparation ownership (#17838)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Heartbeat prepares each run before it starts the native provider. > - Startup recovery can run while that preparation is still active. > - The native input and coordinator exist before workspace synchronization saves its descriptor. > - Recovery checked the later native executor registry but missed the earlier heartbeat execution registry. > - It could claim the live run and dispatch a second executor against incomplete workspace state. > - This change gives the recovery claim the existing live heartbeat registry and checks it before changing ownership. ## Linked Issues or Issue Description **What happened?** Startup recovery can claim a native run that the same server is still preparing. The second execution reads the admitted native input before workspace synchronization has saved its descriptor. It fails with `native_workspace_sync_descriptor_binding_missing`. The original preparation then finds a failed run and cannot start the provider. **Expected behavior** Leave live preparation with its current executor. Do not change its native coordinator or dispatch another executor. An inactive run must still pass the existing recovery checks. **Steps to reproduce** 1. Start heartbeat runtime selection for a remote sandbox. 2. Hold workspace synchronization after native input and coordinator persistence. 3. Run native startup recovery with the heartbeat execution still active. 4. Observe an unintended `bootstrap_incomplete` claim and a second execution. Refs #17439 for broader remote controller recovery. This change repairs the current heartbeat startup race. It does not add checkpoint storage or remote adoption. A separate diagnostics correction is in #17837. ## What Changed - Pass the existing heartbeat live execution registry to native recovery claims. - Check the current registry after locking the run and before any takeover or coordinator change. - Return the existing waiting disposition for live preparation. Keep workspace descriptor validation unchanged. - Add a PostgreSQL regression at the real runtime-selection boundary and an assembled heartbeat recovery regression with the real claim service. - Document the preparation interval and its recovery behavior. ## Verification - Red: the new runtime-selection test observed an unintended bootstrap claim on the original code. The heartbeat regression also failed because recovery dispatched the live run. - Green on current head `88bec51f10d61eb851eec849e82a80bb198555c7`: all 144 runtime-selection, heartbeat recovery, workspace-preparation and restart-policy tests pass. - These cases check an unchanged coordinator, no duplicate recovery dispatch, a running source run, and normal recovery after the execution leaves the registry. - The full native restart integration file passes all 22 available cases. Nine real-runner process cases are skipped because local Runner test binaries were removed to recover disk space. The passing cases include remote startup, old preparation fencing, ownership conflicts, Stop, and concurrent recovery. - Direct full server TypeScript check passes: `pnpm exec tsc --noEmit -p server/tsconfig.json`. Hosted CI passes on this head, including full test partitions, typecheck, build, native Runner checks, serialized suites, browser shards, canary and both aggregates. Apex is 5/5 with no actionable findings. The current head has 54 successful checks, two expected skips and successful Snyk status. - `git diff --check`, module boundary checks, and map checks pass. - A wider local safety run stopped with PostgreSQL error 53100 and ENOSPC after 64 tests passed. Recursive typecheck also stopped with ENOSPC. These attempts did not pass. Generated files in this worktree were removed to free space. The full local test suite and build have not been run for this change; hosted CI must supply those results. - Live evidence: a production startup recovery claimed a new run during outward workspace staging. The second preparation failed before provider startup. Its exact sandbox was later destroyed with successful cleanup. The patch is not deployed. A later audited retry on the existing deployment completed successfully and saved the requested answer once. An audited operator repair through the normal issue service completed the final user assignment in Review after the agent API handoff failed. This acceptance verifies recovered work, not deployment of the new guard. ## Risks - A live heartbeat remains responsible for its own completion and cleanup. Recovery must not compete with it. The registry is process-local; existing durable ownership checks still govern other controllers. - An executor that is still active remains protected until its cleanup removes its registry entry. This adds no timer, polling loop, schema or credential change. - Missing or corrupt workspace descriptors still fail closed. This change does not authorize replay of unknown provider actions. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, source inspection, tool use and code execution. The runtime does not expose the exact serving 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> |
||
|
|
db32bdf98b |
fix(github): recover review replay and preserve passive summaries (#17726)
<!-- entire-trail-link-start --> https://entire.com/gh/paperclipai/-/trails/8/changes/paperclip/8 <!-- entire-trail-link-end --> ## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - GitHub tools save review assessments and publish their confirmed receipts. > - A timeout before publication staging can leave an invocation with no saved publication. > - Exact replay must repeat only the authorized preflight and converge on one publication. > - PR requests also share an App-owned summary comment. Progress and maintenance must preserve its final content. > - A native turn can intentionally wait for an author without sending another reply. > - This pull request repairs unstaged replay and prevents queued or passive-wait notices from replacing a published assessment. ## Linked Issues or Issue Description Related repairs: Refs #16883, Refs #16284, Refs #16275 recover saved publication receipts. Refs #17183 covers unavailable approved replay output. Refs #17714 fixes a separate publication lock-order problem. **What happened?** Exact review retries can return null `begin_review` output or `github_publication_unavailable` after an upstream read times out before publication staging. Separately, response maintenance can replace a completed PR assessment with “Review queued…” or a generic missing-response notice after an authorized no-new-work reply. The latter run can correctly commit a passive wait while its external summary is still overwritten. **Expected behavior** Exact retries repeat only the authorized preflight. A saved or uncertain publication keeps its existing recovery owner. Queued acknowledgements preserve final App-owned summary content. A committed native passive wait settles its current acknowledgement without writing a response or treating an old summary as a new-run reply. Success before presentation remains held until a durable decision exists; exact current-run confirmed receipts can retire their placeholders. Genuine missing/error responses retain fallback handling. **Steps to reproduce** 1. Hold a GitHub metadata read until an authorized gateway call times out before publication staging. Repeat the exact request. 2. Publish a valid PR assessment. Send an ordinary author reply that asks for no new work and no duplicate comment. 3. Commit the native `response_wake` with a no-comment server presentation decision. Run response maintenance twice. 4. The base returns the invalid replay result or replaces the assessment with progress/fallback text. **Paperclip version or commit** Replay regression: `41c42895fa862c586ff841f8c50200d93ffc83a4`. Maintenance regression: the previous PR head `c7553d2325df53d98d9febff7023ade4b1e704eb`. Both use real PostgreSQL and simulated GitHub responses. The maintenance failure was also observed in normal hosted use. **Deployment mode** Source checkout on macOS arm64 with isolated PostgreSQL 18, followed by a dedicated QA qualification. No production rollout is included. ## What Changed - Route exact `begin_review` replay through its typed owner. Repeat unstaged preflight only with the complete request digest and no successful invocation result. - Preserve current policy, immutable assessments, unique action keys, receipt recovery, and provider leases. - Preserve a verified App/marker-owned final shared PR comment during acknowledgements. New canonical assessments can still replace it at the same or a new head. - Project only a bounded server-committed native wait decision. Settle the current main-PR acknowledgement without provider writes or a fabricated current-run reply receipt. - Hold succeeded native runs while presentation is undecided, including the committed-before-presentation window. An exact current-run confirmed receipt can still retire its placeholder. - Keep missing/error fallback and uncertain publication checks. Update the bot guide, execution semantics, maps, and real-database regressions. ## Verification - **Causal RED:** exact begin replay returned null; exact unstaged submit replay returned unavailable. The new real-database maintenance test then reproduced the exact generic summary overwrite. Its first repair also exposed an earlier queued-acknowledgement overwrite. Both publication boundaries are repaired. Four additional ordering regressions reproduced the generic PATCH while native presentation was undecided; the corrected tests hold until the same row settles. - **Local GREEN:** 196 complete GitHub workflow cases pass on an empty migrated PostgreSQL fixture. This includes queued/running preservation, both success-before-presentation windows, null/scalar/invalid decisions, exact-current versus predecessor receipts, durable acknowledgement settlement, repeated no-op maintenance, eventual genuine missing/error fallback, pending writes and same/new-head canonical replacement. Workspace typecheck, exact-head build, maps and whitespace checks pass. The real database respects the actual selected-column projection. - **Command:** `PAPERCLIP_TEST_DATABASE_URL=<owned-postgres-18> pnpm --filter @paperclipai/server exec vitest run src/__tests__/chat-channels.integration.test.ts -t 'GitHub agent review workflow'`. - **CI/review:** historical heads `c7553d2325df53d98d9febff7023ade4b1e704eb` and `4d00d3af6f2ccbda8f38a98f81d392d82dd3c59c` had Greptile 5/5. Final readiness head `2d267f1e4aa0b835a11aede97798fbd800d9cd96` passed independent source review with no actionable finding and fresh Greptile 5/5 with zero unresolved threads; all 54 check runs pass with 2 intended skips; Snyk is successful and the merge state is CLEAN. The dedicated QA destination acceptance also passed. - **Full-suite limitation:** the earlier `pnpm test:run` attempt produced no final summary. Its retained log reports failures in unchanged workspace-runtime tests and 15-second gateway-audit and stale-question timeouts. Their cause remains unknown. Do not treat the targeted results as a full local-suite pass. - **Live evidence and limits:** normal native OpenCode/DeepSeek review delivery published a useful assessment, inline finding and App check at the exact reviewed head. A separate ordinary author reply delivered a useful answer and settled. Those are ordinary delivery proofs, not live injected-timeout proofs. A later no-new-work reply exposed the maintenance overwrite. The final combined source `070e9c4ead9341cd497b23f533a91bf194475e79` includes the exact publication repair and passed normal review → ordinary author reply → quiet destination acceptance. A normal current-head review restored the legitimate assessment; the ordinary no-new-work reply then committed a passive wait without new GitHub tools. The same 1,436-character summary stayed identical while queued/running, after terminal settlement, and more than 3 minutes 50 seconds after successful cleanup. Review rows and receipts stayed unchanged, with no owner, live run or queued input. The timeout fault fixtures prove replay and single-publication safety. The historical first upstream timeout producer remains unknown. The live board reads do not expose the raw acknowledgement action row: its terminal cancellation and next-pass no-op are real-PostgreSQL fixture proofs, while the hosted checks prove actual destination stability. The hosted journey did not inject a timeout or pause the terminal/presentation writer window. Private destinations, raw receipts and internal task identifiers remain outside this PR. ## Risks - Original and repeated metadata reads can overlap. The immutable assessment, action uniqueness and publication lease must remain authoritative. - Missing complete request identity or a deleted completed receipt remains held. The gateway does not reconstruct receipts or relax approval. - Passive suppression requires actual native mode/committed phase, current source ownership and the server's no-comment decision. It applies only to the main PR review surface. Uncertain current writes stay held; other surfaces keep normal placeholder retirement. - There is no migration, credential change, dependency or new retry scheduler. ## Model Used OpenAI GPT-6.1 Sol (`gpt-6.1-sol`) in Codex assisted with diagnosis, implementation, tests, and source review. It used reasoning, repository tools and code execution. The context window size is 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> |
||
|
|
208a093d19 |
fix(chat): preserve resumed review waits and retry newer saved input (#17725)
<!-- entire-trail-link-start --> https://entire.com/gh/paperclipai/-/trails/36/changes/paperclip/36 <!-- entire-trail-link-end --> ## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - GitHub review agents publish findings and wait for an authorized reply or head change. > - Review tools could retain the requester after resume while completion lost that same wait proof. > - A yielded report could then queue its own continuation or repeat a missing-wait error. > - Ordinary Retry could also select an older failed turn while a newer saved request had no admission. > - This change shares the existing authority proofs and canonical admission owners. > - Current access, publication, execution and budget gates remain required. ## Linked Issues or Issue Description Refs #17318. Builds on the canonical saved-input retry owner in #17733. Related #16550 covers deferred legacy comments after ownership waits. The separate recovery repair in #17724 owns the cleanup-to-saved-input handoff; this PR does not add a second admission owner. A resumed review could publish an assessment, then turn its `response_wake` into an immediate `issue_status_changed` wake. A provider that omitted its continuation could instead repeat a completion error. A newer linked-human message saved during a budget hold could also remain unstarted because Retry selected the older failed source. ## What Changed - Resolve passive review waits through the accepted requester ledger used by GitHub tools. Require the latest reviewed head, exact company, task, agent, repository and processed publication under current access. - Fill omitted/null yielded continuation from that server proof. Permit an inherited normal tree resume only through its accepted parent identity. Permit an ordinary follow-up only after this run has a processed useful reply linked to its exact inbound message. Reject acknowledgements, partial assessments, pending or uncertain writes as that reply proof. - Recheck the same run/review/head/source proof during feedback, finalization and final status commit. Preserve explicit malformed-input rejection and Done policy. Add no monitor permission or publication grant. - Keep heartbeat and publication projections narrow. Preserve both published Copilot v62 identities and generate source-bound v63 from the pinned merged base. No v63 live qualification is claimed. - Certify the structured isolated-directory binding failure only at its pre-allocation boundary and only through canonical task Retry. Other workspace validation reasons and unknown effects remain denied. - Route Retry to eligible newer saved input through the existing canonical owner. Preserve the old result and skipped receipt. Require current principal, source, App, runtime fence, budget, native ownership and exact cleanup proof. - Recover absent historical App metadata only through an earlier trusted processed response receipt and an immutable non-null endpoint claim. Explicit malformed or conflicting metadata stays denied. - Revalidate execution through the exact claimed wake, coalesced task Retry and resolved user-continuation receipt after admission. A second normal Retry can recover the exact never-started authorization failure with unchanged saved input. Require empty execution evidence, exact diagnostics and no allocated or active executor. - Explain when a recorded result prevents exact replay. Ordinary board Retry directs a new task message to continue from saved work. Inherited requester identity alone never grants replay. - Keep accepted board-message preparation failures with the canonical task Retry owner. Certify the exact unchanged comment, original user wake, accepted same-user identity and absence of provider execution. Pin that source, recheck it at admission, and bind identity initialization to the coalesced intent and exact claimed successor receipt. Uncertifiable sources retain an actionable fresh-message refusal. - Return safe named authority categories for board Retry refusals. Update execution documentation and capability maps. Add no schema or polling loop. ## Verification - A fresh external review request exposed a separate isolated-directory preparation failure before allocation. Its first normal Retry saved an intent but admitted no successor. This follow-up certifies only that exact structured preparation boundary through the existing canonical Retry owner, with trusted failed settlement and no executor, lease, result or output. A real HTTP/queue regression reproduces the missing successor before the repair. Twenty-three current-source safety cases and the final 98-case Retry/HTTP group pass, including a fresh click after a denied intent, source revocation, accepted results and the older direct API remaining denied. The warning case uses actual configuration preparation and production event append; unknown warning shape or provider provenance stays denied. Full workspace typecheck, build, maps and diff checks pass. Renewed hosted normal Retry now succeeds on the final combined source: it preserves the exact saved request and linked requester, starts one native successor in a fresh attempt workspace, publishes the current-head 2/5 assessment and commits In review with passive response wake. - A later hosted normal Retry published a low-score assessment but lost its accepted source identity because the previous attempt failed before identity initialization. It repeated continuation errors, then submitted Done. This is failed acceptance, not a successful qualification. The initializer now retains the exact source only after execution-time failed-chat Retry authorization; generic Retry and Done policy are unchanged. A real queue/initializer regression fails with a null source on the previous code and passes with the newer saved source. Two real database completion cases verify that source yields the authoritative wait and commits In review. Renewed hosted normal Retry now retains the accepted source and exposes the authoritative current-review wait. It completed after two semantic feedback corrections (wrong contract revision, then wrong criterion IDs); the correct contract was present in emitted input. The third finish was accepted and committed In review, with no missing-wait loop or Done escalation. - Repeated board-message preparation failures now walk their canonical intent, failed dispatch and accepted parent identity, rechecking each contained predecessor. A production queue regression fails the second ordinary HTTP Retry before the repair and passes afterward. Changed source, contradictory execution evidence and cyclic receipts remain denied; traversal stops after twenty links. - New inherited omission cases failed before the repair. The final full PostgreSQL 18 wait/status suite passes **252 tests** under Node 24.22. It covers omitted/null input, malformed-first recovery, same-head resume, exact-source replies, changed heads, revoked access, pending/uncertain/mixed publications, final commit revalidation, no duplicate review and no self-wake. - **15 existing publication tests passed before the pinned merge** on a separate fresh database. They retain default partial-delivery and failure-fallback behavior. Context reads remain below the unchanged 16 KiB heartbeat and publication response limits with large saved output present. - Saved-input tests cover a real signed PR webhook, production accounting-budget refusal, normal policy recovery and canonical Retry. Historical producer-shaped tests prove the missing-App case red, then check trusted prior receipts and malformed, late, revoked or mismatched proof. A broader order-coupled test was reproduced on the prior source; its global fault injector now targets its own authorization query. The 43-case sequence passes without changing production behavior or its safety assertions. - New signed-ingress and real heartbeat execution tests reproduced the admitted-successor failure, then the next normal Retry failure. The final pinned merged source passes 249 full GitHub review/publication and Retry cases on a fresh database, including all 49 saved-input cases. A separate 74-case Retry/HTTP run also passes. Exact dispatch negatives cover source, company, agent, task, successor, receipt, pause, assignment, accepted success, controller and cleanup proof. Bootstrap contradictions remain denied. The canonical Retry suite passes 16 cases through its supported external PostgreSQL test connection. - The normal board HTTP route reproduced the unusable inherited-result refusal. It now returns actionable guidance without starting a successor. The actual UI Retry hook and banner tests pass 12 cases. - A production-shaped accepted board comment followed by a pre-provider qualification failure reproduced HTTP 409 before the repair. The final real HTTP/queue test certifies one canonical successor and preserves the accepted identity. It rejects changed source, actor, task, agent, result, controller, process, profile, allocation and receipt evidence. A post-acceptance source change keeps the same intent pending. Execution revalidation rejects removed or mismatched proof. The probe stops deliberately after production identity initialization; it does not claim provider execution. The final source passes the 75-case Retry group, the focused two-case board/inherited-policy group and 19 canonical Retry cases. Full workspace typecheck, build and map checks pass. - Full workspace `pnpm -r typecheck` and `pnpm build` pass. Map, module-boundary and diff checks pass. Full local `pnpm test:run` remains unverified. The 256-case explicit-native suite cannot initialize its packaged PostgreSQL because libzstd is absent; an existing command-scoped fallback did not resolve it. Current-head remote full-suite checks are required. Merged-source full GitHub+Retry (249), separate Retry/HTTP (74), full wait/status (252), profile/history and completion (75), and visible Retry hook/banner (12) checks pass. The fresh owned PostgreSQL 18 databases applied all 377 migrations. - Actual Rust Runner, OpenCode 1.18.34 and exact DeepSeek used unchanged production-generated synthetic contexts. Resume finished with an explicit server wait. The author-reply trial omitted continuation twice: its first report failed the existing empty-criteria check; the corrected second report still omitted continuation and received the exact server wait. It completed once with no missing-wait loop or Done escalation. Controller acknowledgments were synthetic; these probes do not establish hosted publication or board state. - Hosted combined testing proved automatic admission of the exact saved author reply, a useful GitHub answer and committed passive wait. It required two malformed-continuation rejections before a nullish fallback succeeded. A later normal Pause/Resume completed in one finish with explicit response_wake and no new review/comment. The admitted normal Retry then exposed the execution guard gap repaired here. Those remain checkpoint results. On the final combined source, renewed normal Retry completed actual native provider work and GitHub publication, committed the passive wait, released ownership and cleaned up its environment. A subsequent ordinary unmentioned author reply woke once, made no GitHub tool calls or new assessment, and completed its first finish with an explicit response wake. Both exact leases expired with successful cleanup and the queue was empty. However, final destination inspection found a separate automatic fallback overwrote the existing summary with a generic no-final-response message. External summary preservation therefore remains failed acceptance; the separate publication repair in #17726 owns that producer. Full combined publication preservation has not passed. These hosted runs include the pinned-base native additions; they do not qualify Copilot v63. - Current-head automated review is 5/5 with zero unresolved threads. All current-head CI gates passed (54 successful checks/contexts, four skipped, none pending). The earlier login-cleanup idle-work assertion also reproduced locally while its controlled baseline passed; its cause remains unknown, but the exact assertion passed in the fresh current-head CI shard. No timeout, assertion or production workaround was added. This PR is ready for review within its source, authority, native finalization, state, wake and cleanup scope. The independent automatic fallback publication regression is tracked by #17726; no complete combined workflow pass is claimed. ## Risks - The latest saved review defines the durable head boundary. Ingress must record a new head before admission. A reply receipt proves delivery only for its exact saved source; a shared GitHub comment ID alone cannot authorize this wait. - Historical App recovery cannot infer identity without direct proof or an earlier valid server response receipt. It never replays that response. - This does not infer review-score policy from instructions or override Done. No deployment, merge or repair of historical tasks is claimed by the PR. ## Model Used OpenAI `gpt-6.1-sol`, with reasoning, repository inspection, code editing and test execution. The context-window size is 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 (focused database and native suites; full local suite limitation described 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 (verified on immutable latest head) - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups (verified on the latest head) - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
f0877a9c7c |
fix: recover native work and requalify saved computers (#17724)
<!-- entire-trail-link-start --> https://entire.com/gh/paperclipai/-/trails/32/changes/paperclip/32 <!-- entire-trail-link-end --> ## Thinking Path > - Paperclip manages AI agents and preserves their work after an interruption. > - Native Stop must confirm termination and save the workspace. > - Task and run views must show the current recovery receipt. > - A new external reply can arrive while that cleanup is pending. > - The reply must return to its original chat owner after cleanup. > - A successful fresh retry also becomes the task’s bound workspace for its next ordinary turn. > - Managed computer updates can invalidate a saved snapshot qualification. > - This pull request fixes those instructions, acknowledgements, handoffs and the existing native-agent Test path. > - The operator can continue with new input while the stopped turn remains preserved. ## Linked Issues or Issue Description **What happened?** Stopped native runs could keep the initial workspace-repair instruction after files were recovered. Native Stop could also leave the shared cancellation state at requested after remote termination was confirmed. A new GitHub reply saved during cleanup could then remain queued because cleanup did not ask its original inbound owner to reconsider the receipt. After a managed snapshot update, an existing native agent could also need qualification while the generic environment Test required instance-admin access. **Expected behavior** Show the current saved-work state. Acknowledge Stop only after exact termination proof. Let an authorized operator use the existing saved-agent Run test to qualify its current computer. After cleanup, recheck the saved reply's current authority and admit it once as new input. Preserve the stopped run and uncertain external effects. **Steps to reproduce** 1. Stop an active native turn before it returns a semantic result. 2. Send a new authorized external reply while cleanup is pending. 3. Let workspace recovery and provider cleanup finish. Inspect the run instruction, Stop acknowledgement and queued reply. Related work: #17594 preserves native processes through controller outages. #17401 addresses a separate bootstrap failure. This pull request does not replace those fixes. ## What Changed - Use the exact run's workspace recovery receipt for task and run guidance, including the Activity ledger. - Retire an obsolete exact-session notice through the existing bounded reconciler. Preserve the separate no-replay hold. - Write the shared native Stop acknowledgement only after the audited Stop intent and every exact remote lease receipt match. - Delegate saved external input to the live inbound owner. Recheck its source, actor, endpoint, principal and conversation generation. Promote the same receipt in the transaction that creates its new run. - Use that owner from the cleanup callback and existing stranded-queue catch-up after a lost callback or restart. A denied source cannot abort other items. - Reuse the current private task directory after a successful fresh retry. Re-read the company/task/workspace binding and validate the canonical stable or attempt namespace without recreating missing files; keep a later fresh retry separate. - Extend the existing agent-scoped qualification owner to native agents. The clean saved-agent Test qualifies its exact computer before runtime testing. Reuse a current proof; require a real probe and verified cleanup for a stale proof. Preserve draft tests and metadata-only external/pool previews. - Update execution semantics, capability maps and the recovery verification recipe. Add a production-page Storybook interaction for the normal native Test. ## Verification - **Red:** persisted recovery states returned stale instructions; an exact terminated native lease left shared Stop requested; the real GitHub subscribed-message fixture left zero successors after cleanup. The controlled baseline restored the previous production source, reproduced the failure, then restored the fixed bytes with matching SHA-256 hashes. - **Green:** 382 durable-chat, native-continuation, Stop and recovery tests pass. The real GitHub/PostgreSQL handoff matrix passes 12/12. It covers callback, application restart, callback/sweep race, valid input behind a deleted source, and denial for unknown stop, wrong allocation, paused endpoint, revoked principal, deleted or changed source, changed conversation generation and foreign scope. Repeated callbacks preserve one receipt, its actor, one successor and the unchanged stopped predecessor. - **Workspace continuation red/green:** the real PostgreSQL preparation flow created a fresh attempt and saved a marker, then rejected the next ordinary turn with the same binding mismatch observed in deployed use. The repaired preparation and filesystem suites pass 86/86: stable and attempt-root reuse, saved-marker preservation, a later clean sibling, changed current bindings, foreign company/task, closed workspace, traversal, missing path and symlink refusal. No task row reset or old-turn replay is used. - **Qualification red/green:** a native saved-agent qualification returned 422, and its normal Test skipped qualification. The repaired path passes 224 qualification/immutable-snapshot/environment tests and 176 UI/upgrade tests. It covers revoked authority, foreign or changed computer, current-proof reuse, failed/missing proof, draft settings, settings changed during the probe, and external/pool previews. On exact current source, the real local Harness / Runtime UI also qualified a newly saved disposable Computer with missing proof through actual Daytona, then completed the actual OpenCode/OpenRouter hello probe using `openrouter/deepseek/deepseek-v4.1-flash-1017`. Supported availability changed from Legacy-only to Paperclip Runner after proof persistence. Qualification and runtime leases both completed normal release/cleanup. The five prior task run IDs were unchanged; no task wake was created. This is macOS source-server/UI with real Linux Daytona and provider services, not a hosted UI claim. Test probes are archived by the existing inspection contract; release does not claim physical deletion. - Full workspace `pnpm -r typecheck`, `pnpm build`, token, map and diff checks pass at `f6450f4739fc8141815b8b7c35fde22a655c5f90`. The broad local `pnpm test:run` passed 24,899 tests and reported one existing nested-clone test timeout at 15 seconds. The complete failing file then passed 21/21 with the normal timeout; the exact case also passed on the pinned earlier baseline. The broad runner stopped before its later groups. No timeout or production workaround was added. Prior head `f6450f4` has 53 successful checks, two conditional Storybook skips and Greptile 5/5 with no inline threads. New workspace-reuse head `fcb13399ec70f92f71bd8250081251dca3f48962` passes workspace typecheck, full build, 86 scoped tests, maps and diff checks; Current-head CI has 53 successful checks and two conditional Storybook skips; Greptile is 5/5 with no inline findings. Deployed ordinary-turn reuse acceptance passed as described below. - **Hosted Stop proof:** the real GitHub issue-mention path used native OpenCode, `openrouter/deepseek/deepseek-v4.1-flash-1017`, Daytona and an exact low-trust task boundary. Normal UI Stop interrupted an active Bash call. Native and shared acknowledgements matched the exact lease. Automatic recovery saved exactly `STARTED\n` (8 bytes), with no finish marker. Reload showed Stopped and saved work recovered. Only the original cancelled run remained. Normal five-minute cleanup completed its exact provider-destruction transition. - **Limits:** the provider buffered command output, so the marker was read after recovery. The approved local provider credential could not inspect the hosted sandbox; its 404 is not deletion proof. Cleanup success comes from the exact lease's platform destruction transition. An earlier hosted stale instruction disappeared after rollout with unchanged raw run/action data; that historical cause remains unexplained. Original incident holds and publication receipts were untouched. - **Hosted handoff proof:** after QA deployed the combined candidate containing `46b2e99`, startup admitted the previously saved GitHub author reply without another comment, Retry or manual action. The new native run used the exact original wake receipt and saved comment. It completed once, committed an external-response wait, preserved the stopped predecessor, emptied the queue and left the task In review. The answer appeared in the original GitHub conversation. Workspace finalization and the exact lease's normal destruction transition succeeded. - **Hosted workspace proof:** on the combined candidate containing `fcb13399`, normal Retry preserved the original authenticated GitHub request and completed a fresh native attempt. One later ordinary same-head author reply then completed in the exact same workspace ID and attempt directory, with no Retry/fresh directive. Its input tree digest matched the Retry's finalized digest; final copyback preserved that digest. The persisted assessment row and all five prior run records were unchanged, exactly one new reply run completed, and the task returned to In review with an empty queue and no live run. Both exact leases completed normal verified destruction. This used real native OpenCode, the exact DeepSeek/OpenRouter model and Daytona, without workspace-row repair or a new remote marker. - **Publication limit:** the workspace audit compares the persisted assessment and run history. The ordinary reply exposed a separate destination-summary fallback that changed the visible GitHub summary despite the preserved assessment row. The publication track is repairing that behavior; this proof does not claim the visible summary was preserved. - **Deployment boundary:** current-head CI/review and hosted same-source Retry/ordinary-workspace reuse acceptance passed. The separate visible-summary publication failure remains owned by the publication track. Combined hosted UI confirmation of the native-agent Test path is coordinated separately. Actual missing-proof UI/provider qualification has passed in the isolated local instance above; prior hosted Stop and same-input handoff proof remains separate. No merge or deployment is performed by this pull request. ## Risks Recovery state and termination receipts must match the exact source run and allocation. Missing or foreign proof keeps the hold. The chat owner must retain the original receipt and actor and recheck current authority. Cleanup cannot grant authority or replay the stopped turn. Existing native ownership, Stop, budget, permission and uncertain-effect guards remain in place. ## Model Used OpenAI GPT-6.1 Sol (`gpt-6.1-sol`) through Codex, with reasoning, repository tools, source editing and test execution. The context-window size is 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 (affected suites and isolated failing file pass; broad timeout retained 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 (current fcb has 53 successful checks/two conditional Storybook skips) - [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> |
||
|
|
832c44f26a |
fix: resume user follow-ups that reassign a task (#17821)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The execution control plane saves user messages while an earlier run needs recovery. > - A user comment can also assign a task back to its agent. > - That update creates an assignment wake, but continuation accepted only comment wake reasons. > - The saved question could stay blocked after workspace recovery and confirmed process cleanup. > - This pull request admits assignment wakes that carry a valid, undelivered user comment through the existing continuation checks. > - The same rule applies to new messages and saved requests already waiting for recovery. ## Linked Issues or Issue Description **What happened?** A human follow-up that also assigns a task back to its agent produces `issue_assigned`. After a native run stops during handoff, the continuation policy rejects that wake reason. The question remains saved behind the execution recovery hold even after the workspace is recovered and the old sandbox is destroyed. **Expected behavior** Deliver the saved human question once after the existing stop, ownership, authority, and execution gates pass. Assignment alone must not grant permission to continue. **Steps to reproduce** 1. Finish task work by assigning it to a human for review. Let the native run stop with `issue_reassigned` and retain its recovery hold. 2. Recover the workspace and confirm destruction of the old sandbox. 3. Post a new human question while assigning the task back to the agent. 4. Observe that the assignment wake stays deferred instead of delivering the question. Refs: #17288, #14156. These related changes cover legacy reassignment and assignments without comments. This change covers a human comment carried by an assignment wake behind a native or legacy continuation hold. ## What Changed - Share the comment-bearing wake classification between continuation admission and saved-request recovery. - Accept `issue_assigned` only through the existing persisted user-comment validation and execution gates. - Add database regressions for new and saved assignment wakes, concurrent recovery, single delivery, and unchanged prior run results. - Check that bare assignments, invalid authors and comments, changed ownership, active execution, and pending approvals or questions retain their holds. Cover native and legacy cleanup paths. - Update execution semantics and both recovery maps. ## Verification - Red: both new and saved assignment-with-comment cases stayed deferred without a successor on the original code. - Green: the final continuation suite passes all 284 tests. The four companion recovery, retry, and queue suites pass another 208 tests. - `pnpm -r typecheck` and `pnpm build` pass. - `git diff --check`, `node scripts/check-maps.mjs`, and `node scripts/check-module-boundaries.mjs` pass. - Apex review is 5/5 on `56c9c2d90dcda55b3f760946c9aba6aee448c361`, with no unresolved review threads. The only earlier finding concerned the contribution rule against new source comments; those comments were removed. - Full `pnpm test:run` is still running locally. CI is waiting for the `paperclip-public-pr-x64` runner fleet; the superseded workflow was cancelled so the current head could proceed. No passing CI claim is made yet. - Live recovery: corrected one existing saved wake to the supported comment reason. The normal server admitted one successor with the exact saved question and prior-run context, then started real tool calls. This verifies admission on the existing deployment; the new source change is not deployed yet. The resumed turn later failed with a separate provider terminal event whose error was null, followed by a workspace restore failure. The task is blocked again on that failure. Its useful answer has not been delivered, so end-to-end completion remains unverified. ## Risks - Assignment wakes now reach continuation validation when they carry a comment. The persisted comment must still belong to the task and requesting human, follow the stopped run, and remain undelivered. - The existing stop proof, cleanup, current assignment, approval, pause, budget, and competing-execution checks remain effective. Regression cases cover both native and legacy paths. - No schema migration or data rewrite is required for saved requests. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, source inspection, tool use, and code execution. The runtime does 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 - [ ] 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> |
||
|
|
32ec84db2e |
fix(native): restore plugin checkpoints for same-run retries (#17814)
## Thinking Path > - Paperclip manages AI agents and their work. > - Native sessions retain provider state across execution attempts. > - A same-run retry can receive a replacement plugin task lease. > - The executor loaded the old task checkpoint only for crash recovery. > - An ordinary retry could fail its local authority check before reading that checkpoint. > - This change restores the checkpoint through the existing authorized lease transfer. ## Linked Issues or Issue Description **What happened?** A native provider turn ended without its completion result. Paperclip scheduled an exact-checkpoint retry on the same heartbeat run. The retry acquired a new plugin task lease, then failed with `runner_state_identity_mismatch: authority_indeterminate`. The checkpoint restore branch required a `resume_dead_runner` restart claim. Ordinary same-run retries have no such claim. A controlled fixture with a retained remote checkpoint and no local lifecycle receipt reproduces the error. The original controller file contents were unavailable, so that part of the incident mechanism remains inferred. **Expected behavior** Load the retained plugin checkpoint after the existing policy proves the lease transfer is safe. Keep the original run, session, and saved control journal. Reject an unverified predecessor or a changed checkpoint identity. **Steps to reproduce** 1. Start a native session through a plugin task environment. 2. End its provider turn without a completion result and retain its checkpoint. 3. Retry the same run on a replacement task lease without a restart claim. 4. With no local lifecycle receipt, observe the authority error before the checkpoint read. **Paperclip version or commit** Reproduced against source `507dc70be26c191e372f09e58dc0965e73bf8f57`. **Deployment mode** Native Runner with a plugin task environment. The observed provider used ACPX Claude. The controlled executor fixture uses the shared native boundary. Related work: #17439 concerns recovery after controller replacement. This fix uses the existing checkpoint contract and does not depend on that PR. ## What Changed - Restore prior plugin state for an ordinary same-run attempt when its lease changes. - Keep the existing company, agent, workspace, retained-state, and termination checks. - Extend executor regressions for ordinary retries, mismatched checkpoints, and missing stop proof. - Exercise the same-run checkpoint read through the database-backed task API. - Document the recovery rule and verification recipes. ## Verification - Failing before: the ordinary retry reproduces `authority_indeterminate`. Both new denial cases also fail because the old branch never reaches the transfer policy. - Passing after: all six focused checkpoint cases pass. The saved control journal stays byte-for-byte unchanged. Rejected cases do not construct a provider backend. - `pnpm -r typecheck` passes. - Map and module-boundary checks pass. - All 858 executor, database lease-authority, plugin task, and ownership tests pass. `pnpm build` passes. - The broad local `pnpm test:run` attempt did not complete. It hit a 20-second timeout in the existing historical workspace-recovery HTTP Retry case. That exact case then passed in isolation on the unchanged head. The broad local attempt was stopped after the full CI matrix passed; it is not counted as a local pass. - Greptile reviewed current head `5bc11fa978ab87d3d9c5d575fa9666185aaafc2c` at 5/5 with no actionable findings. The full current-head CI matrix passed on attempt 2: 55 checks passed, no pending or failed checks, and two expected Storybook jobs skipped. - The first broader local attempt could not bind embedded PostgreSQL inside the sandbox (`EPERM`). It was stopped and restarted with loopback access. This was a setup failure, separate from the observed red regression. - The first CI attempt failed two existing checks: the process-adapter signoff happy path exhausted its run wait budget, and the workspace export scheduler did not reach `complete` within 20 seconds. Both tests pass in isolated local runs on the unchanged head. Both failed shards passed on their single rerun without code changes. The initial failures remain recorded. Their timing cause is not proven by the later passes. - Live acceptance at the fixed revision has not run. The hosted workspace still serves the earlier release. No deployment or retry of the original task is claimed. ## Risks The new checkpoint read runs only for same-run plugin recovery with a replacement lease. Missing termination proof, changed scope, or a changed Runner identity still stops execution. The lease resolver owns these checks. The fix does not replay tools or change retry budgets. A turn that omitted its completion result still needs the existing bounded continuation to finish useful work. ## Model Used OpenAI GPT-6 through Codex, with reasoning, repository tools, and code execution. The runtime does not expose a more specific backend 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> |
||
|
|
835966dec8 |
Prepare agent-owned environments during hiring (#17761)
<!-- entire-trail-link-start --> https://entire.com/gh/paperclipai/-/trails/1/changes/paperclip/1 <!-- entire-trail-link-end --> ## Thinking Path > - Paperclip manages agents and their execution environments. > - New agent setup saves an inactive agent before model connection tests. > - Some plugins need that agent to prepare its execution resource. > - The wizard tested without the agent ID, while the setup hold prevented preparation. > - Environment changes also discarded the selected model account. > - This change prepares the saved draft during setup and keeps normal execution held. > - Users can test the prepared resource before they finish hiring. ## Linked Issues or Issue Description **What happened?** An agent-owned plugin environment could not acquire a test lease during hiring. Changing environments also returned the user to Connect and cleared the selected account. **Expected behavior** Keep the selected account, invalidate its test, and prepare the saved agent resource in the background. Test that same agent before finishing setup. **Steps to reproduce** 1. Start a new Claude or Codex agent and select a saved account. 2. Change to an agent-owned plugin environment. 3. Try to finish setup or reconnect the account. Related: #17750 defers probes until after hire submission. This change implements preparation during the wizard instead. The related PR search and ROADMAP review found no other implementation of this setup preparation path. ## What Changed - Add the optional `requiresAgent` driver declaration. Require agent lifecycle participation when it is set. - Prepare saved drafts on creation or environment changes. Keep the setup hold and wait in `verifying` without background verification scans. - Bind tests to the saved agent. Return a warning without allocating a lease when the required agent is absent or still preparing. - Preserve the account and configuration step when the environment changes. Save the selection and invalidate the old test. - Show active preparation and support authorized retries. Keep approval, company, budget, and normal task admission controls. - Document the contract and cover lifecycle, lease, manifest, and wizard behavior. ## Verification - Server and UI TypeScript checks passed. - 112 wizard and setup helper tests passed. The shared manifest suite passed. - 123 lifecycle, policy, lease, and environment-test API cases passed after the approval-gate fix. The diagnostic and driver suites and all 80 agent adapter route tests also passed. - Token gates, module boundaries, map validation, and whitespace checks passed. - All 66 lifecycle/policy cases passed after the stopping-draft permission fix. The new real-DB route case verifies creator success, other-creator denial, and refusal to complete a hire while stopping. - Full workspace typecheck and build were attempted. Both stop at the unchanged Rust Runner step because Cargo is not installed on this host. - CI on |
||
|
|
c7c12dbc79 |
Support plugin panels in task sidebars (#17796)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - Task side panels keep live work beside the conversation.
> - Plugins can already provide agent detail tabs.
> - Those tabs have no generic way to appear beside the task that is
using the agent.
> - This pull request adds an optional task-side-panel declaration to
agent detail tabs.
> - The plugin owns the label, component and availability. Core supplies
the task's running agent.
## Linked Issues or Issue Description
**What existing behavior does this improve?**
Access to plugin-contributed live views from task chat.
**Subsystem affected**
Plugin manifest validation, slot discovery, and task side-panel
UI/state.
**Current behavior**
Agent detail-tab contributions appear on agent pages. A task cannot
offer the same view through a plugin-owned availability decision.
**Proposed behavior**
An agent detail tab can declare `taskSidePanel: { availabilityPath }`.
Core substitutes the running agent into the plugin-local path. A
declared board GET route scoped to that agent returns `{ available:
boolean }`. Available contributions appear in desktop and mobile task
side panels.
**Reason and benefit**
Keep the task and its live plugin views together. Preserve plugin
ownership of provider protocols and product behavior. Core contains no
concrete plugin identifiers, routes, labels or readiness rules.
**Breaking changes**
None. The field is optional. Existing contributions remain unchanged.
Missing, disabled or unavailable plugins add no panel.
**Additional context**
Related: #17111 established the agent detail-tab and scoped API
extension surfaces. Roadmap and related PR searches found no duplicate
of this extension.
## What Changed
- Extend the manifest with optional task-panel metadata. Validate safe
plugin-local paths and require a declared board GET route with
agent-scoped authorization.
- Discover and load only opted-in agent contributions. Poll their
generic availability responses and mount the existing components with
agent context.
- Add generic panel tabs, launcher entries, dismissal and inactive-view
removal in desktop/mobile task chat.
- Reuse the existing live-run polling guard so idle tasks with a healthy
live connection stop polling.
- Add provider-neutral fixtures, schema/authorization tests, task tests
and SDK/feature documentation.
## Verification
- PASS: 301 focused tests including the full task-detail file, generic
panel discovery, persistence, slot loading and manifest validation.
Regressions cover POST-before-GET route order, mobile drawer dismissal,
recovery without focus and the absence of the hidden desktop task panel
on mobile.
- PASS: UI and shared-package typechecks; production UI build; token
gates, feature-map and module-boundary checks; diff and secrets/PII
review.
- PASS on final head: all 795 UI files / 9,186 tests, and all 95
shared-package files / 1,038 tests. Commands: `node
node_modules/vitest/vitest.mjs run --project @paperclipai/ui
--maxWorkers 3` and the corresponding `--project @paperclipai/shared`
command with local socket access.
- On the final head, server shards 7/12 and 10/12 and workspace shard
a-1/2 were interrupted by runner shutdown/communication loss. GitHub
reported infrastructure failures; no assertion failure was surfaced in
the available diagnostics. The queued summary was cancelled, then `gh
run rerun --failed` successfully requested retries for only those three
jobs. They are currently queued for CI runners; the 50 successful checks
remain passing. Interrupted attempts are not counted as passing.
[Final-head CI and
retry](https://github.com/paperclipai/paperclip/actions/runs/40396870920).
- Earlier verification exposed an empty-panel rerender loop, which was
fixed. The sandboxed combined run also failed five shared port-registry
tests because it could not bind loopback listeners; the full shared
rerun with socket access passed. These earlier failures are retained
here rather than reported as passing runs.
- Full workspace typecheck/build were attempted with pinned pnpm 9 after
resolving the initial local package-manager setup. Both stop at the
unchanged Runner Rust step because `cargo` is not installed. Full local
workspace checks are not reported as passing; final CI must provide
those broader checks.
- No live provider or plugin-specific transport acceptance is claimed by
Core's synthetic fixtures.
## Risks
- Availability is polled every three seconds only while an authorized
running agent exists. Plugins own the side effects and meaning of that
read.
- A view uses the running agent's context. It is not a separate per-task
resource.
- Optional metadata adds no backend endpoint or permission bypass. The
host requires existing board and agent authorization.
- Reverting the optional contract and UI integration removes task panels
without a data migration.
## Model Used
OpenAI Codex (GPT-6), with reasoning, repository tools and code
execution. The exact backend snapshot ID and context window size are not
exposed by 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 described the issue in-PR following the relevant issue
template
- [x] I have not referenced internal/instance-local Paperclip issues or
links
- [x] My branch name describes the change and contains no internal
ticket id
- [x] I have run focused 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
- [ ] 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>
|
||
|
|
718c73dafe |
fix(native): require verified remote process exit receipts (#17799)
Require fresh ESRCH or an exact matching zombie generation before treating a remote Runner as stopped. Preserve uncertain ownership through adoption and transport close, retire local controller resources after failed close, and check Node before remote launch. Bind the shared transport change in Copilot profile 62 while retaining historical profile decoding. Add red-green process, permission, launch, adoption and cleanup regressions. Thanks to @hsm-lv for the original investigation in #17073. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
8373d78679 |
fix(recovery): register missing native preservation on Retry (#17800)
## Thinking Path > - Paperclip lets people manage agents and their saved work. > - Native runs can leave a prepared remote workspace after a control deadline. > - The deadline repair in #17788 records preservation for future failures. > - Older failed runs can still have an active lease without a preservation owner. > - Retry correctly refuses another executor, but nothing can finish the missing preservation. > - This pull request registers the exact prepared source through the existing recovery services when the user retries. > - The bounded maintenance worker can then stop the provider and save its files before normal admission continues. ## Linked Issues or Issue Description **What happened?** A historical failed native run has a prepared workspace and an active retained allocation. It has no workspace preservation record. Ordinary Retry cannot prove that the old executor stopped and has no maintenance owner to produce that proof. **Expected behavior** A deliberate Retry registers missing preservation for the exact unowned source. Existing recovery proves termination and saves the files. Existing admission then checks current user authority, effects, pause and budget gates before one successor can enter the queue. **Steps to reproduce** 1. Persist a failed native run with a prepared workspace, an active lease and a terminal, unowned finalization. 2. Omit the workspace preservation record, as an older deadline handler did. 3. Call the normal task Retry route. Before this fix, preservation remains absent and Retry cannot continue. **Paperclip version or commit** The regression fails on `46de15ff4b99bbee59c38f32f4f30b80ad5bbd24`, which already includes #17788. Related: Refs #17788 (future deadline failures), #17741 (committed recovery wakes), #17733 (connected Retry authority). #17773 adds source diagnostics and does not repair this missing registration. ## What Changed - Use native workspace preservation inside the existing issue-locked Retry transaction. A live finalization owner remains held. - Adopt a valid unowned preservation obligation through the existing bounded maintenance service. Bind it to the deliberate Retry intent without resetting an active generation. - Add real PostgreSQL regressions for exact, mismatched and owned sources. Verify that registration cannot create a termination receipt or a successor. - Exercise the HTTP route, worker, real temporary file merge and queue admission with the stop reply held. Duplicate requests admit one queued turn after preservation. - Extend connected GitHub and Telegram Retry coverage for missing historical preservation. Document the contract and access boundaries. ## Verification - Red: the new historical-state regression fails on the base commit because `workspaceRestoreRecovery` remains absent. The mismatched and owned negative controls pass. - Green: the three focused historical-state cases pass with the fix against isolated local PostgreSQL 17. - The local HTTP journey restores saved files and retains newer host edits. It admits no successor while the provider stop reply is held. It admits one successor after verified preservation. The real GitHub and Telegram admission paths wait behind that recovery. - `pnpm -r typecheck`, `pnpm build`, `node scripts/check-maps.mjs` and `git diff --check` pass. - Green: 152 tests across four relevant suites, including all connected Retry safety cases. The six new cases pass again on final head `b8900801a3181fa673ea45f1129f968bbb08d1fd`. - Final-head GitHub checks: 55 successful, two intentionally skipped Storybook checks, and one neutral Paperclip bot review. Greptile is 5/5 with no unresolved threads. The Paperclip bot stopped before finishing and supplied no approval. - The full local command imported an earlier fixture revision before its assertions were corrected. It reported those two stale connected-fixture assertions and later hit the host PostgreSQL semaphore limit again. It was stopped after final-head CI completed. It is not counted as a full local pass; the complete CI test lanes passed on the final head. - The first local rerun hit the Mac PostgreSQL semaphore limit before assertions. Verification moved to an isolated disposable PostgreSQL container. Early assembled fixtures also exposed the existing destruction-cleanup gate; the retained-workspace fixture now uses its actual `keep_running` disposition. This fix does not weaken cleanup. ## Risks - Retry now registers maintenance for historical native failures. Exact descriptor, allocation and coordinator checks remain owned by the existing preservation service. Physical recovery still requires its existing exclusive owner and provider stop receipt. Registration alone grants no execution authority. - No database migration or provider protocol changes. No model, trust, assignment, retry-budget or external identity changes. - Local recovery uses real database, filesystem, HTTP, worker and admission code. Only the provider lifecycle boundary is simulated. No hosted allocation or live model turn has been verified for this new change. - The workspace recovery test file crosses 1,000 lines because this case shares its real database, filesystem and assembled route fixture. Keeping it there avoids duplicating that fixture or extracting unrelated production behavior. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, repository tools and code execution. The exact 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> |
||
|
|
2ee36a4c0a |
test: add chat feature scenarios and real task workflow evals (#17794)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agent Chat lets a person assign work through a conversation. > - Feature and API maps do not prove that a natural request produces the right saved result. > - Product E2E already owns isolated fixtures, browser runs, evidence and cleanup. > - This pull request adds a chat scenario catalog and two real task workflows in that framework. > - Independent checks verify the task, its author, the saved output and the reply in chat. > - The benefit is a small executable foundation for broader chat coverage. ## Linked Issues or Issue Description **What existing behavior does this improve?** It adds real task creation and delegation coverage for Agent Chat. **Current behavior** Existing maps describe features and agent access. Existing chat evals cover specific protocols and handoffs. They do not connect a broad human-request catalog to independent saved-state checks. **Proposed behavior** Keep 244 planned scenarios across 35 feature areas. Promote two requests into the explicit-only `chat-features` suite. One saves a backlog task without starting work. The other delegates an announcement and returns the saved result to the original chat. **Reason and benefit** A successful tool call or confident reply does not prove the requested result exists. These evals check public API state, attribution and browser access after a real model run. **Breaking changes** No API or data schema changes. Chat instructions now require actual relative task links. The local E2E private-state scanner recognizes Codex account ownership metadata while continuing to reject credentials and model-visible identity leaks. **Additional context** Related prior work: #13969 and #13762. This improves verification of the existing Agent Chat roadmap item. It does not add a new core product feature. ## What Changed - Add YAML scenarios with capability IDs, starting context, user requests and expected outcomes. Validate all area files against their schema, global ID uniqueness and exact feature-map capability coverage. - Add two local native Codex subscription cells. Send the exact catalog request once through Chromium. - Seed only prerequisites through public APIs. Use shipped agent instructions and explicit disposable budget policies for unpriced subscription usage. - Check task ownership, creation audit, no premature execution, current worker-authored output, automatic completion delivery and usable links after reload. - Keep private Codex account ownership metadata distinct from bearer credentials. Scan rollout message content, all tokens and published evidence as before. - Teach normal chat instructions to use relative task links instead of invented hosts. Update tests, maps and the runbook. - Repair existing E2E contract drift: include the active Copilot identity in the image digest and update Pi profile expectations. Keep global catalog cardinality in its owning catalog test. Product E2E owns the new flow and grader. Its existing launch and report paths remain in use. The shared scanner change is limited to owner-private temporary Codex runtime metadata. Other callers retain the full secret scan. No UI, endpoint, schema or permission behavior changes. ## Verification - `node scripts/check-maps.mjs` passed: 35 areas and 191 capability IDs. - Product E2E typecheck and focused tests passed before rebase: 225 Vitest tests and 137 Node tests. Conversation service tests passed 40/40. Five existing runner turn-binding regressions passed. - Historical live measurement used real Chromium, server, database and native Codex with no automatic retries. The initial same-definition batch passed 5/6 cells. Backlog passed 3/3; delegation passed 2/3. One CEO startup failed because the runner did not receive a provider turn identity. The cause is unresolved. - An unchanged follow-up passed delegation three times and backlog twice. Combined evidence is backlog 5/5 and delegation 5/6. Each attempt passed cleanup. Later passes do not erase the earlier failure or prove a runner repair. - Earlier failed revisions exposed an invented task hostname, private account metadata false positives and missing funding for unpriced subscription usage. Those led to the specific changes above; the failed records remain retained locally. - The runbook records campaign identifiers and definition provenance. Generated result artifacts are not committed. Historical live results predate this branch rebase; fresh PR-source live evidence and final validation are recorded below. - Full workspace typecheck and production build passed on the rebased branch. Product E2E typecheck passed. - The full Product E2E support suite first reproduced four baseline failures: two missing active Copilot image-identity inputs and two stale Pi/catalog expectations. The narrow contract fixes above resolved them. The full rerun passed 4,282 Vitest tests plus 137 Node tests, with two skipped. Image checks verify mutation changes the hash, unchanged input stays stable, and an input closure without Copilot is unaffected. Original failed logs remain retained. - The repo-wide local Vitest run has reported two failures in unchanged service files. The Workspace connection test passed an isolated recheck and its full file passed 469/469 unchanged. The recovery test hit a 15-second timeout; its full file passed 89/89 unchanged. The run later hit explicit PostgreSQL `semget` resource exhaustion and was interrupted after those observed failures; no final aggregate counts or full local pass are claimed. Its complete available log is retained. No assertion or timeout was weakened. Matching remote server CI passed on the same source. - On clean PR head `39ad80b523ce194c90aafafd077d48dd9a36b4c5`, backlog passed in `local-2026-10-26T19-24-13-014Z`. The parallel delegation fixture failed during PostgreSQL initdb, before browser or model execution; its failed cleanup grade is retained. A disposable standalone initdb probe then passed. No semaphore sets or kernel settings were changed before that probe/recheck. After confirming no remaining fixture process, its private temporary files were removed. - One separate delegation recheck passed in `local-2026-10-26T19-29-24-800Z`, with one attempt, zero automatic retries and successful cleanup. Both passing current-source cells use definition `3f2c9ba2d03e3dcddde47ddab3b43bc52de977f25e256fceae0a24c9128e204b`. The earlier bootstrap failure and the historical provider startup failure remain distinct. These local results omit automatic source-SHA metadata; the clean checkout SHA is recorded here from the execution session. - The later broad local run reported `could not create semaphores: No space left on device`. A bounded cleanup removed 32 current-user PostgreSQL sets with 17 members, marker 537, a dead recorded creator and zero waiters. No live process or kernel limit was changed by that cleanup. The test process group was subsequently stopped; no broad rerun is planned. This direct later resource failure does not prove the precise cause of the earlier live initdb failure. - Review follow-up adds only static catalog validation and documentation of the existing five-minute journey bound. The executable definition is unchanged. Focused catalog/oracle tests passed 28/28; no redundant live run is claimed. - Final head `30fcb36ac9ae1f0270a589dbfafcec91ca6a03f3` passed all required and underlying CI checks in [run 40391402347](https://github.com/paperclipai/paperclip/actions/runs/40391402347), including `ci / verify` and `ci / e2e`. Greptile and Paperclip Review both scored this head 5/5, with all review threads resolved. The static follow-up leaves every executable definition input byte-identical to the live-tested source at `39ad80b`. Normal squash auto-merge is enabled. Actual merge is pending eligible code-owner approval for the owned dependency manifest; no protection is bypassed. ## Risks - Live model behavior can vary. One missing turn-start event remains unexplained; this PR does not claim provider reliability or broad catalog qualification. - Subscription costs are unpriced. Explicit fixture funding admits that usage. Run counts and deadlines remain bounded, but the dollar limit cannot cap unknown cost. - Account identity exceptions apply only to known private Codex runtime files. Token reuse, unknown files and model-visible rollout content remain blocking findings. - Deterministic checks establish saved state, output structure, required brief facts and access. They do not score all prose quality. Initial samples also require human inspection. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, code execution, browser and repository tools. The precise model revision and context window are not exposed to this session. Live eval agents used `gpt-5.6-sol`; that is the evaluated model, not a claim about the authoring model. ## 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 local tests; focused suites pass and the interrupted full-run failures are documented 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> |
||
|
|
5061ab7b35 |
perf(ui): speed up task and inbox cold opens (#17756)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Task lists and inboxes are the main entry points to that work. > - Cold opens fetch overlapping task lists, task descriptions, and run details before useful rows settle. > - Independent responses can insert rows above content that a person has started to read. > - This pull request loads a small task index first and adds details only for visible rows. > - It keeps row order and geometry stable while those details arrive. ## Linked Issues or Issue Description **What existing behavior does this improve?** Cold opens of Tasks and Inbox, including the shared navigation badge. **Subsystem affected** Server list reads, shared response contracts, and the React UI. **Current behavior** The badge fetches full task bodies. Mine fetches several overlapping lists. Historical diagnostics and row metadata add work before the first useful list. A fast failed-run response can appear before task rows, then move down when tasks arrive. **Proposed behavior** Load the selected inbox source and its required context together. Use an index without task descriptions or recovery diagnostics. Fetch diagnostic details for up to 50 visible rows. Keep skeletons, recovery indicators, external status, and live metadata in fixed space. **Reason and benefit** Reduce work on a cold open and prevent loading-induced row movement. On the same 100 local fixture tasks, the compact response was 262,441 decoded bytes and the index was 110,909 bytes. This comparison excludes compression and is not a page latency benchmark. **Breaking changes** Existing full and compact responses remain available. New index/row projections are opt-in and marked as partial data. Mine keeps its existing most-recent-100 display limit, now selected on the server. Existing filters and group preferences remain in the client. No database migration. **Additional context** Refs: #17593. Related: #13095, #17428, #13803. This change addresses collection overfetch and layout stability. It does not replace the blocked-inbox query work or the database activity-index work. ## What Changed - Add authorized index and row projections, with bounded task and parent ID batches. - Replace badge list downloads with unread IDs and aggregate counts. Preserve actor privacy, dismissals, and local archive behavior. - Load only the selected inbox source, plus bounded parent and failed-run context. Return only relevant failures from the bounded run window. - Batch hierarchy reads, including at most one authorized child per collapsed parent in one request. Collapsed markers do not consume the expanded row budget, and partial descendant counts are not shown as totals. Enrich visible rows without replacing membership, ordering, titles, or read state. - Reserve row geometry on desktop and mobile. Reveal the initial inbox only after its sources settle. Preserve legacy task-list reads. - Start collection module downloads during access checks. Keep partial rows out of the task-detail cache. - Keep ETags and concurrent request sharing for the new projections, but skip the short server response TTL so archive undo sees fresh state. ## Verification - On final head `ef6afb2a56`, the full CI workflow passed, including build, typecheck, server/workspace/runner suites, and all eight browser shards. A server shard reported **1,489 passing tests** before runner shutdown canceled the job; its single infrastructure retry passed. Both Greptile and Paperclip Review are **5/5**, with zero unresolved review threads. - The optional external **Entire Gates** check remains `unassessed` because it has no active assessed Change for this comparison. Entire is not set up in this checkout. The repository ruleset requires `ci / verify` and `ci / e2e`; both passed. No gate configuration was changed. - Passed workspace typecheck after the final API batching change. The full production build also passed on the final commit; the exact-retry E2E run built the shipped UI. - Passed token gates and map validation. The final batch-preview pass has 91 passing route/hierarchy/component tests, including privacy, request bounds, 30 collapsed parents in one read, and a 120-child parent alongside a sibling. - Passed the 166-test focused UI/inbox/badge run, 47 additional UI regression tests, and 34 issue-list route tests. The latest regressions cover low-trust agent badge IDs, cold company selection, 30 description-only Mine matches with archive actions, retrying optional row details, and collapsed/expanded siblings. - The full local `pnpm test:run` spanned the rebase and reported failures in five suites before it was stopped; it is not claimed as a complete pass. A fresh serial rerun of all five suites passed **452/452** tests (tool gateway, native resume, project repositories, workspace recovery, and runner selection). Full current-commit coverage is checked by CI. - Real browser: delayed index and row-detail responses on Tasks and Mine. The first placeholder and first row had the same origin and 44-pixel height. Twelve rows on each page had zero position, height, or title-width change after recovery details arrived. - Real browser: reviewed long titles and recovery status at a 390 by 844 viewport. Task text stays on one line and recovery uses a compact indicator. - Three fresh document loads per page on final commit `260893bf92`, with HTTP cache retained on a warm local development server: Tasks 1.031–1.190 seconds; Mine 0.999–1.193 seconds. Browser-control overhead is included. These values must not be compared directly with staging latency or the earlier local samples taken during a full test run. - The browser archive test exposed stale results after Undo. The new projections now bypass the server TTL; immediate-mutation regression tests pass. The final browser retry passed: Archive followed by Undo restored exactly one row and the badge count. - CI exposed a hook-order crash when company selection resolved after the first inbox render. The hook now runs before the empty-company return. All seven affected exact-retry and legacy-continuation browser scenarios pass locally after the fix. - Real browser review regressions: 97 description-only source matches retained Archive actions; deliberately failed optional row reads displayed a retry notice while all 12 observed row positions and heights stayed unchanged. Retry restored the recovery indicator. Network fault injection was removed. - The final production build and workspace typecheck passed. Final focused verification passed 153 UI/helper tests and 26 heartbeat privacy route tests. Final review regressions cover newer diagnostics arriving during the index read, reloading diagnostics when the same task ID changes version, optional source failure/retry without hiding available rows, and required external-status filter failure. The latest-failures route test verifies bounded selection, agent filtering, success suppressing an older failure, and private-run redaction. - Real browser: deliberately failed the run source, then retried it. Twelve available task rows kept the same position and 44-pixel height before, during, and after retry. No loading skeleton replaced them. Fault injection was removed. - Hierarchy review decision: the cold-open barrier stays because inserting ancestors or expanded children after revealing index rows would cause layout shifts. Existing hierarchy context now survives subsequent requests, with a regression proving a new ancestor read does not blank the list. The bounded recursive tree read can still add latency for unusually deep expanded trees. - Tasks now handles a failed external-status filter with an explicit error and Retry, suppressing a false empty state. All 52 Tasks component tests pass, including failure-to-success retry. One existing large-tree test timed out while workspace typechecking ran concurrently; the whole component suite passed when rerun without that competing work. Workspace typecheck, the full production build, and token gates passed for this fix. ## Risks - Saved filters and grouping still operate on the existing bounded collection. This is not a new global server pagination model. - Fixed row slots reduce available title width. Long titles remain accessible through task navigation. - Recovery and related diagnostics arrive after core rows. Their responses cannot replace ordering fields, and stale versions are rejected. - Index/row requests now revalidate against current data instead of a short server TTL. They still share concurrent reads and use ETags. - This has not been deployed by this pull request. Staging latency must be measured after deployment under comparable conditions. ## Model Used OpenAI Codex, GPT-6 family. The exact runtime model ID and context-window size are not exposed in this session. Used code editing, terminal execution, and real-browser diagnostics. ## 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> |
||
|
|
46de15ff4b |
fix(recovery): preserve native workspaces after control deadlines (#17788)
## Thinking Path > - Paperclip lets people manage agents and their saved work. > - Native runs can prepare a remote workspace before provider execution. > - A finalization deadline can stop a run outside its normal exception path. > - That handler marked the run failed without recording its prepared files for recovery. > - Retry then waited for a lease whose preservation had no durable owner. > - This pull request records the exact source in the deadline transaction through the existing recovery service. > - Existing containment and file recovery can then settle the source before another executor starts. ## Linked Issues or Issue Description **What happened?** A native run failed at its control deadline with a prepared workspace and no accepted result. Its environment lease remained active. The run had no workspace preservation record. A saved Retry waited for remote cleanup without a preservation operation to finish that cleanup. **Expected behavior** Record unfinished files when the deadline marks a native run failed. Use the existing stop-and-retain worker. Keep accepted results, exact source binding, and current task ownership authoritative. **Steps to reproduce** 1. Persist a native run with a prepared workspace, an active lease, and an expired control deadline. 2. Reconcile the deadline twice. 3. Inspect the source lease and the run's workspace recovery record. **Paperclip version or commit** Reproduced against `a67a18c171816b097f46eae78fc58c7e55c9c565`. **Deployment mode** Hosted native Runner with a remote sandbox. The regression uses real local PostgreSQL and no provider mocks. Related: Refs #17741 for committed Retry delivery. Refs #17073 for remote process-exit verification. This change records file preservation after a deadline; it does not change either policy. ## What Changed - Call the existing native workspace preservation service in the transaction that fails an abandoned run. - Preserve files after reassignment without changing the current task owner or state. - Add real-database cases for prepared, finalized, mismatched, reassigned, and accepted-result states. Repeated reconciliation retains one source obligation and creates no successor. - Document the deadline behavior and its existing access boundaries. ## Verification - Red: on unchanged production code, the prepared-workspace case failed because its recovery record was null. Finalized and mismatched controls passed. - Green: all 10 deadline reconciliation tests pass. The existing native workspace recovery suite passes all 48 cases. - `pnpm -r typecheck` passed. - `pnpm build` passed. - Map checks, module-boundary checks, and `git diff --check` passed. - Current-head CI passes on `23bf2aa4b50d2c4b74a9ee2ee47034ae542d25c2`: all GitHub Actions CI lanes, including grouped/serialized tests, Runner verification, typecheck, build, E2E, and Canary Dry Run, succeeded. Two Storybook-only checks were skipped. Greptile is 5/5 with no findings. Superagent Security Scan also passed. Entire Gates reports passing checks/findings and fails only because no reviewer has approved trail #10. - The first server shard 11/12 attempt passed all 1,750 assertions but reported an unhandled early process-exit rejection in the unchanged workspace-exposure fixture. Its focused local suite passed (28 passed, 3 skipped); one CI rerun passed. - Full local `pnpm test:run` was started, then interrupted after the complete CI lanes passed to avoid duplicate work. No full local suite pass is claimed. Local targeted tests, typecheck, and build passed. - On the affected staging instance, the existing deployed preservation helper registered the exact failed source. Normal Retry then drove actual sandbox stop, file recovery, and a persisted successful recovery receipt. A successor reached a separate remote process-fingerprint failure before provider execution. The automatic deadline change is not deployed; task execution recovery remains incomplete. - Initial local setup attempts did not reach product assertions: skipped dependency lifecycle scripts left native PostgreSQL library links absent, and the restricted shell blocked localhost binding. The package's link hydration and an authorized isolated listener resolved those setup prerequisites. One new negative-control assertion also required null-safe access; the final red run retained only the intended behavioral failure. ## Risks - File preservation must not certify provider termination. The existing stop receipt, source binding, copyback, and admission checks remain in force. - Preservation failure rolls back the deadline transaction, leaving its durable deadline eligible for another bounded attempt. - Reassignment preserves old files without changing the new owner's task. Accepted results retain their current finalizer. - No schema, credential, provider, or polling change. Historical failed runs still require scoped recovery; this patch does not replay them. ## Model Used OpenAI Codex based on GPT-6, with reasoning, repository inspection, code execution, and browser 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 (targeted suites; full local suite interrupted after CI passed) - [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 - [ ] All Paperclip CI gates are green (CI lanes pass; external Entire reviewer-approval gate remains pending) - [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> |
||
|
|
a67a18c171 |
fix(tasks): hide empty message history disclosure (#17751)
## Thinking Path > - Paperclip helps people manage AI agents and their work. > - Each task page shows the instruction and saved conversation. > - Cold opens show recent content before older history. > - The page used any linked run as evidence of older messages. > - A task's first run therefore showed an empty More messages control. > - This PR shows the control only when the preview omits comments or runs. > - Fresh tasks stay clear, and older task history remains available. ## Linked Issues or Issue Description Refs: #17593. **What happened?** A fresh task with only its first run displayed More messages, even though there was no earlier history to load. **Expected behavior** Show More messages only when older comments or runs are omitted. Runs observed while the page stays open must not create a false disclosure. The output control also uses actual skipped bytes, so a growing run does not gain an empty output control. **Steps to reproduce** 1. Create a task and let its first run start or finish. 2. Open that task with a fresh application cache. 3. Observe the empty More messages control below its instruction. ## What Changed - Keep omitted-run evidence with the cached recent run window. - Use omitted comments or runs to decide whether to show More messages. - Preserve run retention, reconnect reconciliation, and expansion of real history. - Offer More run output when a single legacy log exceeds the compact byte window. - Keep first-run native diagnostics accessible through More task actions → Show task activity. - Add regression coverage and update the task feature map. ## Verification - Passed the existing 9,168-test UI suite across 794 files, then all 504 focused task-detail, history-window, real thread, and log-transport tests after adding the activity-menu regression. - Passed workspace build, workspace typechecks, token gates, and map checks. - Reproduced the bug in the earlier UI using a disposable local task. The corrected UI hides the control with zero runs or only the first run. - In the local browser, expanded a long task to all 80 comments. The latest answer appeared once and the disclosure disappeared. No console warnings or errors occurred in that journey. - Expanded a saved 111 KB legacy log through More run output and opened its earlier activity in the local browser. - On a single saved native run, verified no More messages control. Used Show task activity to reveal its earlier tool output; the latest answer remained visible exactly once, with no console warnings or errors. - The first broad local run stopped because the fresh dependency install lacked PostgreSQL library symlinks. The normal package setup repaired that environment issue. - The next broad run hit one workspace-runtime timeout. Its focused rerun passed with unchanged server source; the original failure remains recorded. Stopped the already-failed broad runner after the previous revision passed full PR CI. All final-head build, typecheck, test, and policy CI jobs passed. Both automated reviewers scored the final head 5/5, with no unresolved threads. The separate Entire Gates check is pending because the PR has no active assessed Change for its current comparison. The installed Entire CLI reports no linked project trail and exposes no Change-assessment command; no gate or repository settings were altered. Browser verification used this branch's UI with the existing disposable test-drive API. No agent execution was started. ## Risks Low risk. This changes the recent run cache shape and the disclosure condition. The full run cache remains an array. Tests cover first-run states, observed new runs, omitted older runs, expansion, and reconnect reconciliation. No schema or API changes. A separate run-output control preserves access to a single truncated legacy log. The task menu preserves first-run native activity access without implying older messages exist. ## Model Used OpenAI GPT-6 through Codex, with code execution and browser tools. A more specific 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 - [ ] 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> |
||
|
|
063a498b54 |
Bound native OpenCode assigned-tool catalog projection (#17740)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Native agents use assigned connection tools through a governed gateway. > - OpenCode received the gateway catalog directly, outside the bounded server tool projection. > - A large catalog can exceed a provider grammar compiler's capacity even when it fits the transport limits. > - Synthetic requests reproduced the Fireworks grammar timeout on the configured DeepSeek model. > - This pull request gives OpenCode two assigned-tool discovery and call schemas through the existing server relay. > - The gateway keeps the same grants, validation, approvals, revocation, and audit rules. ## Linked Issues or Issue Description **What happened?** A native OpenCode run could fail during provider grammar compilation before its first assigned-tool call. OpenCode advertised the full assigned gateway catalog. A synthetic catalog of 741 tool schemas reproduced `Grammar processing took too much time` on Fireworks through OpenRouter with `deepseek/deepseek-v4.1-flash-1017`. The same model and backend accepted a compact two-tool discovery/call catalog. This reproduces the mechanism; it does not replay a historical private request. **Expected behavior** Assigned-tool discovery must keep provider grammar size bounded. Every call must retain the run's original gateway binding and permissions. **Steps to reproduce** 1. Give a native OpenCode run a large assigned connection catalog. 2. Use a provider that compiles tool schemas into a constrained output grammar. 3. Observe the full catalog in the provider tool surface before this change. 4. After this change, observe only `paperclip_search_assigned_tools` and `paperclip_call_assigned_tool` for assigned tools. Discover and call a permitted tool through its pinned alias. **Paperclip version or commit** Source checkout based on current `master`. **Deployment mode** Native local or sandbox execution with OpenCode 1.18.34. Related work: Refs #14258 (discovery paging), #16678 (local adapter MCP launch), and #17688 (gateway capability advertisement). This change covers native OpenCode catalog projection. ## What Changed - Route native OpenCode assigned tools through the existing server-owned authenticated relay. - Use bounded discovery/call schemas for OpenCode, including small catalogs. Preserve transport capacity checks. - Keep assigned gateway credentials on the controller. Ignore gateway and credential values in tool arguments. - Preserve exact declared MCP operation names through admission and driver dispatch. Resolve transport prefixes only against the closed catalog. Reject unknown or shortened names. - Refresh former OpenCode direct-catalog and shortened-name checkpoints. Keep the existing fingerprints for other providers. - Add local and remote wiring, catalog capacity, alias, scope, work-mode, approval, and revocation tests. - Allow the native test files to use a validated dedicated external test database when embedded PostgreSQL is unavailable. - Document the assigned-tool execution contract. - Bound OpenCode discovery pages to 32 KiB and large-schema chunks to 16K characters. Keep other harness budgets unchanged. - Test medium pages and escaped large schemas through the actual HTTP MCP bridge on the explicit Runner testing surface. ## Verification - Red before the catalog fix: OpenCode did not create the server relay, and forced compact delivery advertised 1 or 741 direct schemas. - Red before the alias repair: HTTP MCP changed declared operation names, and the driver sent `search_assigned_tools` instead of the authorized `paperclip_search_assigned_tools`. - Current repair tests: 112 OpenCode/proxy tests pass, plus one actual Rust/proxy/HTTP MCP regression. Two checkpoint regressions fail with the former scoped revision and pass with the new revision. Other providers keep their prior fingerprints. - The combined QA candidate with this exact PR head passes all 916 native tests and all 113 transport tests on supported Node 24.22. An earlier Node 26.4/macOS run passed the 113 assertions but had an uncaught networking error. That non-clean run remains recorded; its stack matches [the upstream Undici defect](https://github.com/nodejs/undici/issues/5544). No production workaround or error suppression was added. - `pnpm -r typecheck`, `pnpm build`, and `git diff --check` pass on `bc41ba72be2195eabeb0d7727227ee0cd02e8532`. The maps structural check passes. - The local `pnpm test:run` attempt stopped after host embedded PostgreSQL initialization failures. The relevant database suites pass with isolated PostgreSQL 18. All repository CI gates, including aggregate `ci / verify`, pass on the current head. - Synthetic live provider comparison: 741 invented schemas produced the exact Fireworks grammar timeout in 20.9 seconds. Two compact invented schemas produced a discovery call in 585 ms on the same model and backend. - The first hosted QA attempt exposed the alias failure described above. On the patched source, a real local Rust runner → proxy → OpenCode 1.18.34 → exact DeepSeek smoke completed discovery, one synthetic gateway read, and `paperclip_finish`, then emitted `turn/completed`. It used the production compact projection and unchanged Rust allowlist. - Two earlier local smoke attempts exposed missing terminal authority and completion-contract fields in the smoke harness. Those failures remain recorded. The corrected ordinary bindings produced the clean result. - Fresh Greptile: 5/5 on `bc41ba72be2195eabeb0d7727227ee0cd02e8532`, with no new actionable findings or unresolved threads. - Hosted QA publication and lifecycle acceptance remain pending. The separate deployed-agent `Paperclip Review` check is also pending; it follows a task that failed on the earlier deployed runtime. - Local OpenCode/OpenRouter acceptance at `bc41ba72`: 530 synthetic tools were authorized and installed. A simple model-ID reply completed in 17.3 seconds with no app calls. A discovery task completed in 37.6 seconds, used the search/call relay, made one upstream call, and returned the exact synthetic value. This is local source acceptance, not a staging sandbox timing comparison. - The large-result review finding has a failing-before/passing-after HTTP MCP regression. Five medium schemas now page without invalid JSON. A large schema with escaped text reconstructs exactly through bounded chunks. All 35 assigned-tool tests and the server typecheck pass after this follow-up. - Final head `d84ce4856a6e65a35ad5fb8b561492598b525f4e`: all CI gates pass. Greptile and Paperclip Review both rate the change 5/5. No review threads remain open. The final full build, server typecheck, and 35 assigned-tool tests pass locally. ## Risks - OpenCode uses discovery before it calls an assigned tool, including for small catalogs. This can add a model turn. - An existing OpenCode provider checkpoint rotates once because it retains the former tool declarations. Paperclip task history remains available. - The historical filtered catalog was not captured. The synthetic comparison proves the failure mechanism, not the exact cardinality of an earlier private request. - No model, provider route, permission, or automatic retry policy changes. ## Model Used The bounded-result follow-up also used OpenAI Codex (GPT-6 family). The exact backend model ID and context-window size were not exposed for that session. It used reasoning, code execution, and tool use. OpenAI `gpt-6.1-sol` in Codex, with reasoning, tool use, code execution, and source inspection. The runtime does 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) - [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> |
||
|
|
d64cb7be52 |
fix(ui): identify accounts in AI connection choices (#17738)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agent settings select an authorized AI account independently of the harness and model. > - Multiple accounts can have the same provider name. > - The account picker and legacy adoption dialog showed only that name. > - Operators could not distinguish a personal API key from a shared subscription during credential repair. > - This pull request shows the existing sign-in method, sharing scope, and available account identity before selection and adoption. > - Operators can select the intended account while the existing access and validation checks remain effective. ## Linked Issues or Issue Description Refs #14970 for the shared account selection control. No duplicate account-identity repair was found. **What happened?** Two authorized OpenAI accounts appeared as identical `OpenAI` choices. The adoption dialog repeated that ambiguous name. The list response already contained the account method, scope, and identity, but the UI omitted them. **Expected behavior** An operator can distinguish a personal API key from a company-shared subscription and confirm the selected account before saving. **Steps to reproduce** 1. Make a personal OpenAI API-key account and a shared OpenAI subscription available to an agent. Give both the name `OpenAI`. 2. Open Harness / Runtime and choose a managed connection for a legacy agent. 3. Inspect the two choices and the adoption confirmation. **Paperclip version or commit** Reproduced on master `a1f77821b9cd5c9c846fdf7a0fa5cc620ad2b6bb`. **Deployment mode** Hosted staging and the source UI regression. ## What Changed - Show the sign-in method, personal/shared scope, and available account or owner identity in connection labels. - Use the same label in the selected value and legacy adoption confirmation. Match the confirmation to both the connection and grant. Wrap dropdown choices so narrow screens retain the account identity, and expose the full selected label in the trigger title. - Add a behavioral regression with duplicate provider names, exact grant selection, and disabled unavailable accounts. - Update affected Storybook interaction selectors, the account guide, and the agent verification recipe. ## Verification - Before the fix, the new regression fails because duplicate accounts have no distinguishing metadata. The other 13 field tests pass. - After the fix, all 67 tests in `ui/src/components/ai-connections` pass. The regression selects the exact personal grant and keeps the unavailable option disabled. - `pnpm -r typecheck` and `pnpm build` pass locally. The full `pnpm test:run` command was stopped after embedded PostgreSQL failed to initialize after five attempts in an unrelated native-runtime suite. Its log is retained. Current-head CI partitions must establish full test coverage. - Token gates, map checks, Storybook catalog checks, and all 30 map/catalog contract tests pass. - In local Chrome, the existing production-component Storybook dropdown shows method and scope. Its nine interaction steps pass, as do all 19 steps in the new-agent connection-modes story. At a 320-pixel preview width, two shared OpenAI subscriptions show their distinct account identities in full, including during keyboard selection. These fixtures do not establish provider authentication. - Separately, the staging credential-repair workflow validated an existing authorized shared OpenAI connection, persisted the agent binding across reload, and resumed the original task into real provider/tool execution. This configuration recovery does not deploy this UI patch or establish task completion. - All CI completes on final head `a283bda2ad2f026f4f3c0fee03bf2962b0ad6e02`: 55 successful checks, the neutral Paperclip review, and two intentionally skipped Storybook checks; no pending or failed checks. This includes the partitioned tests, typecheck, build, runner suites, canary, and eight browser shards. Greptile and Paperclip review both rate this exact head 5/5 with no unresolved findings. [CI run](https://github.com/paperclipai/paperclip/actions/runs/40338613167). - The review's selected-trigger truncation finding is fixed in the final head. Its title assertion failed before the fix, and all 67 account-selection tests, UI typecheck, and token gates pass afterward. ## Risks - Labels are longer and can truncate in narrow selected-value controls; the trigger title exposes the complete label. Dropdown choices wrap, and the adoption dialog uses the complete label. - The UI uses existing authorized account metadata. It adds no credential reads, access grants, provider fallback, or account selection policy. ## Model Used OpenAI Codex (GPT-6). The exact serving model identifier and context window are not exposed in this session. The agent used code editing, terminal tests, and browser tools. ## 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> |
||
|
|
0373f9f261 |
fix(recovery): wake retained workspace preservation after Retry (#17741)
## Thinking Path > - Paperclip lets people manage AI agents and their saved work. > - A stopped run can owe workspace preservation before saved input can continue. > - Retry saved a recovery request but did not wake the worker that owns preservation. > - Older recovery records could also take the bounded scan slots before a due request. > - A second Retry could change the revision while the physical owner was still saving files. > - This pull request wakes a separate worker after commit, selects due work first, and keeps the active owner's revision. > - Saved work can progress without replaying the stopped provider turn or blocking other finalization. ## Linked Issues or Issue Description **What happened?** An operator approved a saved design and selected Retry after native workspace finalization failed. The API accepted one canonical request. The source remained scheduled at zero preservation attempts for more than 30 minutes. No new provider turn started. A local regression also found that repeated Retry during export invalidated the physical owner's completion revision. **Expected behavior** Committed Retry must wake bounded source preservation. Due recovery must progress ahead of passive cleanup obligations and unrelated history. Duplicate requests must keep one physical attempt. Saved input must still pass normal admission after verified recovery. **Steps to reproduce** 1. Retain a terminal run with an exhausted workspace recovery and saved authorized input. 2. Let the delivery coordinator become quiet, then request Retry. 3. Observe the recovery state and physical preservation receipt. Repeat Retry while the export is held. **Paperclip version or commit** Observed on served commit `4b89eec644d6e1a99d58926e77ae58927c3fa87b`. Local baseline: `a1f77821b9cd5c9c846fdf7a0fa5cc620ad2b6bb`. Related work: Refs #17053, #17267, #17094. This change repairs explicit Retry delivery. It is separate from the run instruction projection in #17724 and historical unsafe-export discovery in #17687. ## What Changed - Notify a dedicated workspace recovery duty from the transaction that saves Retry, recovery admission, adoption, or recovery progress. - Reconstruct work and saved retry deadlines at startup. Fill each free export slot independently, track physical work for idle drain, and join the dedicated worker's exports on shutdown. - Drain one bounded pass through completed cleanup and saved-input obligations. Restart that pass after committed changes without repeatedly rechecking paused input. - Share source eligibility between deadline selection and candidate consumption. Keep resolved files-only obligations and ignore unrelated resolved or cancelled history. - Select due unfinished preservation before passive historical records. Rotate past source locks held by other workers and retain the indexed source lookup. - Bind the canonical Retry intent without changing an active physical attempt's generation or revision. Preserve that binding across later progress writes. - Add real producer, physical preservation, startup, deadline, idle, and independent finalization regressions. Document the delivery contract. ## Verification - Red controls: Retry without a notification stayed scheduled; duplicate Retry invalidated the active export; whole-batch waiting stranded a third Retry; a scan without cursor rotation starved a source behind two actual advisory locks. Removing unfinished-first selection left HTTP Retry scheduled behind five real recovered sources still owing cleanup. The fixture explicitly verifies their eligibility with the worker's actual query filter. - Further red controls: the previous worker visits only two of three eligible completed sources. Disabling the committed-change cursor reset misses a new earlier source arriving while two callbacks are held. Both pass with the final worker. - Green: the public Retry HTTP route, registered production worker, real file copyback, duplicate canonical receipts, and public recovery receipt reload passed on an owned local fixture. Its agent is paused to keep this files-only check from starting a provider turn. - Full workspace recovery suite passed 56 tests, including the foreign-lock regression. - Execution-control lifecycle suite passed 24 tests. It covers idle SQL, stored deadlines, cancelled and resolved history, independent finalization, and shutdown. One, three, and seven paused completed sources are each visited in a bounded pass, then stay deferred without a successor or SQL during 90 seconds of fake-clock idle time. A committed earlier source is evaluated when it arrives during two held callbacks. - Both GitHub and Telegram `automatic_running` continuation regressions passed with the new canonical intent binding. - `pnpm -r typecheck` passed. - `pnpm build` passed. - `node scripts/check-maps.mjs` and `node scripts/check-module-boundaries.mjs` passed. - Local `pnpm test:run` could not complete: embedded PostgreSQL repeatedly failed to start. The owned run was stopped after this setup failure repeated. Latest-head CI supplies broad coverage. - Earlier setup failures included a localhost sandbox denial and loss of the owned disposable Docker database. These were separate from the product red controls above. - Local database tests use an explicitly named disposable PostgreSQL `_test` database. That opt-in database is reset before the suite. Default embedded test behavior is unchanged. - Exact-head CI is green at `ef7dcf1ba1060864c9d216c33b51f4d9f8f57fbd`; Greptile and Ponytail both rate it 5/5, with no unresolved review threads. Earlier CI caught the indexed discovery assertion and two exact chat intent-binding regressions; all three were fixed and pass locally and in CI. A separate chat shard lost contact with its self-hosted runner without a product assertion result. A later shared runner shutdown interrupted several jobs; one infrastructure rerun passed before the final test-and-worker follow-up triggered a fresh green run. - No staging deployment is part of this PR. The original approval remains saved; deployed recovery still needs acceptance after rollout. ## Risks - More recovery writes now wake a bounded maintenance duty. Completed history must not keep it active. Idle and deadline tests cover this boundary. - Resolved files-only obligations must remain eligible without granting replay. The startup regression checks that path. - Provider stop proof, copyback ownership, source binding, retry budgets, and normal execution admission remain required. There is no schema or public API change. ## Model Used - OpenAI Codex based on GPT-6, with code execution and browser tools. The exact serving model ID and context window 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> |
||
|
|
338bf75761 |
fix(chat): admit task Retry after GitHub reconnect (#17733)
## Thinking Path > - Paperclip manages agents and their tasks. > - Task Retry must preserve saved input and enforce current access. > - A GitHub reconnect invalidates old runtime callbacks. > - Retry reused that old callback authority and rejected valid new intent. > - Retry also replayed an older failed request when a follow-up was already saved. > - This change admits a deliberate Retry under current authority and transfers saved input once. ## Linked Issues or Issue Description Refs #16965, #17053 and #17317. These repairs preserve work and contain old executors. This change fixes the subsequent chat admission boundary. A search found no overlapping open reconnect/admission fix. **What happened?** Ordinary task Retry returned `chat_failed_run_retry_not_authorized` after the same GitHub App reconnected. The endpoint was healthy, but the saved request still carried its old runtime generation. A newer queued follow-up also made Retry reject the older failed request instead of continuing the follow-up. No successor was admitted. HTTP qualification found two related defects. Concurrent clicks could omit the canonical chat action from a response. Signed-in board dispatch also passed an incomplete task resource to the permission resolver, which rejected a permitted mutation. **Expected behavior** A deliberate Retry checks current authority for the same App, sender, repository, conversation and task. It continues saved input once. A later reconnect, changed App, revoked access or changed source prevents dispatch. Old runtime callbacks remain invalid. **Steps to reproduce** 1. Admit a GitHub request and record a failed native run. 2. Save a follow-up while execution is blocked. 3. Reconnect the same GitHub App. 4. Click ordinary task Retry. 5. Before this change, admission returns 409. Without reconnect, the newer input alone also causes 409. **Paperclip version or commit** Baseline source: `41c42895fa862c586ff841f8c50200d93ffc83a4`. **Deployment mode** Source checkout on macOS. Regressions use real PostgreSQL transactions and the assembled chat, HTTP route and heartbeat admission services. Provider boundaries are simulated. No hosted recovery is claimed. ## What Changed - Record the admitting App identity for new GitHub deliveries. Historical deliveries can use their original working-comment binding. Reauthorize deliberate Retry under a pinned current generation and credential-reference fingerprint. - Select the complete saved-input queue from the failed run's actual conversation before replaying the older failed batch. Keep exact-run Retry bounded while ordinary task Retry supports larger queues. Transfer its receipts with the dispatch transaction. Recover the same ownership after restart or a lost response. Release unadmitted input after a definitive rejection. - Preserve canonical chat action IDs across concurrent clicks. Supply current task status and assignment fields to board mutation checks. - Keep exact-run Retry, stale webhook, containment, source integrity, publication, pause and budget checks. Update recovery contracts and verification recipes. ## Verification - Red: all three new PostgreSQL regressions failed on unchanged production code. Reconnect failed at chat authorization. Newer input failed at the obsolete-source guard. The combined case also failed. - Green: 61 selected chat integration cases passed. These include 27 new cases and 34 existing cases for containment, retained-source recovery, exact batches and source revocation. - A further red/green PostgreSQL regression reproduces the 51-message overflow identified during review. All 51 messages reach one successor, including a later Retry of that successor. A separate 52-message consumed-batch regression also passes. - A competing conversation retains its own deferred message. Distinct automatic policy contexts are checked independently; revoking only the later policy blocks the whole unadmitted batch. Batch validation still rejects a later message with a changed App binding or deleted source. A real PostgreSQL query capture reduced the 51-message preparation from 1,103 calls to fewer than 180. - All 16 durable task Retry tests passed. - The real HTTP route returns 202 and admits one queued successor for concurrent deliveries. Fault injection covers rollback during input handoff, response loss after dispatch commit, and permission loss when resuming an existing durable wait. A wait only adopts input after current admission succeeds; a one-shot settlement marker keeps status projection read-only. A new deliberate Retry works after another reconnect or a failed successor. - Current-App, repository, sender, source edit/delete, reassignment, endpoint pause and board-permission controls passed. Historical deliveries remain unchanged. - Final-head CI: 55 checks passed, three expected skips. The unchanged minute-bucket rate-limit assertion passed locally against PostgreSQL and on its one CI rerun. Greptile reviewed the final commit at 5/5 with no unresolved threads. - Workspace typecheck and full build passed. Map alignment, module boundaries, UI token gates and `git diff --check` passed. - Hosted task recovery and a live provider turn remain unverified. The local tests hold agent capacity to inspect admission without starting a model or publishing a GitHub response. ## Risks - A deliberate GitHub Retry can admit old saved input under current connection authority. It requires the same App binding and current access. It pins that admission; it does not rewrite the historical delivery or make stale callbacks valid. - The durable chat queue has an optional admission callback. It transfers input only when the transaction contains a valid queued execution or saved wait. Other chat consumers have no callback and retain their behavior. - No migration, Cloud dependency, deployment, configuration change or workspace cleanup is included. ## Model Used OpenAI GPT-6 through Codex, with reasoning, source inspection, code execution and GitHub tools. The exact serving 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> |
||
|
|
ad861a7f94 |
fix(runner): allow bounded controller admission before welcome (#17735)
## Thinking Path > - Paperclip manages AI agents and preserves their work across execution failures. > - Native Runner authentication exchanges a one-use bootstrap ticket for a connection lease. > - The controller must admit the connection and persist that lease before it sends welcome. > - Runnerd waited only two seconds for welcome, even when its connection setup budget allowed more time. > - A slow valid welcome therefore looked like a consumed-ticket failure before provider work could start. > - This pull request uses the existing ten-second connection setup budget for welcome. > - The benefit is reliable startup during bounded controller delays, with the same authentication and replay checks. ## Linked Issues or Issue Description **What happened?** A valid native Runner bootstrap can fail while the controller completes admission. The runner then reports `bootstrap connection failed closed; provide a fresh one-use ticket`. A later recovery attempt can report an indeterminate authority and hide the startup error behind a finalization deadline. **Expected behavior** A valid welcome can arrive within the connection setup budget. An earlier execution or reconnect deadline still ends the wait. A missing or invalid welcome never permits bootstrap-ticket replay. **Steps to reproduce** 1. Run the real Runner WebSocket transport against an authenticated controller. 2. Hold the welcome for three seconds after the client proof arrives. 3. Before this change, authentication fails with `WebSocket authentication message deadline elapsed` and `bootstrap_maybe_consumed: true`. 4. With this change, the runner accepts the bound lease and restores the normal read timeout. **Paperclip version or commit** Reproduced against `a1f77821b9` before the production change. **Agent adapter(s) involved** Native Paperclip Runner. The transport is shared by its provider drivers. Related: #17401 reduces repeated work in warm-recovery admission. This change covers delayed welcome delivery for fresh authentication too. It does not replace that optimization. #17594 addresses a separate lifetime failure after controller outages. ## What Changed - Use the ten-second connection setup budget for the authenticated welcome. - Keep the execution/reconnect deadline as an earlier bound. - Add real WebSocket regressions for a delayed welcome and a shorter lifecycle deadline. - Add a real Runner process test proving a delayed admission starts one provider and keeps it through two turns. - Document the startup contract and its recovery verification scope. ## Verification - Red: the delayed-welcome regression failed against unchanged production code with a message deadline and `bootstrap_maybe_consumed: true`. - Green: all 402 Runner core library tests pass. The suite includes authentication, ticket fencing after a lost welcome, identity rejection, replay, and no repeated provider effects. - Map and module checks pass. - Workspace `pnpm -r typecheck` and `pnpm build` pass. The new process integration test passes (one provider process, one thread, two turns, suspended with an empty outbox). - Live acceptance at this branch's production Runner build passes on macOS arm64 with pinned OpenCode 1.18.34 and `openrouter/deepseek/deepseek-v4.1-flash-1017`: delay admission by three seconds, create a file, suspend, resume the same provider session under a fresh run authority, read the first file, and write a second file. Both useful outputs match exactly; final runner state is suspended. - Preserved setup failures: a non-pinned executable was rejected, and the debug binary exceeded cold provider startup admission. The pinned executable and release binary passed. The first harness also tried to reuse a completed task object; the follow-up used the normal resume path. Exactly two paid model turns ran. - The full local `pnpm test:run` was attempted and stopped after the Mac exhausted PostgreSQL semaphore capacity (`could not create semaphores`); it is not a local full-suite pass. - Current-head CI is green at `df5d5494c9f9f444114aaf12e095a554110d2e14`: all checks passing or non-applicably skipped, zero failures or pending checks. The additional Superagent security scan triggered by ready-for-review also passed. These include all general/serialized test shards, Runner Rust/Vitest, E2E, typecheck, build, and the final verify gate. Greptile reviewed that exact commit at 5/5 with no findings or inline comments. - This proves the actual native Runner/provider path locally. It does not prove rollout or recovery on a hosted Linux/amd64 execution environment. ## Risks - A stalled welcome can take up to eight seconds longer to fail when the configured lifecycle allows it. Shorter execution/reconnect deadlines still take precedence. - Authentication proofs, credential expiry, identity binding, and one-use-ticket fencing remain enforced. - This does not repair provider-side grammar errors or authorize replay of an indeterminate historical run. Recovery of existing work requires the normal stopped-owner and retained-state checks. - No schema or migration change. A new Runner binary must reach the execution host before this change affects remote runs. ## Model Used OpenAI GPT-6 through Codex, with reasoning, repository inspection, code execution, and browser tools. The exact serving submodel identifier and context window were 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> |
||
|
|
a1f77821b9 |
perf(tasks): show recent conversation before historical activity (#17593)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - A task page must show the instruction and current conversation
quickly.
> - The current page waits for related task data and historical run
transcripts.
> - These reads grow with task history, even when the reader only needs
the latest answer.
> - This pull request gives cold opens a small initial view and loads
older history on demand.
> - Messages and runs observed while the page stays open remain visible.
> - The benefit is a readable task before historical diagnostics finish
loading.
## Linked Issues or Issue Description
Related: #14667 and #16229. The first changes the reveal gate and scroll
anchors. The second adds general history pagination. This PR adds a core
task read and a folded recent-conversation view. It preserves the
default full-read API contracts. The shared files will need coordination
if either related PR lands first.
**What existing behavior does this improve?**
Cold opening an ordinary task with a long conversation or large run
logs.
**Current behavior**
Task enrichment and historical transcripts delay the readable
conversation. A cold open can fetch several megabytes of tool activity
before revealing saved messages.
**Proposed behavior**
Show the task instruction, recent saved replies, latest human input, and
the latest run's conversation data first. Fetch older messages and full
run activity when the reader chooses **More messages**. Retain new
messages while the page stays open.
## What Changed
- Add an authorized core issue view that skips related enrichment. Keep
enrichment on the existing detail read. Share task mutation, rollback
and invalidation updates with the core cache.
- Add a bounded recent-comment read. Preserve the first human
instruction when no description exists, including legacy rows with a
NULL author type. Keep company and task access checks and comment
redaction.
- Add optional recent activity and run-summary views. Fetch original
input receipts for visible comments separately so delivered messages
stay out of the queue. Reconcile watched unfinished runs after a
reconnect beyond the preview window, removing deleted runs after
reconciliation.
- Filter the latest native run's initial events to assistant messages,
request lifecycles and terminal results. Full event reads remain
available on expansion. Legacy fallback reads use a small tail extended
to the first complete record. HTTP cancellation aborts the storage read.
- Retain observed messages across cursor catch-up and new runs. Apply
local cancellation and deletion to both caches and their task aliases.
Refetch locally seeded history pages on expansion. Preserve expansion
across identifier and UUID links. Keep deep links, classic tasks and
Agent Chat on their existing full-history path.
- Update API documentation, design guidance, capability maps and
regression coverage.
## Verification
- Final acceptance on `9ea0b15ae44d9f6d2c9a9f824b4835f299f92979`: all CI
gates passed, including server/UI tests, all eight browser shards,
runner checks, full typecheck and build. [Final CI
run](https://github.com/paperclipai/paperclip/actions/runs/40326990328).
GitHub reports 55 successful checks, two intentionally skipped checks,
and one neutral Paperclip Review check described below. No checks are
pending or failed; Greptile is 5/5 and no review threads remain open.
- October 26 merge update: merged current `master`. The only conflict
was in task-page imports; both the compact-history hook and the new
live-update hooks remain. All CI tests and build jobs passed on
`044fd6733d`. Fresh review found canceled-comment cache drift, legacy
human-comment filtering, send-then-expand truncation, and partial legacy
log records. These defects were fixed in `af3d66a5bd`.
- Review-fix verification: 470 tests pass across ten affected suites,
including all six PostgreSQL cold-open tests without a helper override.
Cancellation/delete and send-then-expand regression tests failed before
the fixes and pass afterward. Coverage includes task identifier/UUID
reopen, stale in-flight reads, legacy NULL author types, local-file and
object-storage tails cut inside UTF-8 text, route forwarding, and
request cancellation. Full workspace typecheck and production build,
token gates, map validation and diff checks pass.
- Follow-up review found that a failed expanded legacy read lost its
record-alignment state on retry. `9ea0b15ae4` commits the expanded
window only after a successful read. The new regression fails before the
fix and passes afterward; all 19 transcript tests, UI typecheck, UI
build and token gates pass. Greptile reviewed this commit at 5/5 with no
actionable findings, and all review threads are resolved.
- The final Paperclip Review check ended neutral because its execution
did not complete; no passing Paperclip assessment is claimed. Its
earlier four concrete findings were fixed and regression-tested.
Greptile and the security scans completed successfully on the final
commit.
- The preceding `af3d66a5bd` CI run was canceled when superseded by the
retry fix. Its server shard 11 check briefly reported failure, but the
job API records cancellation and its test step passed all 1,750 tests.
This superseded run is not used as final CI acceptance.
- 549 focused tests pass on the final implementation across nine task
UI, activity-route, OpenAPI and PostgreSQL suites. These cover pending
history, desktop/mobile visibility, expansion, retained runs, message
bursts, cancellation recovery and queued-comment removal in both views.
- Legacy expansion keeps the latest answer visible while fetching and
deduplicating older output.
- Five PostgreSQL tests pass for core access denial, recent comments,
missing-description instructions, event paging and bounded activity/run
reads. macOS could not start another PostgreSQL cluster because it
exhausted its semaphore limit. These tests used a separate disposable
database on an existing local server through a temporary test setup
override. The helper was restored afterward.
- Full workspace typecheck and build pass with the final state fixes, as
do token gates and capability-map validation.
- Token gates, capability-map validation and `git diff --check` pass.
- Browser proof used a disposable task with 80 comments and six large
run histories. The cold view showed the instruction and recent exchange.
**More messages** revealed older comments. Navigation away and back
preserved expansion.
- Local HTTP sample: core 50 ms, recent comments 24 ms, recent run
summaries 17 ms. The latest native conversation response was 839 JSON
characters / 8 ms; its full event response was 1,099,005 / 86 ms.
Browser content paint was 1.34 seconds with development assets cached.
These are local observations, not staging latency claims.
- The first CI run passed every job except four board-send browser cases
and the review threshold. Those browser fixtures only mocked the old
comments endpoint; they now serve both recent and full reads, retaining
all message and attachment assertions. Both initial review findings were
fixed with regression tests. The next CI run passed every job. The
deeper review identified core-cache mutation, older delivery receipt and
retained run-status gaps; those are now fixed with regression coverage.
Final review is 5/5 with zero unresolved findings. Final-head CI
initially failed one unchanged runner shutdown test
(`runnerd-codex-transport.test.ts`, timeout-attachment case) with
`NativeSessionCloseUnrecoverableError`; all other CI jobs passed. The
same runner code passed on
|
||
|
|
4b89eec644 |
fix: check selected workspace projects before offering retry (#17552)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Task recovery explains access failures before a user retries saved work. > - A task project and its selected workspace are separate settings. > - Moving a task can retain files from a project that the agent cannot access. > - The recovery notice checked only the task project or a past failure record. > - This pull request checks the projects required by the current workspace selection. > - The notice now offers Retry only after those project checks pass. ## Linked Issues or Issue Description Follow-up to #17509. Related: #13230 concerns workspace binding consistency; this fix changes recovery presentation only. **What happened?** A task could show “Project access is ready” after moving to an allowed project while keeping a repository from a denied project. Typed failures could also keep the notice blocked after an authorized workspace replacement. **Expected behavior** Use the current task, workspace, and source project requirements. Honor a valid pending selection for the next admission. Keep stale, archived, or missing selections blocked without offering a project-permission repair. **Steps to reproduce** 1. Assign a low-trust agent to a task whose selected source belongs to a denied project. 2. Persist a project access failure. 3. Move the task to an allowed project without changing its selected files. 4. Reload the task. The notice must still explain the access block. 5. Select an allowed source through the workspace API. Reload the task. The notice must offer an explicit retry without starting work. **Paperclip version or commit** Reproduced after #17509 on master. The regression failed on the old projection and passed with this change. ## What Changed - Batch the current workspace project requirements for tasks with project access failures. - Check retained workspace and source projects, plus valid pending workspace selections. - Keep unknown historical denial projects unnamed. Do not expose unrelated project identifiers. - Keep unavailable workspace selections in the non-retryable failure state. Adding project permissions cannot repair these selections. - Add real database regressions for project moves, pending and applied repairs, stale revisions, archived pending selections, and foreign-company workspaces. - Update the recovery contract and verification recipe. ## Verification - Red-green regression with the real issue update service and execution access check. - Focused tests: 17 tests passed across `agent-project-access.test.ts` and `task-interruption-presentation.test.ts` after rebasing on current master. - Browser: the retained source stays blocked when the task project is allowed. Manage project access opens Permissions / Trust with Allowed projects and Add project. - The normal workspace API accepted an allowed pending selection. Returning to the task showed “Project access is ready” and Retry. Permissions and run count did not change. - Full repository typecheck and build passed before the final presentation adjustment. The final adjustment passed server typecheck, server build, and all 17 focused tests. The stale, archived, and foreign-workspace cases failed before this adjustment. Map and module-boundary checks passed. - Browser: an archived pending workspace shows the existing failure notice without Retry or a project-permission action. - `pnpm test:run` was attempted and stopped after 15 native runtime database tests failed because embedded PostgreSQL could not initialize on this host. The focused database tests passed on isolated PostgreSQL 18 in Docker. All technical CI checks passed on `a6e9f977`. Fresh CI and review are required for the presentation adjustment. One Runner shard passed on its single rerun after a provider shutdown failure. A fresh local Runner build also passed that case and its reuse sibling. The prior Paperclip Review could not publish its assessment. Its saved presentation finding is addressed. Merge waits for a fresh published review and all checks on the current head. ## Risks - Presentation must follow workspace selection precedence. Tests cover retained bindings, valid pending changes, stale changes, and company isolation. - This adds at most three bounded reads for tasks with a project access failure. It adds no reads for this purpose on unaffected tasks. - Dispatch remains the authorization authority. This change does not grant access, move files, or start execution. No migration is required. ## Model Used OpenAI Codex, GPT-6, with reasoning, repository inspection, code execution, and browser tools. The exact serving model identifier and context window were 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 - [ ] All Paperclip CI gates are 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 --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |