mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-10 20:50:08 +02:00
44e4979d23bfb0728baad89f844033e1b77faefe
1531
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
44e4979d23 |
Capture project and repository update lifecycle events (#15306)
## Thinking Path > - Existing lifecycle capture records agent transitions and project creation. > - Project and repository edits need matching project update records. > - The record must commit with the mutation so failed writes cannot lose a hook. > - Creation with repositories is one creation, and repository replacement is one update. > - Archive-only changes preserve project state without creating a hook. > - Plugin consumption and provider behavior are separate work. ## Linked Issues or Issue Description **Problem or motivation** Project edits and repository/workspace changes lack durable lifecycle records. A future resource plugin needs those changes captured alongside the existing project creation hook. Archive-only changes must produce no hook. **Proposed solution** Allow project `update` records in the existing lifecycle journal. Record project and workspace mutations in their database transaction while holding the project row lock. Suppress intermediate workspace hooks during project creation and aggregate repository replacement. **Alternatives considered** Route-only hooks miss shared service callers. Recording after commit can lose an event. Emitting a hook for each child mutation exposes intermediate repository state. **Roadmap alignment** This completes project lifecycle capture begun in #15280. Plugin delivery, VM/volume provisioning, and backfill remain separate. Searches found no duplicate project lifecycle work; related #13306 concerns decision events on the in-process plugin bus. ## What Changed - Record project edits and workspace additions, updates, and removals as project `update` events. - Commit each event atomically with its mutation under the project row lock. - Keep project creation with repositories to one creation event and repository replacement to one aggregate update. - Ignore archive-only changes and retain workspace records. - Extend the journal action constraint and document project update capture. ## Verification - `pnpm -r typecheck` passed on the narrowed scope. - 57 tests passed across six lifecycle, project, repository, and chat-project suites. - Seven managed-sandbox workspace route tests and the CLI lagging-worktree migration regression passed (65 targeted tests total). - Full GitHub CI passed on `8ba6f97f22`; all required gates are green. - Greptile scored the final project-only commit 5/5 with zero unresolved review threads. - The branch is current with `master` and has no merge conflicts. - `git diff --check` and a local secret/PII scan passed. ## Risks - Apply migration `0300_chunky_chamber.sql` before running the new server. It permits project update actions and tolerates older JavaScript worktree backups that omitted the prior CHECK constraint. - Event-write failure intentionally rolls back the project or repository mutation. - Records contain identity and action; future consumers must load current authorized project/workspace data. - Plugin consumption, provider calls, volume cleanup, and backfill are outside this PR. ## Model Used OpenAI Codex, based on GPT-6, with reasoning, repository inspection, code execution, and tool use. The exact deployment 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> |
||
|
|
1477d1ecea |
test: remove the no-op sequential describe modifier (#15286)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Paperclip runs the server and runner test suites with Vitest. > - Vitest 5 removes the deprecated `describe.sequential` property, so the pending Vitest 5 upgrade fails the type-check and test jobs. > - `describe.sequential` only changes behaviour inside a `describe.concurrent` suite, or when `sequence.concurrent` is on. > - This repository has neither, so the modifier changed nothing at run time. > - The benefit is that the Vitest 5 upgrade can land, and the test files lose a modifier that did no work. ## Linked Issues or Issue Description Refs: #12969 ## What Changed - Replace every `describe.sequential` use with a plain `describe` call. - Drop the `{ concurrent: false }` suite option from the two runner test files. - Add a comment to `server/vitest.config.ts` that records why these suites must run one test at a time. - Leave the package manifests and the lockfile unchanged. ## Why the modifier did nothing The Vitest documentation states that `describe.sequential` is useful to run tests in sequence inside a `describe.concurrent` suite, or with the `--sequence.concurrent` option. `sequence.concurrent` defaults to `false`. This repository satisfies neither condition: - No test file uses `describe.concurrent`, `it.concurrent`, or `test.concurrent`. - `server/vitest.config.ts` sets `sequence.concurrent: false`, with `maxWorkers: 1`, `maxConcurrency: 1`, and `isolate: true`. - `packages/paperclip-runner/vitest.config.ts` sets no `sequence` block, so the `false` default applies. `packages/db` and `cli` already run the same embedded-Postgres suites with a plain `describe`, and those jobs are green. The server package was the only outlier. The modifier did carry one real piece of knowledge: these suites need their tests to run one at a time. The new comment in `server/vitest.config.ts` records that reason next to the setting that enforces it. ## Verification - `git grep` for `describe.sequential` returns nothing outside `node_modules`. - The author ran the changed server test files under the installed Vitest 4, and the results match the results without this change. - Two very large embedded-Postgres test files exceeded the author's local memory limit, so the CI test jobs cover those two. - The two changed runner test files have pre-existing local failures caused by a missing Rust toolchain and a missing global `pnpm` binary. The failures are identical with and without this change. - The author type-checked the changed files and found no new error. - CI must pass the typecheck, build, server test, and runner verify jobs. ## Risks - Low risk. Suite execution stays serial, because the Vitest config enforces it. - The change adds no dependency and changes no package manifest or lockfile. - A future change that turns `sequence.concurrent` on would break these suites. The new config comment warns against it. ## Model Used - Claude Sonnet 5 — code edits and local verification. - OpenAI Codex, GPT-5 — the earlier revision of this branch. ## Test plan - [x] Every CI check reaches a terminal green state. A pending or queued check is not a pass. - [x] The `Typecheck + Release Registry` job passes. This change must not introduce a type error. - [x] The `Build` job passes. - [x] The server test jobs and the runner verify jobs pass. - [x] Greptile re-reviews this commit set and posts a passing verdict. The dependabot waiver does not apply to this pull request. - [x] `mergeable` reads `MERGEABLE` as a terminal value. ## 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 linked the related public issue with `Refs: #12969` - [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: Priya Raman <priya.raman@paperclip.ing> --------- Co-authored-by: Priya Raman <priya.raman@paperclip.ing> Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> Co-authored-by: nickyleach <331803+nickyleach@users.noreply.github.com> |
||
|
|
90182b4f8b |
Report bounded Cloud portfolio failure diagnostics (#15340)
## Thinking Path > - Paperclip manages work for AI agents and their companies. > - Cloud instances proxy a trusted user's portfolio through the control plane. > - A failed request returns a generic error to the client. > - That replacement error loses the failure phase and network code in Sentry. > - Operators need bounded evidence without upstream messages or credentials. > - This PR adds safe diagnostics while preserving the existing request behavior. ## Linked Issues or Issue Description Refs #10850, which added the portfolio proxy. No open PR for this diagnostic gap was found. **What happened?** A rejected portfolio fetch becomes a generic 502 in Sentry. The event cannot distinguish a connection reset, deadline, HTTP response failure, or body failure. The route's previous warning also included the original error and a stack identifier. **Steps to reproduce** Make the portfolio proxy's fetch reject with a TypeError whose cause has `code: ECONNRESET`. The client correctly receives the generic 502, but the captured replacement error loses that code. **Expected behavior** Keep the existing client response. Attach only bounded server-side diagnostic fields to the failure event. Do not retry the request or expose the original error. ## What Changed - Add a typed portfolio error with a private frozen diagnostic record: phase, upstream HTTP status, elapsed milliseconds, and an allowlisted network code. - Read at most four error/cause objects through own data properties. Unknown codes, messages, getters, and out-of-range values do not enter the record. - Replace the route's raw-error warnings with safe fields. Send a plain error plus event-local context through the existing optional Sentry gate. Keep the route callsite and default fingerprint policy. - Preserve authentication, trusted headers, cookies, exact HTTP error bodies, cache behavior, the ten-second deadline, and one fetch per request. Public responses receive no diagnostic fields. - Document the fields and test HTTP behavior, privacy, and event isolation with the real Sentry SDK. ## Verification - `PAPERCLIP_REQUIRE_SENTRY_TEST_SDK=1 pnpm exec vitest run server/src/__tests__/cloud-portfolio-error.test.ts server/src/__tests__/cloud-routes.test.ts server/src/__tests__/sentry.test.ts server/src/__tests__/run-failure-sentry-real-sdk.test.ts`: 65 passed, with the audited optional SDK installed. - Full local `pnpm -r typecheck` and `pnpm build` passed on Node 24.21.0 and pnpm 9.15.4. - Independent review found no blockers and independently passed all 65 tests, including the real SDK checks, on this exact commit. - Full Linux CI passed on this exact commit and provides aggregate suite coverage (54 successful checks, 2 intentional skips). A duplicate full local aggregate was not run. - The first SDK contract job failed before tests when npm could not resolve an OpenTelemetry transitive package. A subsequent empty-cache install first encountered a missing tarball, then succeeded after the registry artifact became available. All 6 real-SDK tests passed against that fresh install; the single unchanged-head CI retry passed. The SDK pin, workflow, and dependency files are unchanged. - The first browser shard 8 run timed out waiting for the inbox retry reply after 45 seconds. The unchanged isolated case passed (1/1), and the test, UI handler, fixture, and recovery files match the base commit. The failed log contains no wakeup POST before the test's immediate navigation; a navigation/request timing race is suspected but unproven without a trace. The single unchanged-head shard retry passed (20 passed, 1 skipped); no timeout or source change was made. - Greptile reviewed this exact commit at 5/5 with no unresolved review threads. - No live portfolio request was replayed. Route tests use controlled local upstream responses. - The added diff passed the secret and PII scan and `git diff --check`. ## Risks This is a diagnostic change. It does not identify or repair the origin of a connection reset. Unknown transport failures remain `unknown`. Elapsed values outside 0–60,000 ms become null. Default Sentry fingerprinting remains enabled; exact historical group membership is not guaranteed. No retry, migration, deployment, or configuration change is included. ## Model Used OpenAI GPT-6 through Codex, with reasoning, repository editing, code execution, and independent agent review. The exact deployment 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> |
||
|
|
9b3fe260ba |
fix(tasks): surface Codex ChatGPT model rejection (#15299)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Native Runner runs report provider errors and can also save a structured failure result. > - Codex rejects a model that the user's ChatGPT account cannot use. > - Master now diagnoses this rejection, but the task's compact run data omits its message. The thread can still call it a generic run failure. > - Users need the account restriction and a clear step to repair the model selection. > - This pull request shows the existing diagnosis as “Model unavailable” on the task. ## Linked Issues or Issue Description **What happened?** Codex returns HTTP 400 with `invalid_request_error` and the message `The 'gpt-6.1-sol' model is not supported when using Codex with a ChatGPT account.` Master now stores an actionable diagnosis for this rejection. The task thread still labels it “Run failed” and does not receive its error text in compact run data. **Expected behavior** Show the account restriction on the task and in the run error. Tell the user to choose a supported model or clear the task's model override before retrying. **Steps to reproduce** 1. Use a Native Runner Codex agent signed in with a ChatGPT account. 2. Select a model that produces the rejection above and start a task. 3. Let the runner save its generic failed result. Inspect the task's failure marker and recovery notice. **Additional context** Refs: #15304. That merged PR diagnoses the provider failure and preserves worker and review recovery rules. This PR adds its task-facing message and guidance without changing that diagnosis or those rules. Refs: #13134. That PR improves model discovery for ChatGPT accounts. This PR exposes the rejection when a configured model still fails at execution time. ## What Changed - Return a bounded model rejection message in compact issue-run data. - Show “Model unavailable” and model-change guidance in the task thread and recovery notice. - Add database and UI regression tests, including both the original rejection text and master's fixed diagnosis. Document the new failure message. ## Verification - Focused merged-branch validation: 279 tests passed across activity service, native provider failure observation and PostgreSQL integration, TaskChatThread, and ExecutionBlockerNotice. - `pnpm -r typecheck`, `pnpm build`, and `pnpm check:token-gates` passed on the merged source tree. - Greptile reviewed conflict-resolution commit `1db39c4e636a92e2e76ba224b71c6f1e2f556c81` at 5/5 with no findings or inline comments. - All 55 check runs completed without failure on that commit. The two optional Storybook jobs were skipped. The legacy Snyk status passed. The branch has no merge conflicts. - UI regression assertion: the task's failure marker says “Model unavailable” and retains the account restriction. It no longer says that this failure happened after a final response. ## Risks - Provider recognition and recovery are owned by the existing master implementation. This PR exposes only bounded error text for failed runs with `native_provider_model_rejected`. - Historical runs with the generic `adapter_failed` code are not reclassified. No stored run is rewritten. - Existing retry and reconciliation gates remain in place. No schema migration or model configuration change is required. ## Model Used OpenAI Codex, based on GPT-6, with reasoning, code execution, and browser inspection. The exact deployment 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> |
||
|
|
a1ab55a56d |
fix(agents): grant configuration access by default (#15283)
## Thinking Path > - Paperclip manages agent work and permissions for a company. > - Agent setup can require one agent to configure another agent. > - New standard agents could create agents, but they had no direct configuration grant. > - Existing agents must keep their current permissions after an upgrade. > - The requested new-agent defaults include 13 more direct permissions for suggestions, skills, tools, audit, inbox, and task assignment. > - This pull request adds the 14-grant set at creation and approval activation, retains it through invitations, and keeps existing agents unchanged. > - The change keeps low trust and built-in agents on their narrower permissions. ## Linked Issues or Issue Description **What existing behavior does this improve?** The agent creation and approval flows, and the agent configuration authorization path. **Current behavior** A new standard agent can create an agent. It cannot make protected changes to a peer agent unless an operator adds an `agents:configure` grant. **Proposed behavior** Add direct grants for `agents:configure`, `agents:suggest-changes`, `skills:create`, `skills:suggest-changes`, `tools:manage_connections`, `tools:manage_profiles`, `tools:view_audit`, `audit:view_agent_actions`, `tools:use`, `tools:manage_runtime`, `inbox:manage`, `tasks:assign`, `tasks:assign_scope`, and `tasks:manage_active_checkouts` to new standard agents. Scope `tasks:assign_scope` to the agent’s reporting subtree. Keep existing agents and their grants unchanged. **Reason and benefit** New standard agents can complete agent setup and the requested tool, skill, inbox, and task workflows under existing route, scope, and approval checks. **Breaking changes** Existing agents keep their current permissions. There is no permission migration. Related PR: #12212 adds scoped grant routes. This PR changes the default grant. ## What Changed - Add the 14 requested direct grants in agent creation and approval activation. Keep them when invitation approval replaces grants, preserving explicit scopes. Remove them when an agent is deleted. - Apply defaults only to new agents. Remove the existing-agent permission migration, its snapshot, and its journal entry. Preserve existing scoped grants. - Add permission, scope, invitation, and existing-agent regression tests. Document all default and excluded permissions. - Prevent agent keys from creating, changing, or restoring host-executed process or local adapter command settings, and from restoring workspace commands through rollback. ## Verification - Run `node_modules/.bin/vitest run server/src/__tests__/agent-default-configure-grants.test.ts server/src/__tests__/invite-join-grants.test.ts packages/db/src/migration-snapshot-drift.test.ts`. All 15 tests pass. These cover new-agent defaults, unchanged existing grants, pending approval, invitation grants, and migration history. - Run `node_modules/.bin/tsc -p server/tsconfig.json --noEmit`. It passes. - Run `packages/db/node_modules/.bin/tsx packages/db/src/check-migration-numbering.ts` and `packages/db/node_modules/.bin/tsx packages/db/src/check-migration-safety.ts`. Both pass. - Confirm that this PR has no files under `packages/db/src/migrations/` in its final diff. - GitHub CI at `e8173b2c41` passes build, typecheck, server suites, browser shards, and canary verification. One unchanged OpenCode transport test reached its five-second timeout in the first Runner shard run. That test passes locally in 2.55 seconds. The shard passed on one retry. All 54 checks pass, with two expected skips. - Greptile gives this exact head 5/5. Security review passes. The PR has no unresolved review threads or merge conflicts. ## Risks - The 14 default permissions apply only to new standard agents. Existing permissions stay unchanged. Low trust and managed built-in agents are excluded. - New grants include connection, runtime, and active-checkout management. Existing company, responsible-user, scope, and approval checks remain in force. The default inbox grant carries a responsible-user-only scope so it cannot override another user's inbox settings. - Protected changes still need the responsible user's authority when that check applies. Company boundaries and approval gates still apply. - Agent-authenticated requests cannot configure process adapters or host command settings on local adapters. Known provider credential references remain allowed, as do narrow plain authentication overrides on new peers when the caller uses an AI connection pool. Arbitrary environment settings remain blocked. Board operators retain the host configuration paths. > I checked `ROADMAP.md`. This is a narrow fix to existing agent configuration behavior. ## Model Used - OpenAI Codex, GPT-6 series. This runtime did not expose its exact hosted model ID or context window. This revision uses OpenAI GPT-6 through Codex with tool use, code execution, and tests. The runtime does not expose the exact hosted model ID or context window. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
f858207161 |
Guard routine UUID lookups without narrowing valid inputs (#15313)
## Thinking Path > - Paperclip manages work for AI agents and their companies. > - Routines expose details, triggers, and management actions through resource IDs. > - These resource IDs are UUIDs. The UI and CLI do not resolve short prefixes. > - A malformed ID reaches a PostgreSQL UUID comparison and returns a server error. > - A lookup guard can return the existing not-found response before that query. > - This PR preserves valid PostgreSQL UUID input forms and the existing access checks. ## Linked Issues or Issue Description Refs #11471. This is a credited continuation of the lookup-guard approach from @mv2woods. That older PR remains open and unchanged. Its review requested the required PR description sections. This continuation uses current master and adds UUID compatibility and authorization coverage. The earlier `isUuidLike` guard restricts UUID versions to 1–5 and trims input. The database currently accepts other UUID values and input forms. This guard preserves the existing [PostgreSQL UUID input contract](https://www.postgresql.org/docs/current/datatype-uuid.html), including uppercase, paired braces, omitted hyphens, and hyphens after groups of four digits. It rejects whitespace and short prefixes without rewriting the value sent to the database. ## What Changed - Guard the shared routine and private-trigger UUID lookups. Malformed resource IDs return null, so existing routes return their normal 404 response. - Keep company access, assignee permissions, body validation order, and database error propagation unchanged. - Add real PostgreSQL tests for stored UUIDv4, UUIDv7, nil, and max values in six input forms. Add no-query checks for malformed input and HTTP coverage across all 15 root-resource route handlers. - Document complete resource IDs and distinguish them from opaque public webhook IDs. ## Verification - `pnpm exec vitest run server/src/__tests__/routines-service.test.ts server/src/__tests__/routines-e2e.test.ts`: 91 passed, including the new PostgreSQL and HTTP regressions. - Independent review found no blockers and passed all 9 focused PostgreSQL and HTTP regression cases on this commit. - Full local `pnpm -r typecheck` and `pnpm build` passed on Node 24.21.0 with pnpm 9.15.4. - Full Linux CI passed on `0a2990eca2f904335821027a322e4db868151eb3`: 53 successful checks and 2 inapplicable Storybook skips. No retries were needed. This provides aggregate suite coverage; a duplicate full local aggregate was not run. - [Greptile reviewed this exact commit](https://github.com/paperclipai/paperclip/pull/15313#issuecomment-6010222312) at 5/5 with no findings or unresolved threads. The PR is ready for review and has no merge conflicts. - `git diff --check` and the added-diff secret and PII scan passed. ## Risks Malformed routine and private-trigger IDs now return 404 instead of a database error. Full UUIDs retain the existing company and assignee checks. This change does not add prefix lookup, alter public webhook IDs, or validate unrelated nested revision/thread IDs or query parameters. No migration is required. ## Model Used OpenAI GPT-6 through Codex, with reasoning, repository editing, code execution, and independent agent review. The exact deployment 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> |
||
|
|
1d5a439e2b |
Diagnose native model rejections and preserve repairable reviews (#15304)
## Thinking Path > - Paperclip manages agent execution and recovery. > - A native provider can return a failed turn with an accepted result. > - This path replaced a structured model rejection with a generic failure. > - Finalization could also queue the same failed request for recovery. > - This change retains a bounded model and authentication diagnosis. > - Workers wait for a configuration fix; reviews retain their assignment. ## Linked Issues or Issue Description **Describe the bug** A native Codex turn can report HTTP 400 because the selected model is not supported by its ChatGPT connection. When the turn also returns a failed semantic result, the run shows `Native session failed` and `adapter_failed`. The native failed-result finalizer can create a retry intent before the adapter error is saved. **To Reproduce** Use a native Codex session that returns a structured `invalid_request_error` model/ChatGPT rejection and an accepted failed result. The regression tests reproduce this with a stub provider and a real isolated PostgreSQL database. No provider account or live request is needed. **Expected behavior** Show an actionable error and stop automatic retries of the rejected request. Block the current worker for a configuration fix. Preserve a pending review so its reviewer can explicitly retry after repair and resolve the original assignment. A stale run must not block a new task owner or override a completed review. **Version and deployment mode** The affected source path is present at `858094ba81`. This change applies to native Codex execution in local and remote environments. Related work: #13853 covers CLI protocol compatibility, #14942 refreshes runtime/model pins, and #12767 proposes legacy adapter model validation. This change concerns accepted native failed results and does not replace those changes. ## What Changed - Recognize only a bounded structured HTTP 400 provider error for the exact selected model and failed turn. - Save a fixed actionable error and four fixed diagnostic fields. Exclude raw provider text and model names from the new diagnostic. - Re-derive finalization evidence from the pinned execution and committed runner event, including its canonical hash and identity bindings. - Block only the current worker. For a current pending reviewer, preserve the original review decision and status version, release execution, and create no automatic recovery action. Recheck execution ownership under the issue lock. Preserve superseded and completed reviews. - Keep unknown failures, accepted results, cleanup, and ownership fences intact. Advance the status policy version to `phase6-v8`. - Route this exact failure code through the existing configuration recovery path. Permit an authenticated Board retry of this native failure only for its saved, still-pending review; discard caller review markers and revalidate at dispatch. ## Verification - Node 24: `pnpm -r typecheck` and `pnpm build` passed. - Independent focused validation: 222 tests passed across the new observer and PostgreSQL integration suites, status arbiter, diagnostic redaction, recovery classification, wake policy, and wake use cases. - The integration tests use actual result persistence, finalization, and the wake dispatcher. They cover zero retry dispatch for an authorized rejection, repeated reconciliation, pending/superseded/resolved reviews, reassignment, and a same-agent successor at an unchanged status version. - Final-commit verification: full typecheck and build passed; independent route/integration/arbiter/review validation passed 136 tests with no remaining source findings. This includes authenticated retry refusals, actual heartbeat retry admission, atomic queued-review claim, and acceptance of the original review. - The local aggregate test run was stopped to avoid duplicating the canonical Linux CI aggregate on this development host. Its partial log showed no failures; no full local-suite pass is claimed. The full hosted Linux CI aggregate passed on the final commit. - No live provider calls, runtime changes, or schema changes were made. ## Risks The classifier is intentionally narrow. A changed provider response format remains an unknown failure. No global model restriction is introduced. The worker blocker requires current task authority and does not replace newer assignments or completed review decisions. A pending review remains in review and requires an explicit retry after configuration repair; it is not rebound to a new status decision. The retry decision is durable. There remains a small existing gap between status/effect commit and diagnostic metadata persistence; a crash there can leave a generic diagnostic while preserving the blocked decision. No schema migration is required. ## Model Used OpenAI Codex, GPT-6, with reasoning, tool use, and code execution. The exact serving model suffix 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 #123` / `Refs #123` 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 id or instance-derived details - [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 - [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> |
||
|
|
d21fe31243 |
Retry pooled execution projection reads after disconnects (#15300)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Task run lists show current execution and recovery state. > - Their execution projection reads runs, finalizations, pending interactions, and recovery records. > - A temporary database disconnect in one lookup makes the run list fail. > - This pull request uses the existing bounded retry policy for these read-only lookups. > - It keeps transaction reads, authorization, and liveness writes outside the retry scope. ## Linked Issues or Issue Description Refs #15248. This extends the same bounded SELECT retry policy to the execution projection used by task run lists. A wrapped `CONNECTION_CLOSED` error from the pending-interaction SELECT makes `GET /issues/:id/runs` fail. These lookups are safe to repeat on the pooled database connection. The shared projection helper also serves transaction callers, so retries must remain an explicit opt-in. ## What Changed - Opt the activity run list into per-query projection retries. Keep the default path single-attempt for transaction callers. - Rebuild only the failed SELECT. Use the existing three-attempt limit and 50/100 ms delays. - Keep completed reads, route authorization, and liveness backfill writes outside the retry callbacks. - Test each query, exhaustion, exact error preservation, non-transient errors, empty results, transaction defaults, run-list backfill behavior, and denied route access. - Document the pooled-read boundary. ## Verification - Frozen install passed with Node 24.21.0 and pnpm 9.15.4. - 92 focused tests passed across execution projection, activity service/routes, prior service-read retries, and the shared retry policy. - Independent review passed 56 projection, retry-policy, and route authorization tests with no blocking findings. - `git diff --check` and the staged diff and PR-text secret/PII scan passed. - Full workspace `pnpm -r typecheck` and `pnpm build` passed. - Greptile scored exact head `78783e84a5` 5/5 with no findings or open review threads. - Initial CI had one Runner test timeout: `stops and closes a timed-out consumer even when the caller requested a warm session` exceeded 5 seconds. Its fixture uses a 1 ms session timeout. The Runner package is unchanged from the base. The focused case passed locally (1 passed, 138 skipped). One unchanged-head rerun of that job passed all 1,219 Runner tests and the additional native-runtime integration test. All other CI lanes passed on the initial run. - Full Linux CI passed on exact head `78783e84a5`: 53 successful checks, two intentional Storybook skips, and no pending checks. It provides aggregate test coverage. A full local aggregate was not launched. The same host's prior aggregate exposed three known macOS immutable-cache rename failures in unchanged company-skills code, documented in #15298. ## Risks - An affected lookup can take up to two additional connection attempts plus 150 ms of delay. Persistent failures still return the final error. - The opt-in is only used by the pooled activity read path. No transaction, mutation, full request, or provider action is replayed. - No schema or response-shape changes. ## Model Used OpenAI GPT-6 through Codex, with reasoning, repository editing, code execution, and independent agent review. The exact deployment 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 references) - [x] My branch name describes the change and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass (focused suites; aggregate coverage is 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> |
||
|
|
858094ba81 |
Fix browser polling for unsaved agent chats (#15298)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agent Chat uses the shared task surface and browser panel. > - An unsaved chat has a temporary ID instead of a stored task UUID. > - The browser poll sent that ID to a PostgreSQL UUID query and returned a server error. > - This pull request waits for a saved task and validates task IDs before the query. > - Saved chats keep their browser tools and access checks. ## Linked Issues or Issue Description Refs #14331. That report describes the same draft-ID problem in email requests. This change covers the browser routes; it does not change email behavior. Opening an unsaved Agent Chat sends `chat:<agent-id>` to `/issues/:issueId/browsers` every three seconds. PostgreSQL rejects this as a task UUID. The draft is only a UI view model. The first send or upload creates its stored task. ## What Changed - Disable browser polling for unsaved chat IDs. Resume polling when the chat has a task UUID. - Return the existing task-not-found response for malformed task IDs before database access. Keep board authentication first and company and credential checks unchanged. - Test all six task browser routes, draft-to-saved polling, normal tasks, saved chats, and denied access. Keep canonical UUID v4, v7, and nil values queryable. - Document the draft and saved-chat browser contract. ## Verification - `pnpm install --frozen-lockfile` passed with pnpm 9.15.4 and Node 24.21.0. - `pnpm exec vitest run server/src/__tests__/browser-use-route-scope.test.ts server/src/__tests__/browser-use-connection.test.ts` passed all 35 tests. - `pnpm exec vitest run ui/src/hooks/useTaskBrowsers.test.ts` passed all 5 tests. - Independent review passed 14 hook and route tests plus both real task and saved-chat authorization cases. - `pnpm check:token-gates` and `git diff --check` passed. - Full workspace `pnpm -r typecheck` and `pnpm build` passed. - Full Linux CI passed on `dafff44a32`: 53 successful checks and two intentional Storybook skips. This includes all general and serialized test groups, UI and browser tests, typecheck, build, and the canary dry run. No CI retries were needed. - The full local `TMPDIR=/private/tmp pnpm test:run` started but did not complete. It was stopped after full Linux CI passed. Before the stop, three company-skills cache cases failed on macOS. A focused rerun reproduced all three as `EACCES` while renaming immutable cache staging directories. The test, company-skills service, and runtime cache files are byte-identical to the baseline previously reproduced on `e99854249c` for #15291. Other local groups were not reached; the full Linux CI run provides aggregate coverage. - Greptile scored the exact head `dafff44a32` 5/5 with no findings or unresolved review threads. ## Risks - Malformed task IDs now return 404 instead of reaching PostgreSQL and returning 500. The route does not map draft IDs to agents or tasks. - No schema, browser provider, task creation, or authorization policy changes. ## Model Used OpenAI GPT-6 through Codex, with reasoning, repository editing, code execution, and independent agent review. The exact deployment 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 references) - [x] My branch name describes the change and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass (focused suites; full local run limitations are reported 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> |
||
|
|
0e0b63e5a5 |
feat(connections): add experimental task-pinned AI routing (#14967)
## Thinking Path > - Paperclip manages AI agents and their work. > - AI Connections separate account access from models and harnesses. > - A pool must act as one connection while retaining each task’s account. > - Core must enforce member access and preserve session and recovery rules. > - A plugin supplies rotation policy without receiving credentials. > - This change adds durable routing and native connector setup and management. ## Linked Issues or Issue Description **Subsystem affected** AI Connections, Connectors, plugins, run dispatch, and session compatibility. **Problem or motivation** Operators need to rotate new tasks across saved accounts while each task keeps its account and session. Pool setup must fit the existing connector catalog and account workflow. **Proposed solution** Add an experimental router binding, a capability-gated plugin hook, and transactional task pins. Plugins declare native pooled connectors through `aiConnectionRouter`. Core hosts the existing-account picker, ordering step, and account settings. Related usage contract: #14936. Companion private plugin: https://github.com/paperclipai/paperclip-cloud/pull/643. **Roadmap alignment** This extends Apps and AI Connections. Core supplies generic enforcement and native connector UI; the private plugin owns rotation and quota policy. The prior duplicate search found no matching router implementation. ## What Changed - Add a router binding without changing existing concrete bindings. Keep the instance flag and new pools disabled by default. Require manual operator configuration. Show no routing toggle in Experimental settings on either open-source or Cloud installs, even after routing is enabled. - Persist company-scoped pools, one shared cursor per pool, and pins keyed by company, pool, agent, and task. Commit pins and cursor advances together with revision checks and bounded retries. Persist run-ID affinity before allocation. - Pass only authorized metadata and normalized usage to plugins. Core retains credential handling, member access checks, runtime qualification, and recovery evidence. Probe outside locks with a shared 15-second budget and freshness cache. - Resolve routing before credential preparation and backend selection. Preserve pins through turns, session resets, removed members, and quota waits. Retain admitted recovery after disable or uninstall. - Separate credential session epochs from token generations. Verified refresh preserves the epoch; reconnect and manual replacement change it. Include the credential slot ID in session and usage-cache identity, so reconnecting an indexed legacy account invalidates its old session even when both epochs are zero. - Validate pool member installations before accepting saved-agent bindings and recheck compatibility when the harness changes. Install only authorized members in the new-agent transaction and record their IDs in local activity. Pool membership cannot install a restricted shared connection. - Preserve pool bindings when agents hire teammates through either creation API or native caller runtime inheritance. Block stale manager credential references; retain explicit child authentication precedence and reject incompatible inherited pools. - Add native connector registration through plugin metadata. Reuse the Connectors catalog, setup header, account header, sidebar, dialogs, and usage display. Setup selects and orders saved connections. Advanced settings hold usage rules and member runtime defaults. New-account setup opens in another tab. - Use revision-checked pool archival from the Connectors catalog and account page. Keep task pins, cursors, recovery evidence, and underlying connections. Reject ordinary connection updates or removals that bypass pool revisions. - Add pool selectors, composer models, override notes, quota status, run details, activity records, and local run-log records. Keep session-adoption copy minimal. - Show **Used by** below the pool connections. List current company agents with shared avatars and profile links. Include paused agents; exclude terminated agents and agents using another pool. - Add Core stories for the generic connector workflow and runtime surfaces. Cloud stories reuse these production routes and tokens through a preview-only alias. ## Verification - Final head `73cb953bca30ed83e4505dd820edd9b5edffd28b`: full workspace `pnpm -r typecheck`, `pnpm build`, and `pnpm check:token-gates` pass locally. - All 422 focused connector/settings/shared-contract/migration tests and all 156 database-backed AI connection, hiring, reconnect, and durable-routing cases pass (69 hiring cases rerun after the final auth-precedence fix). The merged shared contract retains connection instructions and pool metadata. The pool migration is generated at sequence 0299 after the latest upstream migrations; this PR makes no lockfile changes. - All four full-app Playwright tests pass on the final head after a cold restart and migration, against the installed private plugin and isolated database, with no route or pool-API mocks. They cover hidden routing controls after manual opt-in, native pool creation, ordering, membership edits, rename, paused defaults, enabling/save/refresh persistence, stale edits, cancellation/removal, preserved underlying accounts, unavailable routers, and Used by avatars and profile links. Exact command: `PAPERCLIP_CONNECTION_POOL_E2E=1 AI_CONNECTIONS_TEST_COMPANY_ID=a37b9625-5ecf-4e29-8081-04df3d6e7d6f AI_CONNECTIONS_TEST_URL=http://127.0.0.1:3108 pnpm exec playwright test --config tests/ai-connections-app/playwright.config.ts connection-pools.spec.ts`. - [Native setup, ordering, and management screenshots](https://github.com/paperclipai/paperclip/pull/14967#issuecomment-6006976278) address the review follow-up. [Earlier selector, quota, and run-detail screenshots](https://github.com/paperclipai/paperclip/pull/14967#issuecomment-5971537316) show the runtime surfaces. Core previews: `pnpm --filter @paperclipai/ui storybook`, then **Connectors / Pool host** or **AI Connections / Connection pools**. Cloud owns its host-backed plugin stories; both repositories’ Operator Setup Required story assertions pass. - Live acceptance used OpenAI/Codex and Anthropic/Claude ACPX, resumed both exact sessions after restart, preserved pinned accounts through explicit reset and controlled quota deferral/recovery, and committed only two allocations across fourteen runs. A later UI-created task test again rotated OpenAI then Anthropic and resumed OpenAI through follow-up/restart/quota recovery. That later Anthropic execution was blocked by its saved OAuth token expiring (provider 401). No live usage probes ran. - The full local `pnpm test:run` was attempted earlier and did not complete because of macOS embedded PostgreSQL bootstrap/shared-memory failures and the 40,000-file Git fixture timeout. The focused database suites above now pass; full-suite verification is provided by the split CI lanes. The preceding CI run had one runtime readiness timeout; it passes locally both alone and inside the larger runtime suite. That larger local suite also encountered an embedded PostgreSQL setup failure and two macOS temporary-path alias assertions; those two assertions pass with canonical TMPDIR=/private/tmp. All final-head CI checks are terminal green, including full general/serialized server suites, Runner checks, browser E2E shards, canary verification, build, and typecheck. Greptile is 5/5 on that exact head with no unresolved threads. ## Risks - The migration adds routing tables and a credential epoch column. Install the private plugin only with the compatible Core contract. - Routing and each pool require opt-in. Production distribution and fleet defaults remain unchanged. - Unknown usage stays eligible. Known pinned exhaustion waits; revoked access requires operator repair. - Legacy adapters require compatible members. Runner model and effort overrides remain limited by qualified backend support. ## Model Used OpenAI GPT-6 through Codex, with reasoning, repository editing, code execution, and browser testing. The exact deployment 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 - [x] My branch name describes the change and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass (targeted suites; full-suite limitations are reported 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> |
||
|
|
72ff3a9f27 |
Measure native tool context and expand bounded workflow evals (#15218)
## Thinking Path > - Paperclip manages persistent agents and their assigned work. > - Agents receive both fixed instructions and tool definitions. > - Moving a procedure into a tool description still adds model context. > - We need to measure the complete delivered catalog and test real outcomes. > - The tested reductions saved little space and introduced failing outcomes. > - This PR keeps measurement, bounded eval coverage and the original evidence. > - Production prompts, tools and runtime behavior stay unchanged. ## Linked Issues or Issue Description Refs: #15151, #14961, #14948, #14985. This adds the measurement and eval coverage needed to assess further native instruction changes. The attempted hiring and dependency reduction failed qualification and is excluded from the final diff. ## What Changed - Measure the actual standard-mode tool authority, including all 39 tools and their input schemas. Capture scripted native start, resume and continuation payloads and the OpenCode MCP declaration list. - Add OpenCode to the two explicit-only local hiring/reuse and delegation/feedback stories. Preserve the original task requests and independent oracles. - Apply one attempt per selected story and explicit company and lead-agent budget stops. - Select managed hiring credentials from the requested profile, including OpenRouter. - Run the existing Node test files under Node instead of collecting them as Vitest suites. - Retain sanitized comparison reports, original failed grades, source hashes and evidence gaps. ## Verification Final source: `2e7cef78eef7cdfe02265e0dcb03e855b8e50bd8`. Local verification passes: - Full repository `pnpm -r typecheck` and `pnpm build`. - Eval-support unit tests: 1,252 Vitest checks and 128 Node checks. - Eval TypeScript check and six final-source measurement tests. All 36 normalized components across nine scripted deliveries and the OpenCode MCP catalog match the baseline exactly; the complete standing projection is 49,200 bytes. Fresh review of this exact head is [5/5 with no remaining findings](https://github.com/paperclipai/paperclip/pull/15218#issuecomment-5996723170); all three review threads are resolved. [Final-head CI](https://github.com/paperclipai/paperclip/actions/runs/37354539126) passes all 47 jobs, including repository typecheck, build, tests, runner checks, browser shards and the canary check. One initial annotation-test timeout is retained in attempt 1; its seven-test suite passed locally, and the affected CI lane passed on one targeted retry. No source or paid eval rerun was needed. Both ready-transition security scans passed with zero annotations. The PR is out of draft and conflict-free. GitHub still requires code-owner approval for the `package.json` test-script change; its requested reviewers are already set. A byte-for-byte comparison against master context `a65ca0950834a85bb93bcc4b4042ecacdebfef53` confirms no production changes under `packages/` or production `server/` paths. The only server addition is a measurement test. No new paid rerun is needed to compare unchanged production bytes. This does not claim that existing product defects have been fixed. The rejected corrected experiment had baseline **5 PASS / 1 FAIL** and candidate **3 PASS / 3 FAIL**, including **two newly failing pairs**. The later readiness experiment had candidate **3 PASS / 3 FAIL** and baseline **3 PASS / 2 FAIL / one setup cell without a behavioral grade**. Its five comparable pairs had two new failures, two new passes and one unchanged pass. The missing baseline Codex cell never reached its provider step because Docker setup timed out. The observed missing behaviors include parent continuation, waiting for the latest child revision, revised ZIP delivery and OpenCode credential persistence. Those failures remain failures. Source review and passing CI do not regrade them. The original reduction saved 460 bytes; its first repair saved only 125 bytes, and the larger unqualified runtime repair increased the full projection. None of those production changes is shipped here. Read the [report](https://github.com/paperclipai/paperclip/blob/2e7cef78eef7cdfe02265e0dcb03e855b8e50bd8/doc/plans/2026-10-05-native-procedure-guidance.md) and its linked sanitized receipts for exact sources, original campaign links, pair-level results and evidence limitations. ## Risks - Full-catalog bytes are not model tokens, invoices, private vendor prompts, lazy-loading behavior or truncation proof. - The two stories are explicit-only and do not prove general coding quality or arbitrary resume behavior. Single trials do not establish causation or performance trends. - The retained OpenCode candidate credential guard failed. Cleanup removed the original provider database, so the precise persistence mechanism remains unknown. The guard is unchanged. - ACPX provider-execution IDs lack proven host-call mapping. No extra-work or feedback-consumption claim is inferred by matching names, order or counts. - PostgreSQL cannot start locally while the host's shared-memory slots are exhausted. Hosted CI must supply the full database checks; the full local database suite is not claimed green. ## Model Used OpenAI Codex, based on GPT-6, with repository tools and code execution. The exact deployment model ID and context-window limit 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> |
||
|
|
efac8ff2f4 |
Add bounded Git integration restore diagnostics (#15291)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Sandbox runs must restore their workspace before finalization can succeed. > - Restore diagnostics identify the failed phase and operation. > - A Git integration exit code can still describe several different failures. > - This pull request adds fixed command labels and supported failure classes. > - Operators can distinguish these failures without collecting private Git output. ## Linked Issues or Issue Description Refs #15005. This branch includes merged #15268. It labels that change's locked ref transaction and nested branch probe without changing their behavior. **What happened?** A failed Git integration can report only `git_integration`, `unknown`, and an exit code. That evidence does not identify the failed command. Some Git versions also return exit 1 for both a merge conflict and an invalid object. **Expected behavior** Record a fixed command family and a supported failure class. Keep unknown cases as `unknown`. Exclude command arguments, process output, paths, repository URLs, filenames, and ref names. **Steps to reproduce** The tests create local repositories with conflicting commits, a missing object, and an expected-old ref mismatch. They call the real Git operations and inspect the resulting diagnostic. No hosted workspace or external provider is used. **Paperclip version or commit** Base: `e99854249c`. **Deployment mode** Built from source. The diagnostic applies to sandbox workspace restore. ## What Changed - Label Git integration calls with a closed command enum. Preserve arguments, options, errors, and retry behavior. - Recognize supported object and ref errors and OS permission codes. Require both exit 1 and completed tree output for a merge conflict. - Carry the closed fields through the existing restore receipt, saved adapter result, and Sentry projection. Revalidate saved metadata before projection. - Test nested wrappers, parallel failures, reused errors, handled probes, result settlement, and privacy with the real Sentry SDK. - Document the field contract and its limits. ## Verification - Eight focused suites pass: 295 tests. These cover Git sync, restore diagnostics, result settlement, teardown, sandbox runtime, failure projection, the real Sentry SDK, and native warm-workspace Git history. - `PAPERCLIP_REQUIRE_SENTRY_TEST_SDK=1 pnpm exec vitest run packages/adapter-utils/src/workspace-restore-diagnostics.test.ts packages/adapter-utils/src/workspace-restore-result.test.ts packages/adapter-utils/src/git-workspace-sync.test.ts packages/adapter-utils/src/workspace-restore-teardown.test.ts packages/adapter-utils/src/sandbox-managed-runtime.test.ts server/src/services/__tests__/run-failure-diagnostics.test.ts server/src/__tests__/run-failure-sentry-real-sdk.test.ts server/src/__tests__/native-workspace-sync-history.test.ts` - Local checks use Node 24.21.0 and the pinned pnpm 9.15.4. The optional Sentry SDK is pinned to the declared 10.71.0 and uses an in-memory transport. - `pnpm -r typecheck` and `pnpm build`: pass on the rebased head. - The full local `pnpm test:run` was stopped before source changes when #15268 merged and required a rebase. It reported three pre-existing company-skill cache test failures on macOS. The same three cases fail on clean bases `2c43b39167` and `e99854249c` and the earlier head with `EACCES` when publishing a read-only cache directory. The relevant test, service, and cache source blobs are identical. No cache changes are included. Later local test groups were not reached. - All 54 checks pass on exact head `8448896bc6`, including the post-ready security scan, with two intentional Storybook skips. Greptile scores this head 5/5 with no review threads. Full Linux CI covers the local groups that were not reached. - Independent review found no blocker. Its diagnostics, Git workspace, and native history suites pass 115/115 on this head. - A source comparison confirms that removing only diagnostic wrappers yields the merged upstream Git integration code exactly, including ref locks, transaction protocol, arguments, options, and retry decisions. - The clean base has stale dependency overrides in its lockfile. Local installation resolved them as the existing PR CI fallback does. No manifest or lockfile change is included. - `git diff --check` and a local secrets/PII review pass. ## Risks A Git version or localized message may not match a known failure form. Such cases remain `unknown`. Up to 16 KiB of stderr and the bounded tree-ID prefix of stdout are inspected only in memory. The saved fields contain enum values only. These diagnostics do not establish workspace recovery or authorize retries. Restore decisions and Git mutations are unchanged. No schema migration is required. ## Model Used OpenAI Codex, GPT-6, with reasoning, tool use, and code execution. The service does not expose the exact model deployment ID or context-window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
e99854249c |
fix(workspaces): restore rebased sandbox history against its starting snapshot (#15268)
## Thinking Path > - Paperclip manages agents and preserves their work across runs. > - Sandbox execution restores Git history and files to the host workspace. > - An agent can rebase or amend its branch before it finishes. > - Restore currently treats the original and rewritten tips as concurrent work. > - That merge can conflict even when the host has not changed. > - This change uses the starting Git snapshot to accept rewritten history safely. ## Linked Issues or Issue Description **What happened?** A successful sandbox turn can end with `workspace_restore_failed` after the agent rebases and pushes its branch. The restore step merges the original host tip with the rewritten sandbox tip. This can recreate conflicts that the agent already resolved. **Expected behavior** Accept the rewritten history when the host still has the recorded starting branch and commit. Preserve concurrent host work through the existing merge and recovery paths. **Steps to reproduce** 1. Start a sandbox from a feature branch. 2. Rebase that branch onto an upstream commit that changes the same file. Resolve the conflict in the sandbox. 3. Restore the sandbox while the host remains on the original commit. 4. The old implementation attempts a conflicting Git merge and fails the run after the agent finishes. **Paperclip version or commit** Reproduced on `cab4263dc9` with a real Git rebase fixture. **Deployment mode** Self-hosted server with sandbox execution. Related work: #15005 records restore failure stages. #11638 preserves unrelated imported history with a graft. #10601 handles bundle prerequisites. Those changes do not distinguish a rebase from a concurrent host edit. ## What Changed - Pass the run's starting Git branch and commit into sandbox history integration. - Adopt a related rewritten tip when the host still matches that snapshot. Keep the expected-old-value ref update and bounded retry. - Verify the branch attachment inside a prepared Git transaction while Git holds its ref locks. Abort if a checkout changed the branch. - Check host and sandbox Git identity before warm reuse, including nested repositories. Restage when their tips or branches differ. - Reject host branch changes and unrelated imports after a concurrent host commit. - Retain the existing unrelated-history graft for an unchanged host and the conservative behavior for callers without a snapshot. - Export a full bundle for an intentional reset to an ancestor so restore receives the actual sandbox tip. - Add real Git and sandbox restore regressions. Document the restore contract. ## Verification - Eight Git sync, sandbox restore, and native workspace suites pass: 255 tests. - The new checkout-race and warm-reuse regressions failed before the fixes. Real Git hooks verify that prepared transactions prevent a concurrent HEAD change. - `pnpm -r typecheck` passed after rebasing onto `984f092ddf` and applying the Apex findings. - `pnpm build` passed on `f5132603d6`. - The earlier `pnpm test:run` attempt reported three `company-skills-service.test.ts` failures on macOS (`EACCES` renaming a read-only staging directory). The same failures reproduced on unchanged master. The broader run was stopped after confirming that baseline failure; it was not a full-suite pass. Those source and test files are unchanged in the current base. - [Apex review](https://github.com/paperclipai/paperclip/pull/15268#issuecomment-6002549219): 5/5 on `f5132603d6`, requested with `@greptileai apex review`. All three historical findings are addressed and all review threads are resolved. - All CI gates passed on `f5132603d6` (53 successful checks, two skipped). The signoff-policy browser fixture initially timed out waiting for a local process-agent run; its one retry passed without code changes. [CI run](https://github.com/paperclipai/paperclip/actions/runs/37387511152) ## Risks - A recorded starting snapshot now authorizes replacement of related rewritten history. A stale or changed host tip retains the concurrent-history path. Ref writes still compare the expected old commit. - Branch changes and unrelated rewrites after host advancement require recovery instead of replacing host work. - An intentional reset to an ancestor uses a full bundle. Large histories can increase transfer time in that case. - The existing directory merge rules remain in force. The fix does not resolve an earlier failed restore or replay its external actions. ## Model Used OpenAI GPT-6 via Codex, with reasoning, repository analysis, code editing, and local test execution. The exact deployment 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 — 255 affected tests; the broader-suite baseline failure is 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> |
||
|
|
4857799a88 |
feat(connections): deliver saved instructions to authorized agent turns (#15216)
Persist optional connection instructions and deliver authorized snapshots to agent execution prompts. Keep provider templates with each app definition, preserve edits and opt-outs, and replace sessions when guidance or access changes. Use shared production settings across setup and Permissions, with source visibility in agent Instructions. Add the initial memory-provider defaults and managed Honcho workspace configuration. Include migration 0298 and regression coverage for generic providers, runtime delivery, authorization, and catalog regeneration. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
984f092ddf |
Add project and agent resource lifecycle hooks (#15280)
## Thinking Path > - Paperclip manages agents and projects for work. > - Plugins need reliable lifecycle hooks for these resources. > - In-process notifications can disappear during a restart. > - A lifecycle record must commit with the resource change. > - This pull request adds a generic lifecycle journal without provider calls. > - A later plugin delivery layer can use these records without losing lifecycle changes. ## Linked Issues or Issue Description **Problem or motivation** Resource provisioning needs durable hooks for agent hiring, pause, resume, termination, and project creation. Hooks must cover shared service callers, budget actions, and approval paths. Capture should work for all plugins and deployment modes. **Proposed solution** Record content-free events in the resource transaction. Deduplicate creation and unchanged status. Preserve each pause/resume cycle. Commit approval, activation, and creation together. Commit termination and API-key revocation together. **Alternatives considered** Event subscriptions alone cannot survive process failure. Cloud-only capture would exclude other plugins. Provider calls inside tenant transactions would couple resource creation to external services. **Roadmap alignment** This is lifecycle infrastructure for the existing plugin system. It adds no provider, adapter, UI, or plugin read API. Repository mutations and backfill remain separate work. Searches found no duplicate lifecycle-journal PR. ## What Changed - Add a company-scoped lifecycle journal and an additive migration. - Record hired-agent and project creation from shared services. - Record agent pause, resume, and termination, including generic updates and budget actions. - Lock agent state changes to suppress concurrent duplicate hooks. - Make hire approval, rejection, and termination transactions atomic with their lifecycle records. - Document capture, ordering, future per-plugin acknowledgments, and migration scope. ## Verification - Full workspace typecheck: `pnpm -r typecheck` passed. - Production build: `pnpm build` passed. - Focused agent, project, approval, budget, and built-in regressions: 102 tests passed across 9 suites. - Final lifecycle journal check: 14 tests passed. It covers repeated/concurrent transitions, rollback, key revocation, self-hosted capture, and company boundaries. - Review regression: 32 lifecycle and approval tests passed, including rejected-hire rollback and retry; server typecheck passed after the fix. - The initial local `pnpm test:run` overlapped the rejection fix and reported the new rollback regression against the earlier service code. A fresh lifecycle run passed all 14 tests. Fresh full local shards were stopped once the complete CI test matrix passed on the final commit. - `git diff --check` and a local secret/PII scan passed. - Greptile: 5/5 on `3ee3903f8e1a171ea3ba2bea9caa2b5766a3f807`, with the review thread resolved. - [Complete CI passed](https://github.com/paperclipai/paperclip/actions/runs/37374227222) on `3ee3903f8e1a171ea3ba2bea9caa2b5766a3f807`: general server/chat/workspace tests, serialized server suites, runner checks, build, typecheck, canary, and all end-to-end shards. The requester waived CI during the Actions outage, but the workflow subsequently completed successfully. ## Risks - The migration creates an empty table. It does not scan or backfill existing resources. - Apply the normal database migration before running this server version. Event-write failure intentionally rolls back the resource change. - Pending hires cannot bypass approval through pause or resume. - Capture works on all deployments. Plugin delivery, retention, retries, and provider actions remain separate work. No plugin can read this journal through a new API in this PR. - Future delivery must enforce company scope, track acknowledgments per plugin, and preserve resource order. A global sequence cursor can skip uncommitted transactions. - A termination hook does not authorize deleting persistent volumes. ## Model Used OpenAI Codex, based on GPT-6, with reasoning, repository inspection, code execution, and tool use. The exact deployment 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> |
||
|
|
6c36c07a4f |
feat(adapters): add GPT-6.1 Sol and refresh shared coding harness pins (#14942)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agents run through coding-agent adapters and the native runner. Both use the same installed provider CLIs, model catalogs, and reasoning controls. > - OpenAI released GPT-6.1 Sol (`gpt-6.1-sol`) in Codex. Anthropic released Claude Sonnet 5.5. The static Codex, Bedrock, and OpenCode catalogs do not list these IDs. > - The shared provider pack pins Codex 0.156.0 and OpenCode 1.18.32. The evaluation image pins older Grok, Gemini, Kimi, Cursor, and GitHub CLI releases. Codex 0.156.0 has no bundled metadata for GPT-6.1 Sol. > - A model entry without a current harness, or a harness pin without its runner integrity checks, fails at run time. > - This pull request adds the verified model IDs and moves the harness pins, executable digests, controller checks, and image pins together. > - The benefit is that operators can select the current models, and the native and local adapters share one current CLI installation. ## Linked Issues or Issue Description Refs #13829 and #13838 (the September 22, 2026 model and harness refresh). Related pull requests: #14993 (merged October 5, 2026, superseding #14816) added the direct Claude Sonnet 5.5 entry and refreshed the Claude runtime to Agent SDK 0.3.286 / Claude Code 2.1.286. This pull request does not change the Claude runtime or the direct Claude model list; it keeps the #14993 pins and adds only the Bedrock Sonnet 5.5 ID. After #14993 merged, this branch was rebased onto `master` (October 5, 2026). The six overlapping pin regions (`docker/daytona-runner/Dockerfile`, `docker/daytona-runner/README.md`, `package.json`, `pnpm-workspace.yaml`, `packages/adapters/claude-local/src/index.test.ts`, `packages/paperclip-runner/src/backends/native-backend-factory.test.ts`) were resolved by keeping this pull request's Codex 0.160.0 and OpenCode 1.18.34 pins next to #14993's Claude 0.3.286 / 2.1.286 pins, taking the union of the Sonnet 5.5 model IDs in the Claude test, and merging both README paragraphs. The Sonnet 5.5 effort and CLI-gate lines in the Claude adapter were identical in both pull requests and merged without a diff. #14917 and #14918 reordered the Claude and Codex model lists earlier; the new entries sit where those ordering rules put them. Sources checked on 2026-10-02: - [OpenAI Codex models](https://learn.chatgpt.com/docs/models): GPT-6.1 Sol uses `gpt-6.1-sol`, supports reasoning efforts from Light to Ultra, and has Standard and Fast modes at launch. The page also records that `gpt-5.4` and `gpt-5.4-mini` retired from Codex with ChatGPT sign-in on August 31, 2026, and that `gpt-5.5` retires on October 14, 2026. Neither retirement applies to the OpenAI API. - [Codex CLI releases](https://github.com/openai/codex/releases) 0.157.0 through 0.160.0. The bundled model metadata in the 0.160.0 Linux binary contains `gpt-6.1-sol`. - [Claude Sonnet 5.5](https://platform.claude.com/docs/en/models/sonnet-5-5/overview): Bedrock ID `anthropic.claude-sonnet-5-5`, released September 28, 2026. - [OpenCode releases](https://github.com/anomalyco/opencode/releases) 1.18.33 and 1.18.34 (fixes only). The OpenCode model registry lists both added provider-qualified IDs. - npm `latest` tags for `@xai-official/grok` 1.0.46, `@google/gemini-cli` 0.62.0, and `@moonshot-ai/kimi-code` 2.1.1. [xAI](https://docs.x.ai/docs/models), [Google](https://ai.google.dev/gemini-api/docs/models), and [Kimi](https://www.kimi.com/code/docs/en/kimi-code/models.html) list no newer coding models. - Cursor CLI 2026.10.01-e373342 is the version the official installer resolves. The pinned digest is the SHA-256 of the versioned Linux x64 archive. - [GitHub CLI 2.102.0](https://github.com/cli/cli/releases/tag/v2.102.0) (security fixes). The pinned digest matches the release `checksums.txt`. ## What Changed - Codex adapter: add `gpt-6.1-sol` to the model list, the Fast mode list, and the Ultra effort set. It is the first entry: #14918 orders the list newest version first, and its description notes the ChatGPT app lists GPT-6.1 Sol first. Update the adapter documentation text. - Claude adapter: add `us.anthropic.claude-sonnet-5-5` (Bedrock Sonnet 5.5) to the Bedrock catalog in the newest-Sonnet slot after Opus 5.5; `us.anthropic.claude-sonnet-5` moves into the older-Sonnet group, matching what `sortClaudeModels` from #14917 produces at runtime. Any Sonnet 5.5 ID (direct or Bedrock-qualified) now gets the documented `xhigh` and `max` efforts and requires Claude Code 2.1.284 or later on the CLI lane (the Claude Code changelog entry for 2.1.284 adds `claude-sonnet-5-5`). These two lines are identical to the ones #14993 merged, so the branch carries no diff for them. - OpenCode adapter: add `openai/gpt-6.1-sol` and `anthropic/claude-sonnet-5-5` to the static fallback catalog. - Codex runtime pin 0.156.0 → 0.160.0 in the root and workspace overrides, the runner package, the Codex ACP package patch, the qualified ACPX profiles, the Linux x64 executable digest, the Rust provider backend and its tests, the provider-pack manifest pins, the remote controller pins, the sandbox npm install spec, and the opt-in qualification scripts. - Remote Codex compatibility window: upper bound 0.157.0 → 0.161.0. The minimum stays at 0.149.0. - OpenCode runtime pin 1.18.32 → 1.18.34 in the runner package, the materialization script, the server and Rust qualified versions, the eval and live-session labels, fixtures, and the configuration label. - Evaluation image (`docker/daytona-runner/Dockerfile`): Grok CLI 1.0.46, Gemini CLI 0.62.0, Kimi Code 2.1.1, Cursor CLI 2026.10.01-e373342 with its digest, GitHub CLI 2.102.0 with its digest, Codex and OpenCode version probes, and the refreshed lockfile digest. The Claude Code 2.1.286 probe comes from #14993 and is unchanged here. - `pnpm-lock.yaml` is not part of this pull request. The repository's pull request gate rejects lockfile edits, and the refresh bot regenerates the lockfile on master (the same flow #13838 used). The Dockerfile `PAPERCLIP_RUNNER_LOCK_SHA256` default is the digest of the lockfile that `pnpm install --resolution-only --ignore-scripts --no-frozen-lockfile` (the refresh workflow's command) produces for the combined pins on the rebased branch (`e1856797…`); that lockfile differs from master only in the `@openai/codex` 0.160.0 platform packages, the `@anthropic-ai/claude-agent-sdk` 0.3.286 override that #14993 introduced (the open refresh-bot pull request #14872 carries that part), `opencode-ai` 1.18.34 with its Linux x64 baseline, and the `codex-acp` patch hash. - Documentation: runner README, runner compatibility doc, environment variable example, and a new `doc/adapter-model-audit-2026-10-02.md` with sources and deferred items. - Tests: Codex adapter catalog, server adapter models, Codex compatibility window, native session executor pins, runner package contract, OpenCode materialization, and UI effort options. Unchanged on purpose: Claude Agent SDK 0.3.286 / Claude Code 2.1.286 (already on `master` from #14993), ACP bridges (`acpx` 0.13.1, `claude-agent-acp` 0.73.0, `codex-acp` 1.6.2; newer upstream releases need a separate qualification), the native Grok runtime 1.0.13, Pi 0.84.2 / 0.87.1 (the Pi 1.0 runner stack covers it), and Hermes 0.19.0 (current). `gpt-5.4` and `gpt-5.4-mini` stay in the picker because the OpenAI API still serves them. ## Verification Run on Linux x64 with Node 25.9.0 and pnpm 9.15.4 after `pnpm install --no-frozen-lockfile` (the refreshed lockfile stays local; see above). The results below were re-run on the rebased head (October 5, 2026) for the suites the conflict resolution touches; the other rows are from the original run and are covered by CI on every push: - Rebased head: `packages/adapters/codex-local` 482 passed; `packages/adapters/claude-local` 340 passed, 4 failed (`execute.remote`, `test.probe`, `execute.acp-fallback`, `acp` spawn/env-hardening cases that fail identically on unchanged `master` in this host environment); `server` adapter-models + codex-runtime-compatibility + native-session-executor + adapter-registry 607 passed, 1 failed (the same adapter-registry override-pause case as before, also failing on `master` here); `packages/paperclip-runner` native-backend-factory + qualified-profiles 36 passed; `ui` codex-reasoning-effort + config-fields + model-utils 19 passed. Rust, full typecheck, build, and the Docker image are left to CI as before. - `vitest run` in `packages/adapters/codex-local`: 13 passed. `vitest run` in `packages/adapters/claude-local` (whole package, including the new Sonnet 5.5 gate and effort tests): see the latest CI run and the comment below. `vitest run` in `packages/adapters/opencode-local`: 48 passed, 1 failed (`runtime-config.test.ts` reads the host `PAPERCLIP_OPENCODE_PROVIDERS` variable; it fails the same way on the unchanged base). - `vitest run src/__tests__/adapter-models.test.ts src/services/native-runtime/codex-runtime-compatibility.test.ts src/__tests__/adapter-registry.test.ts` in `server`: 84 passed, 1 failed (`adapter-registry.test.ts` override pause test; it fails the same way on the unchanged base). - `vitest run` in `ui` for `codex-reasoning-effort`, `agent-setup-fields`, `config-fields`, and `ComposerRunSettingsPicker`: 25 passed. - `node --test test/acpx-codex-package-contract.test.mjs scripts/materialize-opencode-binary.test.mjs scripts/runner-protocol-eval-campaign.test.mjs` in `packages/paperclip-runner`: 23 passed. The package contract test verifies the installed Codex ACP executable digest and the 0.160.0 patch pin. - `vitest run src/drivers/acpx src/backends src/drivers/opencode src/live/live-session.test.ts` in `packages/paperclip-runner`: 626 passed, 5 failed, 1 skipped. The 5 failures (`installation-integrity.test.ts` `/proc/self/fd` module loading and one OpenCode answer-selection test) also fail on the unchanged base under Node 25; Linux CI runs Node 24. - `pnpm run test:opencode:qualification` in `packages/paperclip-runner` against the installed OpenCode 1.18.34 executable: passed. - `codex --version` from the installed pack prints `codex-cli 0.160.0`. The Linux x64 executable digest `12eb3e81…652aad` was computed from the `@openai/codex@0.160.0-linux-x64` archive after checking its registry `dist.integrity`. - `pnpm check:token-gates`: all gates clean. - `pnpm run typecheck:typescript` in `packages/paperclip-runner`: passed. Package typechecks ran one at a time; see the comment below for the server and UI results. Not run here, and needed from CI: - Rust tests and `pnpm -r typecheck` / `pnpm build` for the server (no `cargo` in this environment; the server typecheck prepares the runner vendor build). - The Docker evaluation image build and the real-binary Codex startup and session-resume probes (no Docker; the probes need the compiled `paperclip-runnerd`). The trusted CI runner workflow covers them. - Authenticated inference with any new model. This change is metadata and startup validation only. ## Risks - Codex 0.160.0 changes the bundled model catalog and app-server behaviour (authoritative provider catalogs, incremental running-turn tracking). The patched `codex-acp` 1.6.2 bridge is unchanged and declares `^0.148.0`; it worked with 0.156.0 under the same override. If CI probes show a protocol change, the pin can return to 0.156.0 by reverting this pull request. - The compatibility window upper bound moves to `<0.161.0`. Remote images with Codex 0.157 to 0.160 become accepted. Older images stay accepted down to 0.149.0. - Until the refresh bot lands the regenerated lockfile on master, the Dockerfile lockfile digest default does not match the committed lockfile. The trusted CI workflow computes the digest from its own resolution at build time, so this affects only a local build that passes no digest. - Existing saved model selections and effort settings are not changed. Agents on `gpt-5.4` or `gpt-5.5` with ChatGPT sign-in need a model change before the OpenAI retirement dates; that is documented, not enforced. - Rollout order: deploy the controller and runner from this change before promoting a sandbox image that carries these pins. Older controllers reject the new provider-pack pins. ## Model Used - Claude Fable 5.1 (Anthropic, model ID `claude-fable-5-1`), 1M context window, adaptive thinking, tool use. The model ran as a Paperclip agent through the Claude Code harness, performed the web research, edited the code, and ran the tests listed above. ## 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 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Bender (Fable) <noreply@paperclip.ing> Co-authored-by: devinfoley <139239+devinfoley@users.noreply.github.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
41c1431d66 |
fix(server): remove the fixture-cleanup deadlock in the stale queued-run test (#14968)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The server heartbeat tests use shared database fixtures and concurrent run execution. > - The stale queued-run test checked the database before all active executions finished. > - A late run writer could then hold a row lock while fixture cleanup held another table lock. > - PostgreSQL could report a deadlock, and the test cleanup could fail. > - This pull request waits for active executions and shares the deadlock retry helper. > - The benefit is reliable test cleanup without a production code change. ## Linked Issues or Issue Description Refs: #14198 **What happened?** The stale queued-run test could fail during fixture cleanup. Its cleanup poll could miss a run that had not written its database row. A later writer could then deadlock with the cleanup `TRUNCATE` operation. **Expected behavior** Fixture cleanup must wait for active run executions. It must retry transient PostgreSQL deadlocks and foreign-key races. **Steps to reproduce** 1. Run the server heartbeat tests with concurrent test activity. 2. Let an active run write its database row after the cleanup poll starts. 3. Observe a PostgreSQL `40P01` deadlock during fixture cleanup. **Paperclip version or commit** `master` at the base commit for this pull request. **Deployment mode** Test-only change against the server test database. ## What Changed - Replace the local cleanup poll with `drainHeartbeatRunsToQuiescence`. - Add the shared `truncateTablesWithDeadlockRetry` test helper. - Retry PostgreSQL `40P01` deadlocks and the existing foreign-key race. - Use the shared helper in both heartbeat test files. - Remove the private duplicate helper. - Change no production code. ## Verification - `vitest run server/src/__tests__/helpers/truncate-with-deadlock-retry.test.ts` passes. - `vitest run server/src/__tests__/heartbeat-active-run-output-watchdog.test.ts` passes. - The target stale queued-run test passes in the engineer validation run. - CI must confirm the full stale queued-run test file and the required server checks. ## Risks Low risk. This change affects test cleanup only. The helper keeps a bounded retry count and rethrows persistent errors. The full stale queued-run test file needs CI because the local sandbox lacks the managed Codex home required by an existing pre-dispatch credential gate. ## Model Used OpenAI Codex, GPT-5, with tool use and code review assistance. ## 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 (no documentation change is needed for this test-only change) - [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 ## Test plan - [x] CI `General tests` passes for the `server` shards. - [x] CI `verify` passes. - [x] `vitest run server/src/__tests__/helpers/truncate-with-deadlock-retry.test.ts` passes. - [x] `vitest run server/src/__tests__/heartbeat-active-run-output-watchdog.test.ts` passes. - [x] `vitest run server/src/__tests__/heartbeat-stale-queue-invalidation.test.ts` passes. ## Note on the sandbox test gap The engineer could not run the full `heartbeat-stale-queue-invalidation.test.ts` file green in the development sandbox. A pre-dispatch credential gate in `heartbeat.ts` needs a usable Codex home for `codex_local` agents, and that sandbox has no managed home. The engineer proved the failure is pre-existing: they stashed both test-file changes, reran the unmodified file, and got the identical 25 failures with the identical error. CI supplies the full-file run. Treat the CI result for this file as the authoritative check. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
b43073d11f |
feat(connections): sync and group accounts managed by aggregators (#15254)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Connections give agents governed access to external tools. > - Aggregator gateways can expose accounts that users already connected upstream. > - The Apps catalog did not show those accounts or their current provider status. > - Separate cards and setup tasks also made account ownership unclear. > - This pull request discovers upstream accounts and groups them under one app card. > - Users can find connected apps while each provider keeps control of its accounts. ## Linked Issues or Issue Description **Subsystem affected** Connections across the database, shared contracts, server, and board UI. **Problem or motivation** Users cannot see which apps are connected through a saved aggregator gateway. Native and upstream accounts need one app card. Discovery must preserve company, user, gateway, and credential boundaries. **Proposed solution** Sync account metadata from Composio, Arcade, and supported Executor gateways. Keep upstream account management in each provider. Use source chips and search to browse the catalog. Preserve native setup and the gateway's existing access policy. **Alternatives considered** Creating a local executable connection for each upstream account would duplicate authorization state. Using an agent task for routine Composio setup would add an unnecessary step. The board now calls the saved gateway directly for that setup. **Roadmap alignment** This extends the shipped Connected Apps and MCP Tool Gateway features in ROADMAP.md. The duplicate search found no open PR for managed account discovery. Related work: Refs #13755, Refs #13941, Refs #14725, Refs #13855. Open PR #12906 covers adjacent toolkit routing work. ## What Changed - Add provider-neutral discovery, sync, and refresh APIs. Preserve the Composio API paths. - Cache observations by company, saved gateway, viewing user, and credential version. Retain stale observations after failed or incomplete scans. - Add optional Arcade account sync credentials in the vault. Discover Executor accounts through its supported inventory interface. - Group native and upstream accounts in one app card. Imported account menus open their provider. Gateway menus own refresh and sync setup. - Add Paperclip, Composio, Arcade, Installed, and All chips. Show 50 catalog entries per page. Keep connected accounts above discovery. Keep explicit provider searches scoped. - Simplify Composio app setup and refresh its connected app list on the gateway Permissions page. - Add a compact agent access card and task creation defaults for connection setup. Preserve explicit blocks and approval policies. - Add two replay-safe migrations, service and UI tests, Storybook journeys, and acceptance stories. ## Verification - Passed the repository typecheck, full build, token gates, and migration ordering check. - Passed the focused provider adapter, connection interaction, and catalog tests after rebasing onto master. - Passed all nine database sync and migration replay tests using a disposable database on the test-drive PostgreSQL cluster. Removed that database after the run. - Verified Arcade cursor pagination against its official Go SDK and passed all eight adapter tests, including short and incomplete pages. - Passed all 45 interaction tests after making the exact requested tools and their Allowed/Ask first permissions visible before granting access. Verified the compact card in Storybook. - Passed the complete UI suite on the final code: 683 files and 7,432 tests, including the corrected Composio destination assertions. Passed 130 focused tests for the UUID, management-link, and health-status corrections. - Passed 22 Composio setup/sync tests, 23 connection-intent service tests, and the connection migration test in separate disposable databases. Database startup alone was substituted; the suites exercised their real SQL and services. - Passed all 10 OpenAPI route checks and the full-stack connection-intent browser test, including scoped consent, agent continuation, and task completion. - The local full runner encountered embedded PostgreSQL startup failures on this loaded macOS host. The earlier in-flight run also held the pre-fix Arcade transform; a fresh run of the final provider suite passes. The final-head CI is queued during GitHub’s active Actions incident: https://www.githubstatus.com/. The previous run also lost several runners simultaneously; its real catalog assertion failures are fixed and the fresh complete UI suite passes. - Tested the real test-drive server in the embedded browser with a live Composio gateway. Detected Airtable and Circleback. Verified refresh progress, account rows, source chips, search scope, and 50-entry pagination. - Arcade and Executor coverage uses provider fixtures. Live credentials were unavailable. - Storybook builds successfully and includes grouped native/provider accounts, stale and unavailable discovery, optional Arcade setup, and mobile states. The acceptance document records the simulated and live coverage separately. - Greptile reviewed final commit `217b024c27b5933e773ce9419c4e92b1032042c6` at 5/5. All six review threads are resolved, security scans pass, and the PR has no merge conflicts. The outstanding remote checks are `ci / Select trusted runner` and `review`, queued by GitHub. They need to complete before merge. ## Risks - Provider response changes can break inventory discovery. Failed scans retain observations and show stale status. - Composio scans only the supported catalog and can take time. Large inventories run in the background with progress and a bounded lease. - Arcade requires a project API key and user ID when the gateway cannot supply them. This key is used only for discovery. - Executor discovery depends on the server's exposed inventory tools. Unsupported servers report unavailable discovery. - Cached account rows do not grant access or create executable connections. Gateway policies still govern tool use. Account deletion and per-app authorization remain upstream. - The migrations add tables and one nullable column. Replay preserves existing rows and company-scoped foreign keys. ## Model Used OpenAI Codex, based on GPT-6. The session does not expose a more specific serving model ID or context limit. Used reasoning, repository tools, code execution, and browser verification. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [ ] 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> |
||
|
|
cab4263dc9 |
feat(claude-local): add Sonnet 5.5 and refresh the qualified Claude runtime (#14993)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The Claude local adapter lists models for users with a Claude subscription. > - The list needs Claude Sonnet 5.5 and its supported effort levels. > - Sonnet 5.5 needs Claude Code 2.1.284 or later on both execution paths. > - The qualified ACP runtime previously used Claude Code 2.1.280. > - This change adds Sonnet 5.5 and pins Agent SDK 0.3.286, which includes Claude Code 2.1.286. > - Users can select the model and run it with a qualified runtime. ## Linked Issues or Issue Description Refs #3936. This replaces #14816 because the maintainer integration cannot write to the contributor fork. Thank you to @SkilLab-Tech for the model support, runtime refresh, tests, and platform digest verification. This branch preserves both original commits: `8d2f3261af61a2ac1120e51e8a8618732ace543b` and `e68d1d002a3ed745f016fb11c50ac5a3c5a9ff8d`. Related work: - #14917 added Claude model ordering. This branch includes that merged change and resolves its conflicts with #14816. - #14942 updates the other models and harnesses. It remains separate. Its matching Sonnet effort and CLI-gate changes are identical. Both PRs merge with master. The second PR will need a rebase after the first merges because adjacent runtime-pin and test edits conflict. - #14954 is another Sonnet 5.5 change. It overlaps with the model additions but does not include the qualified runtime refresh. - #14039 makes the per-task effort picker model-aware. #3937 is also related to effort selection. The original author checked the [Claude Code changelog](https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md) and [effort documentation](https://platform.claude.com/docs/en/build-with-claude/effort) on 2026-10-01. ## What Changed - Add the direct `claude-sonnet-5-5` model and Low, Medium, High, X-High, and Max effort levels. - Require Claude Code 2.1.284 or later for that model on the CLI path. - Put Sonnet 5.5 after Opus 5.5 in the current-model group. Keep Sonnet 5 in the older-model group. - Retain the Sonnet 5.5 assertions and the model-order assertions in the server tests. - Pin Agent SDK 0.3.286 and Claude Code 2.1.286 across overrides, integrity digests, qualified profiles, Rust provider pins, and the Daytona version check. - Update the related adapter and runtime documentation. ## Verification Local verification uses the resolved source tree and pnpm 9.15.4. Model tests passed on Node 25.9.0. Runtime integrity tests use CI's Node 24.21.0. - Five focused Claude test files pass: 62 tests. They cover model defaults, model ordering, CLI gates, and remote execution probes. - Server model-list and UI setup tests pass: 30 tests. - The Claude adapter typecheck passes. - Runner integrity and qualification tests pass on Node 24.21.0: 78 tests. Four descriptor-loader tests fail on Node 25.9.0; all four pass on the CI version. - The runner package contract passes: 10 tests. - Full local typecheck stopped with exit 137 in the database package under the container's 4 GB memory limit. The production build reached the runner Rust build, then stopped because `cargo` is absent. - The full stable local Vitest run was stopped after all current-head CI test shards passed. It did not complete locally. The 180 focused tests listed above passed. - `git diff --check` passes. The branch changes 20 files against master. It has no lockfile or workflow changes. - The original author verified all three platform digests against registry integrity and ran the Linux executable. Its version was `2.1.286 (Claude Code)`. See #14816 for that evidence. - Greptile reviewed head `6db3d3f1` and gave 5/5 with zero comments. Both Superagent scans and Commitperclip pass. All current-head CI jobs pass, including build, typecheck, Rust, test shards, browser tests, and the canary dry run. ## Risks - The controller and provider pack must use matching runtime pins. Deploy them together. - CI owns `pnpm-lock.yaml`. The master lockfile refresh must resolve the SDK override. Refresh the Daytona lock digest with that lockfile. - Images built with Claude Code older than 2.1.284 need a rebuild before the CLI path can use Sonnet 5.5. - The runtime remains at SDK 0.3.286. This PR does not take the later 0.3.287 patch. - A live Sonnet 5.5 session and a Daytona image build are not part of the local verification. ## Model Used - Original work: Anthropic Claude Code, `claude-sonnet-5-5`. Review: `claude-opus-5-5`. The author reported `xhigh` effort, tool use, and code execution. The original context window was not reported. - Merge repair and PR preparation: OpenAI Codex, based on GPT-6, with tool use and code execution. The runtime does not expose the exact model identifier or context window 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 ## Squash Attribution Keep these trailers in the squash commit to preserve the original author and AI attribution: ```text Co-Authored-By: Claude Code (Ivan) <SkilLab-Tech@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Co-Authored-By: Paperclip <noreply@paperclip.ing> ``` --------- Co-authored-by: Claude Code (Ivan) <ivan@skillab.com.br> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
17fa718675 |
Retry transient disconnects in scoped read queries (#15248)
Apply existing bounded transient-disconnect retries to audited dashboard, heartbeat-list, and base issue reads. Rebuild each query per attempt and preserve authorization, company scope, enrichment, and final error propagation. Validation: exact-head Greptile 5/5, passing CI, no unresolved review threads, and a clean merge. Detailed verification and limitations are recorded in the pull request. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
3b47a6befd |
Record bounded workspace restore failure stages (#15005)
Capture allowlisted restore substep and failure metadata for future diagnosis while preserving workspace recovery behavior, error identity, cleanup ordering, and privacy. Validation: exact-head Greptile 5/5, passing CI, no unresolved review threads, and a clean merge. Detailed verification and limitations are recorded in the pull request. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
2e67ea8dc7 |
fix: renew explicit continuation authorization for bounded retries (#14987)
Preserve exact user-authorized continuation receipts across bounded retries and retain the task claim through owned retry admission. Stop, reassignment, superseding input, and active cleanup continue to block unsafe continuation. Validation: exact-head Greptile 5/5, passing CI, no unresolved review threads, and a clean merge. Detailed verification and limitations are recorded in the pull request. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
a65ca09508 |
fix(runner): settle accepted results after shutdown failures (#15217)
## Thinking Path > - Paperclip manages AI agents and the tasks they perform. > - The native runner saves tool results and completion reports before it releases a session. > - Large project discovery responses can exceed the durable command limit. > - A shutdown failure can leave a saved answer waiting for workspace repair. > - Recovery reused the old assessment for a different status decision, which violated a database constraint. > - This pull request bounds discovery responses and lets recovery commit the saved result after workspace repair. > - The benefit is a task that reaches its correct final status without another provider turn. ## Linked Issues or Issue Description **What happened?** A native run can save its final answer, fail during shutdown, and leave the task In Progress after workspace repair succeeds. Reconciliation tries to reuse the failed-workspace assessment for a new decision. The one-decision-per-assessment constraint rejects the write. Replaying the old decision can also retain a fresh coordinator lease. Separately, retained session cleanup only recognizes the old `adapter_failed` label. The project-list tool returns full project records, including large descriptions and workspace configuration. A large response exceeds the runner's durable command limit. The settlement diagnostic previously recorded only a failure flag. **Expected behavior** Project discovery stays within the command limit. Recovery finishes the saved result after workspace repair, releases its lease, and preserves the original error for inspection. It does not repeat provider work or relax session ownership checks. **Steps to reproduce** 1. Return large project records from `list_projects` and observe an oversized semantic result. 2. Persist an accepted native completion result, then record a shutdown failure. 3. Finalize with a failed workspace, repeat that attempt, then record successful workspace repair. 4. Reconcile the run. Before this fix, the issue stays In Progress. **Paperclip version or commit** Reproduced on `a386a599983519eb1d399f8b770bfccdb2a74762`. **Deployment mode** Self-hosted server with Paperclip Runner. Related transport work: #12208 drains queued events; #12241 resumes interrupted semantic calls. This change addresses bounded project discovery and accepted-result finalization. ## What Changed - Read bounded project summary projections from the database and return at most 50 authorized summaries with a continuation cursor and explicit description truncation. Agent and run trust boundaries narrow the database candidates; project-specific policies still receive full authorization. Only visible projects determine continuations. The default project-list API remains unchanged. - Record bounded, content-free settlement failure causes for command limits, storage errors, and rejected dispatch. - Include workspace state in assessment identity. Preserve the initial assessment for interrupted finalization, and commit replacement assessment and decision references together. - Release the coordinator lease when an existing decision is replayed, without repeating its effects. - Clear stale errors when recovery succeeds and retain them in `recoveredExecutionFailure`. - Accept both current and legacy close-failure labels in the existing exact-state cleanup path. - Add regression tests and update the tool contracts and recovery documentation. ## Verification - Red: the new project paging, settlement diagnostic, current cleanup label, and repaired-workspace regressions failed on the original implementation. - Green: protocol/catalog/tool checks (117 tests), the full project-tool and finalizer suites (47 tests), cleanup ownership cases (70 tests), and cleanup sweep cases (4 tests) pass. Database-backed pagination covers large descriptions/configuration, complete enumeration, uppercase cursors, agent/run restrictions, project-policy scope contributions, and identical results/cursors when hidden projects are added. - The initial CI failures in interrupted Board waits, contended endpoint proof, and semantic schema validation were reproduced and fixed; all affected cases pass locally. - `pnpm -r typecheck` — passed. - `pnpm build` — passed. - `pnpm test:run` — started before the review corrections; it spanned several source revisions and was stopped after reporting old-behavior and timing failures. It is not claimed green. Fresh project and recovery suites pass; the recovery suite also passes all 25 cases with the broad runner’s isolated home/config. The Slack timing case passed in isolation. Latest-head CI is the authoritative complete test matrix. - Existing authorization suite — 66 tests passed. - Latest-head CI on `8e5763d915aa6f375bdab6601996899ea01496fc` — 55 checks passed, 4 intentionally skipped, no pending or failing checks. - Greptile — 5/5, zero unresolved threads on the same commit. - `git diff --check` — passed. ## Risks - `list_projects` now returns summaries. Callers must follow `nextCursor` and use the authorized project API for full records. Candidate narrowing is only an optimization: project policy and responsible-user authorization remain authoritative. - Assessment identity changes for workspace finalization. Existing evidence remains intact; no migration is needed. - Cleanup still requires matching identities, settled tool evidence, and verified process ownership. Unknown tool outcomes remain blocked from session reuse. ## Model Used OpenAI Codex, based on GPT-6, with reasoning, code execution, and GitHub 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> |
||
|
|
1c07b5903b |
feat: Chat leads the left nav, agent work beside chats, and a Combined Inbox + Task List flag (#15100)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The left nav is the main way people move between tasks, the inbox, and Agent Chat > - The nav has separate Inbox and Tasks rows that show overlapping work, and Chat is one row among many > - The side panel beside a chat shows the conversation's own artifacts, not the work the agent did > - People want Chat to be easy to find, and they want one place for their task views > - This pull request moves Chat to the top of Work, shows the agent's tasks and artifacts beside each chat, and adds an experimental flag that folds Inbox into Tasks > - The benefit is a shorter nav and a chat view that shows what the agent is working on. Both changes stay off until an operator enables them ## Linked Issues or Issue Description Refs #14706 (the secondary Agent Chat navigation this change builds on) Refs #14848 (reopen the last visited agent chat) **Subsystem affected** UI navigation (left nav, mobile tab bar), Agent Chat side panel, task list and inbox, and the company artifacts API. **Problem or motivation** Inbox and Tasks are two nav rows for overlapping work. Chat sits in the top group with no clear home. The chat rail lists only agents you already talked to, so you cannot see your other teammates there. The side panel beside a chat shows only the conversation's own artifacts. It does not show the tasks and files the agent made. **Proposed solution** With Agent Chat on, Chat leads the Work section and the rail lists every eligible agent. The chat side panel opens on the agent's tasks as cards, and the agent's artifacts are available from +. A new experimental flag, Combined Inbox + Task List, makes Inbox a set of views inside Tasks. **Alternatives considered** Rebuilding the inbox inside the task list. Instead, `/issues` hosts the existing Inbox component for inbox views and the existing task list for status views, so all inbox behaviour stays the same. **Roadmap alignment** Agent Chat (ROADMAP.md, "Agent Chat (including CEO Chat)"). All changes are behind experimental flags that are off by default. ## What Changed - **Agent Chat nav (streamlined shell):** Chat is the first row of Work, not a top-group row. Workspaces leaves the nav while Agent Chat is on. The mobile tab bar is Home · Chat · + · Tasks · Agents. The legacy shell keeps master's top-group Chat row. - **Chat rail:** `AgentConversationsSidebar` lists every eligible agent. The open chat is first, then conversations by recent activity, then the rest of the roster alphabetically. Terminated agents and agents you left are omitted unless you have history with them. The picker still marks only real conversations as "Open chat". - **Chat side panel:** a new default Tasks tab shows one card per task the agent created, was assigned, commented on, or acted on, newest first. It has the task list's filter popover and a sort control. **+ → Artifacts** shows the agent's artifacts as cards. Cards open in a new tab. Agent Chat off keeps the old Artifacts tab. - **Artifacts API:** `GET /api/companies/:companyId/artifacts` accepts `agentId`. The filter applies to documents, work products, and attachments by the agent each result is attributed to. The shared validator and the UI client carry the new parameter, and the OpenAPI entry picks it up from the shared schema. - **Combined Inbox + Task List flag (`enableCombinedInboxTasks`, off by default):** new card in Settings > Experimental. The Inbox row goes away and its badge moves to Tasks. A Views menu on `/issues` covers Mine, Unread, Blocked, Recent, Everything, All, Active, Backlog, and Done. Bare `/issues` opens the last-used view (default Mine). Links that carry `assignee`, `workspace`, `participantAgentId`, or `q` open All so the filter is kept. `/inbox/*` and `/issues/{all,active,backlog,done,recent}` redirect to the matching view. `/inbox/requests` stays its own page. - **Task detail breadcrumb:** the view key now decides the source, so quick-archive still works after a reload from an inbox view. - **Docs:** `doc/PRODUCT.md` and `doc/SPEC.md` describe the chat rail, the chat side panel, and the new flag. ## Verification - `cd ui && npx vitest run --no-file-parallelism src/components/chat src/components/task-side-panel/TaskSidePanel.test.tsx src/components/AgentConversationsSidebar.test.tsx src/components/Sidebar.test.tsx src/components/SidebarCompanyMenu.test.tsx src/components/Layout.test.tsx src/pages/AgentChats.test.tsx src/pages/InstanceExperimentalSettings.test.tsx src/lib/task-views.test.ts src/lib/issueDetailBreadcrumb.test.ts src/pages/Inbox.test.tsx src/pages/Issues.test.tsx src/App.test.tsx src/App.activity-routing.test.tsx src/components/MobileBottomNav.test.tsx src/components/CommandPalette.test.tsx`: 20 files, 356 tests pass. - `cd server && npx vitest run src/__tests__/company-artifacts-service.test.ts`: 13/13 pass, including the new agent-filter test across all three artifact sources. - The new rail test fails against the unmodified rail. - `pnpm check:token-gates`: all gates clean. - Manual: enable Agent Chat in Settings > Experimental. Open Chat. The rail lists all agents. Open a chat. The side panel shows the agent's tasks. Use **+ → Artifacts** to see the agent's artifacts. Then enable Combined Inbox + Task List. The Inbox row goes away, and Tasks shows a Views menu. - Snapshot baselines are intentionally not updated. See `doc/design/DECISION-SHEET.md`, "Per-change snapshot verification demoted to dormant (Jul 13 2026)". ## Risks - With both flags off, the app behaves like master. The only exception is the API: it accepts a new optional query parameter. - With Agent Chat on, the rail can list many agents in a large company. It uses the agent list the app already loads, and search filters it. - The Tasks panel reads at most 200 recently updated tasks per agent and says so when it reaches the limit. The Artifacts panel reads at most 500 of the agent's artifacts. - Combined Inbox + Task List changes what bare `/issues` opens for people who enable it. Deep links with a task filter still open All. ## Model Used - Claude (Anthropic), model ID `claude-opus-5-5`, through Claude Code with tool use (shell, file edit, test runs). Extended thinking was enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] 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 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: scotttong <squadbot000@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
994d6edcdd |
Fix Markdown in provisional task titles (#15047)
## Thinking Path > - Paperclip uses issues to organize work for AI agents. > - Paperclip creates a provisional issue title from the issue description. > - A description can start with a Markdown image or other Markdown syntax. > - The old title logic truncated the raw Markdown source. > - This pull request parses Markdown before it truncates the title. > - The benefit is a short and readable provisional title. ## Linked Issues or Issue Description **What happened?** When an issue description started with a Markdown image, Paperclip used the raw image syntax and URL in the provisional title. Other common Markdown markers could also appear in the title. **Expected behavior** Paperclip must remove Markdown syntax before it creates the 120-character provisional title. It must keep useful text, such as link labels and inline code content. **Steps to reproduce** 1. Create an issue without an explicit title. 2. Start the issue description with a Markdown image. 3. Add Markdown text after the image. 4. Observe that the provisional title contains raw Markdown syntax or an image URL. **Paperclip version or commit** The problem reproduces on `master` before this change. **Deployment mode** Local development with the embedded PGlite database. ## What Changed - Parse the description and remove image nodes before title generation. - Convert the remaining Markdown to plain text before the 120-character limit. - Keep link labels, inline code, and identifier punctuation. - Use image alt text, or `Image`, for an image-only description. - Fall back to a simple 120-character title if Markdown parsing or conversion fails. - Add regression tests for image and inline-code titles, parser failures, and text-conversion failures. ## Verification - `./node_modules/.bin/vitest run server/src/__tests__/task-title-routes.test.ts` - `./node_modules/.bin/tsc -p server/tsconfig.json --noEmit` - Full GitHub CI matrix passed on commit `663f3a0517c9e450f174b6c37970756457067ba5`. - Greptile reviewed the latest commit with a 5/5 confidence score and no unresolved findings. ## Risks - Low risk. This change only affects generated provisional titles. It does not change explicit titles or full issue descriptions. - The implementation uses the Markdown parser and plain-text converter that are already present in the server. > This is a focused bug fix. It does not add planned core work from `ROADMAP.md`. ## Model Used - OpenAI Codex with GPT-5. The run used reasoning, tool use, code execution, and repository access. The runtime did not expose the context window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [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> |
||
|
|
b17019e14d |
fix(agents): reduce default instructions and qualify stock harnesses (#14948)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Its adapters supply task context and access to Paperclip skills and tools. > - The default hire manual and shared prompts also repeat general work procedures. > - Those procedures overlap with stock provider instructions and the Paperclip skill. > - Existing E2E fixtures supply a QA manual, so they do not qualify the production default. > - This pull request reduces the generic instructions and adds real default-hire coverage. > - The benefit is less competing guidance, with inspectable evidence for preserved skills and task context. ## Linked Issues or Issue Description Refs: #14920. That merged change preserves native Codex base instructions. This PR covers the default manual, shared legacy prompts, operational skill guidance, and the narrowly approved ACP skill-discovery/session-environment repair for measured delivery and credential-persistence failures. **What existing behavior does this improve?** New non-CEO hires without a custom bundle and legacy task/chat startup and continuation prompts. **Current behavior** The shipped default manual contains 602 words. Generic task/chat prompts and ordinary resume deltas repeat work procedures already available through the harness and Paperclip skill. **Proposed behavior** The default manual contains only the eight-word company identity. Shared startup prompts retain identity and connection guidance. Ordinary resume deltas retain current work context without the generic execution contract. **Reason and benefit** Let the stock harness guide general work. Keep Paperclip-specific capabilities and independently test default hires, skills, ordered comments, and chat restart. **Breaking changes** New default hires receive less guidance. Existing saved manuals, explicit custom bundles, CEO templates, and specialized wake contracts retain their behavior. The obsolete includeExecutionContract option remains accepted for source compatibility. ## What Changed - Reduce the default hire manual to one sentence. - Reduce shared task/chat defaults and remove the generic ordinary-resume contract. - Keep connection guidance, auth, skills, custom prompts, and specialized wake context. - Add credential-free instruction-boundary gates and 26 explicit Product E2E cells across eight legacy/native profiles, including two focused Paperclip-storage cases. - Capture public hire receipts before providers run, then grade delivered prompts and independent task/chat outcomes. - Add an early legacy skill API recipe for saving a task document, checking the saved revision receipt and linking the document. Improve stock task/heartbeat skill-selection metadata and show a clickable Markdown UI-link example. Keep native tool completion separate. - Advertise bounded routing descriptions and exact successfully staged SKILL.md paths in legacy ACP Claude; keep full bodies on demand and preserve remote path rebasing. - Remove only the provider environment from copied persisted ACP session records, while loading current run credentials and preserving all other options/conversation state. - Regenerate both capability metadata inventories and reject stale manifests/inventories before provider admission. - Publish the original reduction and focused skill-repair comparisons, preserving all failures, automatic recovery, cost coverage and limitations. ## Verification **Behavioral qualification remains pending.** Original legacy ACP Claude loses the issue document only in the reduced cohort beneath an unchanged credential failure. A source-backed diagnosis finds that neither ordinary assignment reads the staged operational skill, while the runtime persists provider environment in session state. The new common repairs expose skill metadata/path and omit persisted env; strict document and credential guards stay intact. [Inspectable diagnosis and retained hashes](https://github.com/paperclipai/paperclip/blob/9f654db4541d3d002769c988f6e51fc0b08dadbd/doc/plans/2026-10-03-legacy-acp-claude-readiness.md). Current repair head `de0965984ff3edf611ae6d0e7ca5c7d5ae3947bb` incorporates master `569c7203aa24b95440682983ce7940ba1d4247bd` (merged #14961/#15007). All 222 affected adapter tests, adapter-utils/E2E typechecks, and final 96 variant/grader/retry calibrations pass. The frozen historical comparator is `c25697f4260b6f3adfea143c3ae9932e2f42986d`: 8,280 of 8,291 paths identical, exactly two production instruction paths plus nine declared unit expectations differ. The operational skill/discovery/environment repairs, selected model/profile/task/core grader/auth/permissions/retry policy are identical. Both actual launcher prepare→verify admissions pass with zero providers. [Immutable manifest and exact receipts](https://github.com/paperclipai/paperclip/blob/9f654db4541d3d002769c988f6e51fc0b08dadbd/doc/plans/2026-10-03-legacy-acp-claude-evidence/manifest.json). One original legacy ACP Claude cell per variant is authorized, with enforced single campaign attempts, 12-minute deadlines and company/agent 1,000-cent hard stops; every product recovery run/cost is counted. Actual live outcomes are pending. Current normal CI has one failed server shard and failed aggregate verify under diagnosis; other normal gates including typecheck/build/Rust/all eight browser shards pass. Fresh review completed successfully; the valid historical startup/resume masking finding was fixed with per-invocation task/chat checks and strict complete-snapshot capture, calibrated and resolved. Prior heads, failures and campaigns below remain historical evidence, not checks on this repair head. - Prior head `36aa4d81c49a1a8f6f04b1a068fae19aa901955f` is replayed on merged hiring master `862a5758ba0e88a33232c1f1fa645e85c38a3113`. All 52 current-head checks pass with two intentional Storybook skips, including repository typecheck/test/build and the browser shard. Fresh Greptile is 5/5 with zero unresolved review threads. Exact-head stock prerequisites pass 599 assertions (598 TypeScript + 1 Rust), all six gates and retained receipt verification, zero providers/source errors. Fingerprint `a7f5a22d860a88fe20cce213c6d5e0004788f32c8363930729aea4fd740ad16d`. Combined catalog/hiring calibrations pass 67 assertions, E2E typecheck and 26-cell stock discovery pass. Canonical contract/inventory checks and the later issue-derived reference calibration are retained; that reference-only follow-up is not live-qualified by earlier frozen runs. - Prior full repository typecheck/build passed. The complete local Vitest run executed 14,956 tests: 14,870 passed, 83 skipped, three timing failures. All three affected files passed unchanged narrow reruns; original failures remain retained. Current-head CI now passes the full general checks; the original local failures remain retained. - The original 24-pair default-manual/shared-prompt comparison has two new overall classic Claude/OpenCode document-delivery failures plus an additional legacy ACP Claude document loss beneath an unchanged credential-guard failure (not closed by later runs), two newly passing OpenCode ordered cases, seven unchanged failures and 13 unchanged passes. Equal 15/24 totals do not establish behavioral equivalence. [Complete original report](https://github.com/paperclipai/paperclip/blob/875f4c397d9e8c3f12f39dedd59abaf1eaf5236e/doc/plans/2026-10-02-stock-harness-live-comparison.md). - The skill-only repair holds the eight-word manual/shared prompts and merged #14920 fixed. All four matched profile configurations and 203 fixture/behavior files match. Candidate `abd0b628ca642c09a54a4edc56a5227402f6686e` varies only the two skill sources against baseline `bc83fe030234439ac51279502a28803958963e2e`. [Candidate workflow](https://github.com/paperclipai/paperclip/actions/runs/37060885547) and [baseline workflow](https://github.com/paperclipai/paperclip/actions/runs/37060888047) each pass 571 exact-source prerequisites before providers; all eight cells clean up successfully. Failed campaigns publish successfully and remain failed. - Repair pairs: Claude original Fail → Pass; Claude explicit Pass → Pass; both OpenCode cases Fail → Fail. Explicit OpenCode's handoff worsens beneath the unchanged failing UI-link grade: baseline gives a clickable API URL, candidate gives a code-formatted path without an anchor. The request's usable-link wording is narrower in the UI-only oracle. [Complete repair report and safe projection](https://github.com/paperclipai/paperclip/blob/875f4c397d9e8c3f12f39dedd59abaf1eaf5236e/doc/plans/2026-10-02-legacy-document-skill-repair.md). - The subsequent narrow stock metadata/link correction has two matched Pass → Pass cases, zero new machine failures/passes and no pending pairs. Both original-case handoff links remain deficient: candidate uses a wrong PAP prefix, baseline supplies a bare prefix-less slug path; the preserved original oracle only requires a durable document. Both explicit clickable UI-link cases pass revision/content/link grading. All four exact-source 587-check gates, single assignment runs and cleanup pass. This does not establish fix causality because baseline also succeeds. [Candidate workflow](https://github.com/paperclipai/paperclip/actions/runs/37069547401) freezes `fe9dc1e3c518825242ed889ab9c8352986f8c2ed`; [matched baseline](https://github.com/paperclipai/paperclip/actions/runs/37069552374) freezes `0d7ecfa96d72fba79b7f0a25052b42c0686c0488`. This is a skill-only comparison with reduced manuals/shared prompts held constant, not a repeat of the historical-manual comparison. Only original and clarified explicit classic OpenCode cases are selected, two per variant/four expected turns. 8,242 other tracked files and both profile hashes match; protected workflows admit each exact source before credentials. [Complete qualification report](https://github.com/paperclipai/paperclip/blob/74d0d3d945f4c52d0814b5a845ab5bd09f33cd6b/doc/plans/2026-10-02-opencode-skill-routing-link-qualification.md). Candidate original loads Paperclip/reference before saving publicly; baseline original loads it after writing locally, then saves publicly within the same assignment. Reported cost totals are $0.0107824490 candidate / $0.0107909015 baseline, with unmetered runtime. The later reference-only issue-derived link correction is provider-free calibrated and **not live-qualified** by these frozen runs; no further paid runs. - Retained tool calls show the repaired original OpenCode assignment loads only its assigned output skill before writing locally. Operational Paperclip is first loaded during automatic disposition recovery; its early recipe is visible then, but it never saves the missing document. Explicit candidate loads Paperclip and reads the new reference before saving successfully. All nine actual runs are counted. Reported LLM totals are $0.3802537209 baseline and $0.4918990161 candidate; local runtime is unmetered. - Initial setup, packaging, cancelled/missing-cell recovery, callback test and relative-output attempts remain retained. No completed provider failure was rerun. Frozen measurement branches are unchanged by later canonical metadata maintenance. - Run `pnpm test:e2e:runner:stock-harness`, `pnpm test:e2e:runner:unit`, and `pnpm test:e2e:runner:typecheck`. Select `stock-harness` explicitly for paid execution; it is excluded from `--all`. Prior-head integration: `36aa4d81c49a1a8f6f04b1a068fae19aa901955f` replays this PR on merged hiring #14985 (`862a5758ba0e88a33232c1f1fa645e85c38a3113`), preserving the four explicit custom-CEO-bundle checks, minimal generic manual boundary, and both suites. The combined fixture catalog and hiring calibrations pass 67 assertions; exact-head stock prerequisites pass 599 assertions (598 TypeScript + 1 Rust), all six gates and retained-receipt verification, zero providers/source errors, fingerprint `a7f5a22d860a88fe20cce213c6d5e0004788f32c8363930729aea4fd740ad16d`. E2E typecheck and 26-cell stock discovery pass. Fresh current-head CI passes all 52 checks with two intentional skips, and fresh Greptile is 5/5 with zero unresolved review threads. The prior source-plan browser failure is retained: a deterministic process fixture replayed its last `fixture:plan` command on `chat_task_completed`, writing revision 2 with identical body after the approval handoff. This was not paid provider execution. Rebased current-head CI passes the same assertion without an old-head retry or a change to that browser fixture. The merged hiring change was measured separately on immutable matched unions, with this reduced/shared/operational context and native completion guidance held constant. [Complete original two-profile report](https://github.com/paperclipai/paperclip/blob/f0512647656be78e48abd8c22a3078db8bf6bcd2/doc/plans/2026-10-02-hiring-template-live-comparison.md): [candidate](https://github.com/paperclipai/paperclip/actions/runs/37075466208) / [historical baseline](https://github.com/paperclipai/paperclip/actions/runs/37075469463), 705 provider-free prerequisites each. Both pairs are unchanged Fail → Fail on the exact-five count, with six core delivery checks passing all four cells; 28 actual successful runs include eight automatic completion wakes, zero retries, four successful cleanups. Source-read coverage is uncomparable, actual model charges unknown. Separately versioned provider-free accounting remains analytical work; original verdicts are preserved. This does not rerun or qualify the completed default-manual or native campaigns. ## Risks - Legacy ACP Claude's additional delivery loss is not closed by any later matched run and blocks the no-extra-failing-behavior merge criterion. Legacy document delivery may have relied on the prior manual/shared prompts. The early skill repair improves Claude in one trial; the later OpenCode pairs pass in both variants and cannot establish causality or robust recovery. Both original-case links remain deficient beneath the storage-only grade. The later issue-derived reference correction has only provider-free validation. Native finish/block descriptions must not be supplied to legacy agents. - The comparison holds merged native Codex fix #14920 constant; it cannot measure that fix's before/after task performance. - These bounded skill/context/chat workflows do not measure general coding quality. Unrepresented providers remain unqualified. - Saved manuals and old Codex sessions are not automatically migrated. Codex through ACP still has a separate base-instruction follow-up. ## Model Used OpenAI Codex, GPT-6 family as identified by this session. The exact deployment ID and context-window size are not exposed. The assistant used reasoning, repository tools, code execution, and delegated PR/eval work. ## 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 (relevant suites and all three unchanged narrow reruns pass; complete-run timing failures retained in Verification) - [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 on the new repair head (prior-head checks retained above) - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups on the new repair head - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
ffe5e9e2a8 |
fix: retain execution evidence for Retry and saved input (#15033)
## Thinking Path > - Paperclip lets people steer and recover AI-agent conversations. > - Recovery eligibility depends on retained cancellation receipts. > - Run presentation intentionally omits result JSON on SQL_ASCII databases and reduces oversized output. > - Retry and the saved-input sweep mistakenly used that presentation read for admission. > - The banner could offer Retry while the endpoint rejected the same stopped run. > - Read the narrow execution-evidence fields for internal admission and keep normal presentation unchanged. ## Linked Issues or Issue Description Refs #15024 and #15015. Searched existing recovery and redaction PRs; no duplicate fix found. **What happened?** On a SQL_ASCII instance, a verified pre-dispatch review-wait cancellation offers Retry in the recovery notice. Clicking it returns an eligibility conflict, and a saved user message remains deferred. The notice reads the retained database receipt, but the endpoint and sweep read a presentation projection where `resultJson` is null. **Expected behavior** Retry and saved user input use the recorded execution evidence and ordinary admission gates, independent of presentation redaction. Public run reads retain their existing encoding and output-size protections. **Steps to reproduce** 1. Record a cancelled, unclaimed review-wait continuation and its recovery hold. 2. Use the SQL_ASCII presentation projection, where run result JSON is omitted. 3. Click Retry or save a new user message and let the recovery sweep inspect it. 4. Verify a fresh turn starts once, with no replay of consumed input. **Paperclip version or commit** Reproduced on `9ae3d8db3`. **Deployment mode** Authenticated private self-hosted server with a SQL_ASCII database. ## What Changed - Add an explicit internal read of cancellation, startup, review-wait, tool-inventory, and Stop evidence; omit provider diagnostics. - Use that read in the Retry route, wakeup validation, and saved-input continuation checks. - Preserve the distinction between absent result JSON and an unrecognized stored result. - Cover the reproduced SQL_ASCII Retry and saved-input failures, retained public redaction, native Stop behavior, and excluded provider output. - Document the presentation and admission distinction. ## Verification - Red: four selected assertions fail before the fix, including the SQL_ASCII eligibility conflict and saved input remaining deferred. - Targeted green regressions and existing native Stop cases pass. - Workspace `pnpm -r typecheck` and `pnpm build` pass. - All 626 affected recovery, continuation, and route tests pass, including 22 focused admission and native Stop cases. Current-head CI has 54 passing gates and 2 skipped optional Storybook checks. Greptile reviewed `9b94af91e295a4e8007dfc6bff6a8d532d945e36` at 5/5 with no findings or open review threads. No complete local monolithic pass is claimed; the complete suite runs in sharded CI. ## Risks Admission still checks recorded process and controller ownership, provider events, cleanup, company scope, user authority, pending decisions, and task holds. The evidence projection must retain every field used by these eligibility predicates; existing native Stop cases guard against dropping its acknowledgement receipt. No schema, dependency, UI, or public response change. ## Model Used OpenAI Codex, an agent based on GPT-6. The exact runtime model ID and context window are not exposed in this session. Used reasoning, repository tools, code execution, and browser inspection. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
9ae3d8db3d |
fix: keep pre-dispatch review waits out of execution recovery (#15024)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The queued-run gate can cancel a continuation that must wait for review. > - This cancellation happens before execution authority or a provider starts. > - Recovery currently treats the gate receipt as unknown provider execution. > - That mistake blocks a conversation after a successful reply and hides Retry. > - This pull request recognizes only the recorded, unclaimed review-wait state. > - Review waits keep their normal disposition path, and new user input can recover older false holds. ## Linked Issues or Issue Description Refs #15015, #15020, and #15022. Related #11614 narrows the review posture that causes cancellation; this change corrects recovery after a valid cancellation. **What happened?** After a successful agent reply, the queued-run gate cancelled an automatic continuation with `issue_continuation_waiting_on_review`. The gate retained `timeoutSource: stale_queued_run_gate` and a matching stop reason. No execution authority or provider started. Recovery still created an unknown-action hold, moved the task to Blocked, and hid Retry. **Expected behavior** Use normal review-wait disposition repair for this recorded state. Allow Retry, a new user message, or saved undelivered input to recover an older false hold after ordinary admission checks pass. Preserve the cancelled run and do not replay its input. **Steps to reproduce** 1. Finish an agent turn on an open task that has a real review target. 2. Let the automatic continuation reach the queued-run review gate. 3. Refresh after the cancelled run is checked by recovery. 4. Confirm a review wait is handled as a wait rather than unknown provider work. 5. Reproduce an older false hold for the same receipt, then request Retry or send a new message. 6. Confirm only one fresh turn starts, and contradictory execution or cleanup evidence retains the hold. **Paperclip version or commit** Reproduced on `215586d127`. **Deployment mode** Authenticated private self-hosted server, built from source. ## What Changed - Recognize the exact review-wait dispatch receipt only while all execution claims remain unset. - Exempt recovery only after checking retained launch and provider events, coordinators, and environment cleanup. Keep the synchronous classifier conservative without that database proof. - Apply the verified classification to automatic recovery, heartbeat retries, and stranded-queue release, so saved user input starts once. - Reuse guarded startup admission for Retry, new input, and saved input on older false holds. - Show a precise review-wait notice and keep continuation guidance consistent with Retry availability. - Verify provider events, launch events, coordinators, and cleanup before admission. - Add five initial red regressions, three additional red recovery evidence regressions, concurrent saved-input coverage, and negative evidence checks. - Document the review-wait contract. ## Verification - Red: five regressions fail on unchanged master. Existing review-wait and contradictory-evidence cases still pass. - Workspace `pnpm -r typecheck` passes. - All 752 affected recovery, continuation, queue, classification, and retry-scheduling tests pass. - Three additional review regressions failed before the database proof was added; all 12 focused review-wait cases then pass. - Workspace `pnpm build` passes. - Saved-input promotion and recovery notice regressions fail before their fixes and pass afterward. - Current-head CI has 54 passing checks and 2 skipped optional Storybook checks. Greptile reviewed `0bf1437110e1617ae4544afa41f4319eac763dba` at 5/5 with zero open findings. The complete suite runs in sharded CI. No complete local monolithic pass is claimed; an earlier long run was stopped, and its unrelated failing case passed in isolation. ## Risks The error code alone cannot establish that no provider started. This exception also requires the server gate receipt, matching stop reason, and null execution authority fields. User admission separately checks coordinator, launch and provider events, environment cleanup, pending decisions, ownership, task holds, budget, and active execution. No migration or dependency change. ## Model Used OpenAI Codex, an agent based on GPT-6. The exact runtime model ID and context window are not exposed in this session. Used reasoning, repository tools, code execution, and browser inspection. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
cc67d4e1d8 |
fix: preserve steering and recover stopped task conversations (#15015)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - A task conversation must let a user guide a running agent and resume stopped work. > - The active run owns its input protocol, even when the user changes the next model or effort. > - Queue delivery waits for a provider receipt, which must be able to persist during the request. > - A stopped startup also needs a clear user action that passes normal task admission. > - This pull request fixes steering delivery, makes queue actions immediate, and restores explicit continuation. > - The benefit is a responsive conversation that can recover without losing saved input. ## Linked Issues or Issue Description **What happened?** A queued message could change from Steer to Interrupt while a native run prepared. A steer request could wait on its own database lock and fail to deliver. A stopped startup could then leave the conversation without a working Retry or message continuation. Interrupt also waited for the server and showed a toast. **Expected behavior** The active run keeps its input protocol. Steer delivers input to that run. Steer and Interrupt clear the submitted queue rows and show the input in the conversation immediately. Failed delivery restores the latest queue with an inline error. An eligible stopped run offers Retry, and authenticated user input can start a fresh turn through normal task admission. **Steps to reproduce** 1. Start a task with a native Paperclip Runner. 2. Change the selected model or effort while that run prepares. 3. Queue a message and press Steer. 4. Observe the provider receipt and queue state during the request. 5. Stop a startup before its provider process begins, then try Retry or send a new message. 6. Repeat queued delivery with a legacy runner and press Interrupt. **Paperclip version or commit** Reproduced on the parent of this branch, `59c07ede7`. **Deployment mode** Authenticated private deployment. The fixes also cover local task conversations. Related work: Refs #12834, Refs #13354, Refs #13275. The open refactor in #13160 moves the same queue route; it does not fix the receipt lock or stopped-run continuation addressed here. ## What Changed - Select queue behavior from the active run's immutable dispatch and runtime resolution. - Leave the run row unlocked during provider acknowledgement, then lock and read it before merging the receipt. - Retain queued input if the target run stops during that wait. Keep inline delivery errors visible after empty queue updates. - Permit exact Retry and authenticated continuation after verified native startup cancellation. Preserve pause, approval, budget, ownership, and process-stop gates. - Carry undelivered native queue input into a fresh turn once the old execution is confirmed stopped. - Show Steer and Interrupt input in the conversation and clear submitted composer rows immediately. Restore the latest queue inline on failure. Remove delivery toasts. - Keep optimistic delivery stable across stale polls, empty queues, and paginated history. Preserve classic Interrupt error handling. - Document recovery and optimistic delivery behavior. Add regression tests across server, shared queue projection, and UI boundaries. ## Verification - Red-green regression tests reproduced the queue protocol, receipt lock, stopped-startup continuation, and optimistic delivery failures. - The focused server route, continuation, queue, and runner boundary suites passed during implementation. - The queue-route suite passes with 78 tests. The three complete conversation UI suites pass with 347 tests. - UI typecheck, production build, and `pnpm check:token-gates` pass. - Workspace `pnpm -r typecheck` and `pnpm build` pass. The local monolithic `pnpm test:run` is still running; remote CI verifies the complete suite on the latest commit. - All CI gates pass on `bd9031ad56abfcde13d13a13488c1b9217c2fd3a`, including the full test shards, runner verification, browser E2E, typecheck, release registry, and canary dry run. - Greptile reports 5/5 for that commit. Both review threads are resolved. ## Risks This changes queue display and explicit continuation admission. The UI must restore rejected delivery without losing other-session edits. The server must preserve concurrent provider result updates and must not resume a process whose stop is uncertain. Focused tests cover these boundaries. This change has no database migration. ## Model Used OpenAI Codex, an agent based on GPT-6. The exact runtime model ID and context window are not exposed in this session. Used reasoning, repository tools, code execution, and browser inspection. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
1815474597 |
fix: report pending execution phase at Stop timeout (#14990)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The server owns each adapter execution and waits for it to settle after Stop. > - A Stop timeout reports that termination remains unverified. > - Existing phase timings arrive only after their work completes, so a stalled await has no timing. > - This pull request samples the pending phase when the Stop timer expires. > - Operators can identify the pending operation without treating diagnostics as stop proof. ## Linked Issues or Issue Description **What existing behavior does this improve?** The opt-in Sentry context for an unconfirmed adapter Stop timeout. **Current behavior** The timeout includes execution identity but no pending phase. A session close, instruction collection, workspace restore, or diagnostic write can remain pending without producing its completion timing. **Proposed behavior** Add a closed-list phase and elapsed milliseconds from the exact live execution control. Sample them when the timeout fires. Report `unknown` and a null age when the control or attribution is unavailable. **Reason and benefit** The next timeout can identify which operation is still pending. It does not require task text, paths, provider output, or additional database writes. **Breaking changes** No API or execution behavior change. The existing opt-in error context gains two fields. Related public work: #14639 added Stop identity diagnostics; #14866 and #14945 cover instruction cleanup and teardown outcomes. This change adds pending attribution to those paths. The native Stop work in #14802 remains separate. ## What Changed - Add a bounded tracker per execution control. Token scopes support nested and overlapping awaits. A late release cannot clear a newer scope. - Track adapter execution, ACP cancellation and settlement, diagnostic writes, and host cleanup. Keep a coarse host scope until the executor finishes. - Sample only the matching current control and settlement promise at timeout. Freeze the sanitized result. Use a monotonic clock and cap elapsed time at one day. - Test stalled operations, repeated Stop calls, stale and wrong-run controls, callback failures, scope bounds, and the real Sentry SDK context. ## Verification - `pnpm -r typecheck` passed. - `pnpm build` passed. - Six focused suites passed: 79 tests. They cover pending scopes, Stop control ownership, real ACP settlement stalls, and Sentry context isolation. - The real Sentry SDK contract ran with the audited optional peer `@sentry/node@10.71.0` installed outside the workspace. Valid phase and elapsed values were exported; arbitrary labels and nonfinite elapsed values were rejected. - An independent agent reviewed the production diff and ran the focused tests without blockers. - `git diff --check` and a redacted Gitleaks scan passed. The local full `pnpm test:run` was stopped during its large serial server batch to avoid duplicating the sharded CI suite. No complete local broad-suite pass is claimed. - All CI gates passed on `c223237b58aa8d479d1c66d7d399de30270bac4f`: 54 successful checks and two expected Storybook skips. This includes the full sharded test suite, typecheck, build, real Sentry SDK isolation, browser tests, canary dry run, and the security scan after the PR became ready for review. - Greptile scored the same commit 5/5 with no actionable findings or unresolved review threads. ## Risks This is diagnostic instrumentation. Cancellation, deadlines, teardown order, termination proof, and file recovery proof remain unchanged. Unsupported or uninstrumented work uses a coarse phase. Tracker overflow fails closed to `unknown`. The tracker emits no new run-log or Telemetry event. The existing Sentry opt-in gate remains in place. ## Model Used OpenAI Codex, GPT-6. The agent used code inspection, local command execution, automated tests, and an independent agent review. The runtime did not expose a more specific model identifier 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> |
||
|
|
862a5758ba |
fix(agents): reduce hiring templates to role descriptions (#14985)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - New agents receive role instructions from onboarding, the hiring skill, or a team package. > - These sources repeat harness procedures and impose generic work policies. > - They can crowd out the task and the harness instructions. > - This pull request reduces those sources to short role descriptions. > - It preserves configuration, skills, authentication, reporting lines, and approval controls. > - The benefit is less repeated instruction text with explicit coverage for the default hiring path. ## Linked Issues or Issue Description Refs #3307. The CEO template can impose a fixed delegation route instead of letting the agent choose how to fulfill the request. This change removes that route. It does not implement autonomous goal selection. Related work: #14920 preserves stock Codex base instructions. #14948 reduces the generic manual and shared runtime prompts. #14961 improves native completion-tool descriptions. This PR is separate from those changes. ## What Changed - Select only the short CEO `AGENTS.md` for new default CEO bundles. Keep the three former companion files as compatibility assets. - Reduce the first-agent chief-of-staff prompt and coder, QA, UX, and security role examples. - Reduce seven bundled team role bodies. Preserve their role, reporting, and skill metadata. Regenerate the catalog. - Make hiring examples optional. Replace the long generic role manual with short role drafting guidance. Preserve explicit requester instructions. - Add configuration and import coverage for native and legacy managed bundles, custom instructions, first-agent rendering, and catalog contents. - Add an explicit-only hiring eval that starts from the production CEO default and checks one coder hire, independently computed JSON output, saved instructions, and worker reuse. - Include the full prompt comparison and a separate three-request drafting simulation. Neither is a live provider comparison. Prompt differences: [before and after](doc/plans/2026-10-02-hiring-template-prompt-diff.md). The CEO default falls from 1,897 to 20 words. The coder example falls from 652 to 18 words. Word counts describe instruction size, not outcome quality or billing. ## Verification - PASS: 99 focused server tests and eight shipped-catalog tests. - PASS: catalog generation and validation for four shipped teams. - PASS: hiring skill validation. - PASS: `pnpm -r typecheck`. - PASS: `pnpm build`. - INCOMPLETE: the full local `pnpm test:run` was stopped before rebase. Its original log is retained. This is not a completed full-suite pass. The full current-head GitHub CI workflow passed: https://github.com/paperclipai/paperclip/actions/runs/37073372419. - PASS: `pnpm test:e2e:runner:typecheck` and `pnpm test:e2e:runner:unit` (63 files / 843 tests). - PASS: discovery for the two new hiring cells, 50 existing everyday cells, and the full 438-cell catalog. - PASS after rebase: 99 server tests, 11 catalog tests, 62 selected E2E support tests, and the E2E typecheck. - PASS: all current-head PR checks at `57dcee147ed0b2d2e3cc657cd9e50fb16bf9ec25`: 51 successful check runs, two intentional Storybook skips, and successful Snyk status. Fresh Greptile is 5/5 with zero unresolved threads. - PENDING follow-up: matched live hiring runs on frozen integration refs. No live outcome-quality or non-regression result is claimed from the configuration checks or this merge. The new suite has two local native cells: Codex and ACPX Claude. It expects five provider turns per cell. It compares source-derived bundles, so the historical long templates remain admissible. Missing successful source-read receipts make a pair uncomparable. They do not establish a behavior regression or equivalence. ## Risks - New default roles have fewer prescribed procedures. Live checks must determine whether a removed instruction was needed for an outcome. - Existing custom and saved bundles keep their contents. The retained companion assets avoid a source-file compatibility break. - Specialized Summarizer, Reflection Coach, and Wiki Maintainer prompts remain unchanged. Their product contracts need separate review. - The generic non-CEO fallback reduction is in #14948. This PR alone does not provide its eight-word fallback. - Configuration tests and drafting simulations do not establish live outcome quality. QA, UX, security, and chief-of-staff hiring behavior remain outside the new two-cell comparison. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI Codex, based on GPT-6, with reasoning, code editing, shell tools, and delegated verification. The runtime does not expose the exact deployment 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> |
||
|
|
22cea6b2e6 |
fix: bound sandbox bridge waits and flag silent runs sooner (#14979)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Sandbox agents exchange input and output through bridge control commands. > - A provider can stop responding to a command even when it receives a timeout. > - These small commands can inherit a four-hour agent lifetime and block input or teardown. > - The board also calls a silent run healthy for the first hour. > - This pull request bounds bridge control waits and surfaces silence sooner. ## Linked Issues or Issue Description **What happened?** A sandbox run can remain active when a bridge control command never returns. The shared helper passes a timeout to the provider but does not enforce it on the host. It also accepts the agent's hours-long timeout. Output silence remains `ok` for an hour and becomes `critical` only after four hours. **Expected behavior** Bound short bridge operations even if the provider never settles. Report failed input delivery through the existing shutdown path. Warn after five silent minutes and escalate after fifteen. Keep normal agent command limits and require verified termination before releasing execution ownership. **Steps to reproduce** 1. Use a sandbox runner whose bridge read or input-upload promise never settles. 2. Set its configured timeout to four hours. 3. Observe that the old queue client never returns or rejects. 4. Inspect a running task with 35 minutes of output silence. The old summary still reports `ok`. **Paperclip version or commit** Base commit `d6d88b9de2`. **Deployment mode** Self-hosted server with sandbox execution. **Agent adapter(s) involved** Shared command-managed sandbox bridge, including Codex ACP sessions. The informational silence thresholds apply to active runs across adapters. Related: #14889 recovers stalled Daytona output streams; #14485 retries explicit gateway failures during input delivery. This change bounds short control operations whose provider promises never settle. It does not add tool replay or automatic cancellation for output silence. #6297 proposes configurable per-agent silence thresholds; this patch only changes the existing defaults. ## What Changed - Enforce at most 30 seconds per bridge control shell command on the host and provider, including callback startup and shutdown, process-session launch, and payload setup. Preserve shorter configured deadlines and launch environments. - Keep the long-lived agent command outside this deadline. Use a fixed timeout diagnostic without command payloads. - Surface suspicious output silence after five minutes and critical silence after fifteen minutes. - Decouple the shared-workspace holder cutoff from warning thresholds and preserve its existing one-hour value. - Add regressions for hung reads, a late upload response, failed input delivery, exact warning boundaries, and fresh output clearing warnings. - Update the adapter guide and execution contract. ## Verification - The three new queue-client regressions fail on the unchanged base and pass with this patch. - Final callback bridge and sandbox session suites: 214 passed. These cover hung reads, writes, startup, shutdown, process-session launch, payload setup, and the separate long-running agent limit. - Stdin ordering and shutdown suite: 56 passed after the lifecycle change. - Daytona and watchdog coverage passed in the earlier focused runs. Across the focused suites, 602 distinct tests pass. - `pnpm -r typecheck` and `pnpm build`: passed. Server and adapter typecheck/build also passed after their respective follow-up changes. - `pnpm test:run`: attempted and stopped after known local failures. Four chat/email cases used an external ancestor skill path, three skill-cache cases failed on macOS, and one wakeup case timed out. The wakeup case passes alone (1 passed, 27 skipped). This run spanned the workspace-cutoff follow-up and also failed its new holder case; a fresh final-head workspace suite passes all 19 tests. The interrupted run is not a full local-suite pass or final-head verification. - A filesystem queue-drain test failed once during the lifecycle rerun and passed on the complete two-suite rerun. It uses the filesystem client, outside the changed command-runner path. - Complete CI on `ff2212c235`: 53 successful checks and two expected skips, including the full test suite and canary packaging dry run. No failed or pending checks. - Greptile reviewed `ff2212c235` at 5/5. All review findings are addressed, no threads remain unresolved, and the branch has no merge conflicts with `master`. - `git diff --check` and a scan of added text for secrets and private identifiers passed. ## Risks - A bridge control operation that needs more than 30 seconds now fails, even if the caller selected a longer run lifetime. Agent commands retain their own limits. - Timing out a provider promise does not cancel the remote operation or prove it stopped. Existing execution settlement still owns termination verification. No uncertain tool action is replayed. - Quiet healthy runs display warnings sooner. Existing snooze, continue, and false-positive dismissal controls still apply. Silence alone does not cancel a run, create review work, or change assignments. - No schema or API shape change. ## Model Used OpenAI GPT-6 through Codex, with tool use and code 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 (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run change-specific 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> |
||
|
|
5b8b2b38ca |
feat(apps): add Neon connection (#14980)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agents reach external services through the Apps catalog. Each catalog entry is a reviewed `AppDefinition` that wires a provider's hosted MCP server into Paperclip's shared vault, grants, policies, gateway, and audit trail. > - Neon is a widely used serverless Postgres provider with an official hosted MCP server, but it is not in the catalog. Teams that run their databases on Neon must use the generic "connect your own MCP server" path, which has no branding, no guidance, and no project or read-only controls. > - The connector playbook requires a catalog entry for a provider like this: the hosted server supports dynamic client registration and bearer API keys, and the common definition fields can express every option Paperclip can serialize. > - This pull request adds the Neon definition, its official artwork, the research and permission-review ledger rows, documentation, and deterministic tests, without any provider-specific runtime code. > - The benefit is a one-click, governed Neon connection with optional project pinning and read-only mode, and a documented path to live qualification. ## Linked Issues or Issue Description **Problem or motivation** Neon is a common Postgres host for the applications agents work on, but Paperclip's Apps catalog has no Neon entry. Operators who want agents to inspect schemas, run SQL, or manage branches must paste the MCP URL into the generic remote-MCP flow, which gives no branding, no provider guidance, no project boundary, and no read-only switch. **Proposed solution** Add a catalog-only Neon connection built from the connector playbook: browser sign-in through Neon's dynamic client registration with the reviewed `read` and `write` scopes, or a customer API key sent as an Authorization bearer header. Both methods expose Neon's documented `projectId` pin and `readonly` switch as optional Advanced fields. Every discovered tool stays governed by the normal per-action policies. **Alternatives considered** A plugin was not needed because no custom UI, tables, workers, or webhooks are involved. A separate read-only method was not added because the playbook treats read-only switches as advanced fields rather than methods. Neon's repeatable `category` query filter was left out because tenant fields serialize lists as one comma-joined value, so it cannot be sent correctly without new runtime code; per-action policies cover catalog narrowing instead. **Roadmap alignment** This extends the existing self-serve remote-MCP connection catalog and does not overlap planned core work. ## What Changed - Added the `neon` provider to `scripts/ingest-app-definitions.mjs` (category, API-key placement, methods, tenant fields, guidance, warnings) and regenerated `packages/shared/src/app-definitions/neon.json` plus the generated registry. - Added the Neon row to the self-serve MCP research ledger with `dcr_or_api_key` auth and risk tier S4. - Added permission reviews for `neon/mcp-oauth` (explicit scopes `read`, `write`, taken from Neon's live authorization-server metadata) and `neon/mcp-api-key` (provider key), with evidence links. - Added Neon's official tile icon (`ui/public/brands/apps/neon.png`, copied byte-for-byte from the icon linked by neon.com) and the brand manifest entry. - Added prosumer gallery copy for the Neon card. - Added `doc/connections/NEON.md` (service involvement, endpoints, administrator setup, capabilities and policy, manifest, brand provenance, validation hook) and linked it from the connections README and the permission audit. - Tests: Neon definition shape, store visibility and artwork, URL recognition, reviewed scopes with scope-widening rejection, URL projection of the project pin and read-only flag, invalid project ID rejection, the connect form's API-key gating, and the pinned catalog counts. ## Verification - `pnpm exec vitest run packages/shared/src/app-definitions.test.ts packages/shared/src/app-definitions-url.test.ts` — 34 passed. - `pnpm exec vitest run server/src/__tests__/tool-access-service.test.ts` — 367 passed. - `pnpm exec vitest run ui/src/pages/apps/AppsConnect.test.tsx ui/src/pages/apps/Browse.test.tsx ui/src/lib/app-brand-assets.test.ts ui/src/pages/apps/AppLogo.brand-assets.test.tsx` — all passed. - `node scripts/check-app-brand-assets.mjs` and `node --test scripts/app-brand-validation.test.mjs` — passed. - `pnpm --filter @paperclipai/shared typecheck`, `pnpm --filter @paperclipai/server typecheck`, `pnpm --filter @paperclipai/ui typecheck`, `pnpm check:token-gates` — clean. - Manual: in a local instance, open Apps → Browse, confirm the Neon card and icon, open `/apps/connect?source=neon`, confirm both methods, the Advanced project pin and read-only toggle, and that Connect enables after an API key is entered. The operator completed a live connection against a Neon account on this build. - Live metadata probed on 2026-10-02: both `.well-known` documents at `mcp.neon.tech` return the recorded endpoints and scopes; an unauthenticated `initialize` returns 401 with `resource_metadata`. ## Risks - Low risk to existing providers: the change is additive catalog data plus tests. The generated registry only gains one import. - Neon's hosted server grants broad project and database management. The definition carries two warnings, recommends a development project, and keeps every write under the normal action policies; the read-only switch is enforced by Neon's server, not locally. - The permission-review ledger records live proof for both methods as not run; the full lifecycle checklist in `doc/connections/NEON.md` still needs a documented pass before the entry is considered fully qualified. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used - Claude Fable 5.1 (`claude-fable-5-1`) in Claude Code, with extended thinking and tool use (shell, file editing, browser verification). ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
d6d88b9de2 |
fix: preserve run outcomes when agent file cleanup is deferred (#14945)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The heartbeat service records each agent turn and releases its working files. > - A turn can save its work and finish before instruction-copy cleanup runs. > - A cleanup exception can replace that completed result with an adapter failure. > - This also loses result accounting and can prevent environment lease release. > - This pull request records a cleanup warning and keeps the original run outcome. > - The existing recovery sweep retries cleanup from the durable working-copy record. ## Linked Issues or Issue Description Related cleanup and lock work: #14866 and #14869. Related, distinct work: #14695 retains warm-process files; #12021 handles provider-process SIGTERM after a terminal result. **What happened?** An agent saved its plan, posted a comment, and requested approval. The provider completed its turn. Instruction-copy cleanup then timed out on a directory lock. Its exception escaped a `finally` block and replaced the provider result, so the completed turn showed `Run failed`. **Expected behavior** Keep the provider outcome, usage, cost, saved work, and pending approval. Record a cleanup warning and let the existing recovery sweep retry. A real provider failure must keep its original error. A failed file save must keep its failed-save receipt. **Steps to reproduce** 1. Complete a legacy adapter turn that saves work and requests approval. 2. Make instruction-copy release throw a directory-lock timeout. 3. Read the run result. Before this change, the cleanup error replaces the provider outcome. The new heartbeat tests reproduce the failure without a live provider or external service. **Paperclip version or commit** The regression reproduces on `c83df091b1a5207375eaf23466bb5c62e4e1518e`. This branch is rebased onto `cf8ad63c80`. **Deployment mode** Server-managed agent execution with persistent instruction working copies. ## What Changed - Catch instruction-copy release failures in both heartbeat teardown paths. Stop repeating a failed cleanup attempt within the same run. - Write a sanitized `instruction_cleanup` warning. A warning-write failure also preserves the run result. - Test successful, failed, and throwing providers; both teardown paths; warning-write failure; accounting; approval state; and execution-control release. - Extend the held-lock test to prove a fresh recovery worker removes the deferred copy and preserves its failed-save receipt. - Document deferred cleanup and the run-log event. ## Verification - Red proof: all five new heartbeat regression cases fail with the original release calls. - At head `20bea4f431c916d2f5db1970213aab85f5daa34c`, all 417 tests passed across heartbeat process recovery, agent directory working copies, and directory merge locks. - Full local `pnpm -r typecheck`, `pnpm build`, and `git diff --check` passed. - [GitHub CI](https://github.com/paperclipai/paperclip/actions/runs/37031119795) passed at this head. All 53 reported checks passed; the two Storybook checks were correctly skipped. This includes general and serialized tests, browser shards, runner verification, build, typecheck, and the canary dry run. - Greptile reviewed this head with 5/5, no code comments, and no unresolved review threads. The branch has no merge conflicts. - The local `pnpm test:run` attempt was stopped after it reported eight failures in unchanged suites. Four Slack/AgentMail cases selected an unrelated ancestor skills directory and failed with `ENOENT`; the two Slack cases passed with a temporary local skill-root link, which was then removed. Three company-skill cases reproduced macOS `EACCES` errors when renaming read-only cache directories. One gateway case passed when rerun alone. No full local-suite pass is claimed; the complete CI test jobs passed. ## Risks - Cleanup errors now leave recovery work pending. The durable working-copy record remains available for the existing retry sweep. - This change preserves provider failures and failed-save receipts. It does not claim that unsaved file edits were saved. - Native instruction reservation errors retain their existing behavior because they guard process ownership. - No schema, lockfile, workflow, API, or UI changes. ## Model Used OpenAI Codex, based on GPT-6, with reasoning, repository tools, and code execution. The exact backend model 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 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> |
||
|
|
92ad158ce1 |
fix(claude-local): order Claude models the way the Claude app does (#14917)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Each agent runs on an adapter, and the operator picks the agent's model from a list the adapter advertises. > - The `claude_local` adapter advertises a static list and merges in the models the Anthropic API returns. Neither list has a deliberate order. > - The model dropdown then sorts every list by id. For Claude this shows "Fable 5", "Fable 5.1", "Haiku 4.5", "Mythos 5", "Opus 4.6" ... which is not the order of capability, release, or version (#14877). > - This pull request gives the adapter one defined order, the one the Claude app uses: the newest release of each family first, by decreasing capability, then older releases grouped by family. The server applies it to discovered models, and the dropdown keeps the adapter's order instead of re-sorting. > - The benefit is that a user who knows the Claude app finds the right model at once, and older models sit at the end of the list. ## Linked Issues or Issue Description Fixes #14877. Related: #14147 touches the same adapter's model list (the `ANTHROPIC_MODEL` default label) and does not change ordering. #14878 is the Codex counterpart and depends on the dropdown change in this PR. ## What Changed - `packages/adapters/claude-local/src/server/model-order.ts` (new): `sortClaudeModels()` and `parseClaudeModelId()`. The parser reads the current scheme (`claude-opus-4-8`), the legacy scheme (`claude-3-7-sonnet-20250219`), dated snapshots, `-latest` aliases, the `[1m]` suffix, and Bedrock ids (`us.anthropic.…-v1`, `…-v2:0`). The sort puts the newest release of each family first (Fable, Mythos, Opus, Sonnet, Haiku), then older releases grouped by family with versions descending. An alias sorts before its dated snapshots, and dated snapshots of one release sort newest first. Ids that are not Claude models keep their incoming order at the end. - `packages/adapters/claude-local/src/server/models.ts`: apply the order to the static fallback, to the merged API list, and to the Bedrock list. Reorder `BEDROCK_MODELS` to match. - `packages/adapters/claude-local/src/index.ts`: reorder the advertised `models` list to the same order. - `ui/src/components/AgentConfigForm.tsx`: `ModelDropdown` gets a `preserveOrder` prop. With it the dropdown shows the list as the adapter ordered it; without it the list is sorted by id as before. `ui/src/lib/model-utils.ts` adds `adapterCuratesModelOrder()`, true for the built-in adapters whose list arrives in a deliberate order (`claude_local`, `codex_local`, `paperclip_runner`, `gemini_local`, `grok_local`, `kimi_local`, `openclaw_gateway`, and `opencode_local` / `pi_local`, which the server sorts when discovered and which lead with the default model when it falls back to the declared list). Cursor is not in the set because its list comes from `agent models` discovery, and adapters not named there, including externally installed ones, keep the alphabetical fallback. The three dropdown call sites (`AgentConfigForm`, `ConfigureBuiltInAgentModal`, `NewAgentSetup`) pass it; `NewAgentSetup` decides by the resolved brand type, because a `paperclip_runner` agent fetches the Claude or Codex list for its brand. Grouped lists (`opencode_local`, `pi_local`) are unchanged. - Tests: `model-order.test.ts` (adapter, including the snapshot-date tie-breaker), `ModelDropdown.test.tsx` (ui: preserved order with the prop, alphabetical without it, provider groups unchanged), `model-utils.test.ts` (which adapters opt in), and two updated expectations plus one new order assertion in `server/src/__tests__/adapter-models.test.ts`. Mythos is not in the Claude app's list. This PR ranks it directly after Fable, in the top capability tier. The rank table in `model-order.ts` is one line to change if you prefer a different slot. ## Verification Run from the repository root: ```sh pnpm exec vitest run packages/adapters/claude-local server/src/__tests__/adapter-models.test.ts ui/src/lib/model-utils.test.ts ui/src/components/ModelDropdown.test.tsx ui/src/components/AgentConfigForm.render.test.tsx ui/src/components/ConfigureBuiltInAgentModal.test.tsx ui/src/pages/NewAgent.test.tsx pnpm --filter @paperclipai/adapter-claude-local typecheck pnpm --filter @paperclipai/ui typecheck pnpm --filter @paperclipai/server typecheck pnpm check:module-boundaries && pnpm check:token-gates && pnpm check:tokens ``` Red on `master`, green here: - `ModelDropdown.test.tsx` fails against the unmodified dropdown because the ids come back sorted alphabetically even with `preserveOrder`. - `adapter-models.test.ts` fails against the unmodified adapter because the first model is `claude-opus-4-8`, not `claude-fable-5-1`. Manual check: open an agent that uses `claude_local`, open the model dropdown. With no `ANTHROPIC_API_KEY` the list reads Fable 5.1, Mythos 5, Opus 5.5, Sonnet 5, Haiku 4.5, Fable 5, Opus 5, Opus 4.8, Opus 4.7, Opus 4.6, Sonnet 4.6, Sonnet 4.5. With a key, the discovered models slot into the same order. ## Risks - The other built-in adapters in the set (Gemini with `Auto` first, Grok, Kimi, OpenClaw, the runner's Codex list, and the OpenCode and Pi lists in the built-in-agent modal) are now shown as their adapter delivers them instead of alphabetized. Cursor's discovered list and every adapter outside the set, including externally installed ones, keep the alphabetical order they had, so no option moves between refreshes. Grouped lists are unchanged. - The first entry of the Claude list changes from Opus 4.8 to Fable 5.1. Nothing reads the first entry as a default: `DEFAULT_CLAUDE_LOCAL_MODEL` is `claude-opus-5` and is resolved separately. - No API, schema, or migration change. ## Model Used Anthropic Claude Fable 5.1 (`claude-fable-5-1`) through Claude Code, extended thinking on, with tool use for reading the repository, running vitest and tsc, and editing files. The account holder reviewed the change and owns the commit. ## 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: abderbj <115119179+abderbj@users.noreply.github.com> |
||
|
|
2ec82c5774 |
fix(runner): preserve task context when tool connections change (#14963)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agents use tools through company-scoped connections and provider sessions. > - Resolving a tool connection currently forces a fresh session even when the provider can load new tools into the existing conversation. > - A fresh provider conversation can receive too little history to continue the task. > - This pull request adds explicit tool-refresh capabilities and uses them in both runner paths. > - Fresh attempts receive bounded task history with source IDs and retrieval instructions. > - The benefit is that agents can continue the same task after a connection changes. ## Linked Issues or Issue Description **What happened?** A resolved tool connection forced a fresh provider conversation. The new conversation could lose the original goal and prior answers. Claude also rejected resume when only the MCP server set changed. **Expected behavior** Resume the provider conversation when its harness can refresh tools. When a fresh session is required, supply enough bounded history to continue the task. Preserve company, agent, task, workspace, model, instruction, and skill checks. **Steps to reproduce** 1. Start a conversation and agree on a task and its constraints. 2. Request and connect a tool needed for the task. 3. Continue the conversation after the connection resolves. 4. Check that the agent remembers the task and can use the new tool. **Paperclip version or commit** The bug was reproduced on master at `c46e41e81`. This branch is rebased on current master. **Deployment mode** Self-hosted server. Both legacy adapters and the native runner are affected. Related public work: Refs #13282 for task-backed conversations. Refs #13057 for the broader session-compaction proposal. Refs #14659 for another report about local CLI session continuity. This change fixes tool-connection continuation. Provider authentication repairs keep their existing recovery behavior. ## What Changed - Expose tool-refresh support in native harness descriptors and legacy adapter metadata. - Request tool refresh after connection resolution. Keep provider authentication repair as a fresh-session wake. - Reload current tools and credentials while retaining supported Claude, Codex, Grok, and other provider conversations. - Allow MCP-only changes during qualified native recovery. Keep all other compatibility checks. - Refresh managed-provider and ACPX tool bindings when attaching a new run. - Add a fresh-session handoff for both runner paths. Bound database reads, excerpts, and the final packet to 24,000 bytes. - Include the original request, recent messages, decisions, plans, prior answers, and source IDs. Mark omitted content. Apply reset boundaries, wake cutoffs, quarantine, and secret redaction. - Add regression tests and document the capabilities and handoff behavior. ## Verification - `pnpm -r typecheck` and `pnpm build` passed. Rust formatting passed. - Final review fixes passed 314 server tests, 333 adapter utility tests, 139 native-session runtime tests, and 12 managed-provider Rust tests. They verify historical quarantine, raised budgets across attachment, no history reads on successful resume, and handoff delivery on fresh retry. - Broader branch verification also passed 1,401 adapter utility tests, 1,047 runner TypeScript tests, 43 Grok adapter tests, and 311 Rust core tests. - Live Claude CLI and Grok ACP probes preserved the provider session ID, recalled a prior task constraint, and called a newly added read-only MCP tool. - GitHub CI passed on `b21486d18084a7aa4cafbe8e012f7cad6585d9cc`: 55 successful checks and 4 skipped checks. This includes all test shards, all eight browser shards, runner checks, and the Grok clean public npm install canary. [CI run](https://github.com/paperclipai/paperclip/actions/runs/37057514976). - A full local test attempt encountered a separate Git snapshot timeout. All affected local suites passed after the final edits, and the full CI test gates passed. - Review the capability matrix in `packages/paperclip-runner/README.md`. Repeat the four reproduction steps with a supported provider and with an unsupported harness. ## Risks - Provider tool refresh can fail. Existing recovery falls back to a fresh conversation where policy permits it. - A new transport can replace an old process while preserving the provider conversation. Tests cover current credentials and unchanged identity. - Long history can omit older context. Explicit markers and source IDs let the agent retrieve needed context within task scope. - Unknown and unqualified harnesses use the fresh-session path. No database migration is required. ## Model Used OpenAI Codex, GPT-6, with reasoning, tool use, code execution, and live provider testing. The exact model ID and context-window size are not exposed in this session. Claude and Grok also ran as test subjects. ## 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> |
||
|
|
144083fd48 |
fix(interactions): wait for workspace readiness before enabling approval (#14893)
## Thinking Path > - Paperclip lets people manage AI agents and review their work. > - Task confirmations must use the work produced by their source run. > - The server blocks approval while that run still needs to sync its workspace. > - The card currently enables approval before that check can pass, so an ordinary click produces an error. > - This PR exposes the existing readiness check and shows “Preparing approval…” with acceptance disabled. > - The card refreshes itself and enables approval when the source workspace settles. ## Linked Issues or Issue Description **What happened?** A confirmation appears while its source run is still preparing or syncing its workspace. Its enabled approval button returns a conflict asking the user to retry after syncing. **Steps to reproduce** 1. Run an agent in an isolated workspace. 2. Have it create a confirmation before workspace finalization completes. 3. Click the approval button while the source workspace is still active. **Expected behavior** The card explains that approval is preparing. Acceptance becomes available automatically when the same server check permits it. Reject and revise remain available. Related work: #10770 handles this conflict after a click with retries. #9520 proposes changing the workspace acceptance barrier. This PR preserves that barrier and exposes readiness before the click, including in compact task chat. It preserves the terminal-finalize behavior from #10099. ## What Changed - Add an optional, read-only `acceptanceBlocker` to interaction responses. Readiness uses the existing source-run workspace predicate, with one check per pending source run. - Disable acceptance and show a shared preparation notice in classic and compact confirmation cards, including checkbox and secret-binding confirmations. - Refresh preparing cards every two seconds in task detail, attention, pipelines, and Skill Studio. Restore each surface's previous polling cadence when preparation clears. - Preserve live tool reviews, questions, rejection, revision, and the server acceptance barrier. No automatic acceptance occurs. - Document the preparation state and cover readiness, terminal sync outcomes, unrelated runs, historical cards, and automatic refresh. ## Verification - Focused service, card, query-refresh, and helper tests: 217 passed across five files. - `pnpm -r typecheck`: passed. - `pnpm build`: passed. - `pnpm build-storybook`: passed. - `pnpm check:token-gates`: passed. - `pnpm test:run`: incomplete locally. Stopped after about 17 minutes once it reproduced seven existing environment failures: two Slack tests and two email tests lack ancestor-directory skill fixtures; three company-skills tests fail on macOS runtime-cache staging permissions. These are outside this change. The full CI test matrix passed. - CI: all 53 checks passed; two optional Storybook jobs were skipped. The branch has no conflicts with `master`. - Greptile: 5/5 on commit `8a6f216d8d`, with no review threads. - Reviewed added lines and new files for credentials, private URLs, internal task references, user paths, and run artifacts. None found. ## Risks - No database migration or change to acceptance authorization. Readiness is advisory; the server still enforces its existing gate at acceptance. - An open preparing card adds a read every two seconds. This cadence stops after readiness clears; historical cards add no workspace checks. - Failed or stale finalization retains the existing server behavior. This PR does not change recovery policy. ## Model Used OpenAI GPT-6 through Codex. The exact serving model ID and context-window size are not exposed in this session. Used reasoning, repository inspection, tool execution, and automated tests. No sub-agents. ## 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 (217 focused tests; full local-suite limitations are 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> |
||
|
|
d034ba7491 |
fix(interactions): derive question storage from canonical forms (#14946)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agents request human input through durable issue interactions. > - A question form has a canonical presentation and a compatibility storage format. > - The creation API required agents to write both formats. > - Tool guidance told agents to split text and choice questions across those formats. > - This pull request accepts one complete canonical form and derives storage fields on the server. > - The benefit is a complete question card with stable answer and retry behavior. ## Linked Issues or Issue Description Related work: Refs #13630 and #14430. PR #13630 addresses the display of historical partial forms. This change fixes creation and keeps the check that rejects conflicting new forms. **What happened?** A question save supplied three compatibility questions and one canonical text question. The API correctly rejected the incomplete canonical form. The Runner's tool description encouraged this split. Sending only a complete canonical form also failed because the API required compatibility questions. **Expected behavior** An agent sends one complete `payload.questionSet` with every text and choice question. Paperclip derives `payload.questions` for storage and answer compatibility. Existing legacy requests remain valid. Explicitly conflicting dual forms remain invalid. **Steps to reproduce** 1. Call `paperclip_request_human_input` with `interactionKind: "questions"`. 2. Send `payload: { version: 1, questionSet: ... }` with a required text question and a required choice question. 3. The old API rejects the missing compatibility questions. With this change, it stores both questions and preserves the canonical form. 4. Retry with the same idempotency key. Confirm that only one interaction exists. 5. Submit both answers. Confirm that the normal resolver and continuation rules apply. **Paperclip version or commit** The branch is based on `cf8ad63c8`. The problem affects the native Runner and the interaction creation API. **Deployment mode** Server deployment with the native Paperclip Runner. Integration tests use the real interaction service and an embedded test database. ## What Changed - Add one shared canonical-to-storage projection. Reuse it for native harness question requests. - Accept canonical-only question creation at the shared validator and server boundary. - Export the input type and update the plugin SDK and its RPC contract. - Advertise a typed, complete question form in the live and scenario tool schemas. - Enforce canonical text and custom-answer constraints before ordinary or native resolution. Preserve harmless display whitespace. - Run regex matching in isolated workers with a deadline and resource limits. Both answer paths await the result before persistence. Saved native delivery uses the validated answer without taking another worker slot. - Update agent guidance and generated Runner contracts. - Test mixed forms, option-ID collisions, retries, answers, legacy requests, and conflicting forms. ## Verification - Interaction service, HTTP route, native bridge, and Runner authority suites: 221 tests passed after correcting an obsolete tool-description assertion. - Shared validator, plugin SDK, CLI, and UI compatibility suites: 67 tests passed. - Runner core tool-contract suite: 20 tests passed. AJV validates live and scenario schemas. - Final review regressions: 172 shared, service, native bridge, and authority tests passed. These cover text length, pattern, numeric limits, whitespace, custom option IDs, and historical pending cards. - Runner session suites: 67 tests passed. Published example tests: 4 tests passed. - Server typecheck and the shared/server builds passed after the compatibility fixes. - Final delivery verification: 35 response-delivery tests passed. The native delivery regression proves saved answers do not enter pattern workers; server typecheck and build passed. - Pattern security and answer-flow verification: 205 tests passed after repairing the child fixture loader. These cover pathological matching, event-loop responsiveness, worker concurrency, slot cleanup, HTTP routes, native delivery, and the full helper in a child process. - `pnpm -r typecheck` passed on the bounded-worker revision. - `pnpm build` passed on the bounded-worker revision. - All 55 GitHub checks passed on `fe457af`; four optional jobs were skipped. An unchanged Cursor adapter test timed out once in CI, passed locally, and passed on one failed-job rerun. - Reviewers can send the canonical-only mixed form above and verify that the saved interaction contains both canonical and compatibility questions. ## Risks - The creation API accepts a new input shape. Stored rows and answer contracts keep the existing shape. - The shared projection must preserve synthetic free-text option IDs. Collision and native round-trip tests cover this behavior. - Historical partial rows remain readable. New conflicting dual forms, including written-answer mismatches, remain rejected. - Existing pending cards retain the written-answer paths offered by their stored options. Canonical text constraints still apply. - Ordinary answers now enforce declared canonical constraints before persistence. Invalid answers leave the card pending. - Regex validation has a one-second deadline and a four-worker capacity limit. A complex pattern or capacity error leaves the card pending with a validation error. - No database migration or change to company authorization is required. ## Model Used - OpenAI GPT-6 through Codex. The session exposes the GPT-6 model family; its exact runtime model identifier and context window size are not exposed. Used reasoning, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
9786f6df56 |
fix(runner): preserve credential content in document saves (#14937)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The Runner sends authorized tool calls to the control plane. > - Agents use these calls to save plans and instruction files. > - The Runner used diagnostic secret detection to reject execution arguments. > - Ordinary credential-related prose could reject a document save before persistence. > - This pull request forwards the original arguments and leaves credential policy to the provider harness. > - The benefit is reliable saves with useful diagnostic records. ## Linked Issues or Issue Description Related foundation: Refs #12415 and #14430. No duplicate save-policy fix was found. **What happened?** A `write_document` call failed before the server saved its plan. The Runner reported `semantic tool input contains credential material; refusing to execute altered arguments`. The detector also masked ordinary phrases such as `secret manager` and `credential handling` in diagnostics. Both TypeScript dispatchers had equivalent execution gates. One dispatcher also rewrote structured approval and question payloads before execution. **Expected behavior** Paperclip forwards authorized arguments unchanged. The provider harness decides credential-content policy. Log and audit redaction does not reject or rewrite save input. **Steps to reproduce** 1. Send an authorized `write_document` call with a plan that discusses credential handling. 2. Include an intentional credential value in the body to exercise harness-owned policy. 3. The old Runner rejects the call. With this change, the document service stores the exact body. 4. Diagnostic records still mask explicit credential values. Qualified credential fields, short bearer values, opaque diagnostic pairs, and valid encoded JSON token headers have regression coverage. **Paperclip version or commit** Reproduced at `c46e41e81c03cd3c8b64cf993615b604d7fe8c62`. The branch is based on current `master`. **Deployment mode** Server deployment with the native Paperclip Runner. Local regression tests use the real document service and an embedded test database. ## What Changed - Remove credential-content vetoes from Rust admission and both TypeScript semantic dispatchers. - Preserve original structured approval and question arguments during execution. - Keep transport bounds, schema checks, authorization, idempotency, and audit masking. - Require explicit credential syntax or recognized formats for diagnostic masking. Preserve ordinary prose, metadata, and dotted identifiers. - Test exact document persistence, replay, nested argument identities, and masked audit copies. - Remove obsolete retry guidance and document harness-owned credential policy. ## Verification - `cargo test --manifest-path packages/paperclip-runner/runner/Cargo.toml --locked -p paperclip-runner-core --lib --test acpx_event_payload --test acpx_provider_state --test acpx_provider_turns`: 355 tests passed. - Focused server and adapter tests: 189 tests passed after rebase. These include the real document save and the complete tool-gateway suite. - Semantic dispatcher and conformance tests: 34 tests passed. - Diagnostic redaction and MCP tests: 46 tests passed, including all six review examples. - `pnpm -r typecheck` and `pnpm build` passed on the repaired branch. - The broad local root suite was interrupted after database fixture setup failures. The focused database suites passed. CI runs the complete configured test lanes. ## Risks - Authorized tool arguments can intentionally contain credentials. The harness must enforce its content policy. - Diagnostic detection is narrower. Explicit assignments, credential fields, and recognized credential formats remain masked. - The change does not add a database migration or change company authorization. ## Model Used - OpenAI GPT-6 through Codex. The session exposes the GPT-6 model family; its exact runtime model identifier and context window size are not exposed. Used reasoning, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
839cac1343 |
fix: request supported offline access for generic MCP OAuth (#14950)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agents use external MCP tools through the governed gateway. > - Remote MCP connections can use OAuth access tokens that expire. > - Some providers issue refresh tokens only after an offline-access request and consent. > - Resource scopes hid that identity-provider capability in the generic connection flow. > - This pull request requests supported offline access and tests expiry through a local MCP server. > - The benefit is continued tool access without another sign-in when the provider permits refresh. ## Linked Issues or Issue Description Related PR: #13447 addresses the same OAuth symptom together with managed Codex configuration. This PR focuses on generic MCP OAuth. It also covers consent, explicit scope overrides, legacy reconnects, exact scope persistence, and real HTTP expiry tests. **What happened?** A generic MCP resource can advertise only its tool scopes. Its OAuth server can separately advertise `offline_access`. Paperclip selected the resource scopes and omitted the offline-access request. A provider could then issue an access token without a refresh token. Tool access stopped after the access token expired. **Expected behavior** Paperclip adds advertised offline access to the selected tool scopes when the OAuth server does not exclude refresh tokens. It requests consent and stores the scopes sent in the authorization request. Existing connections can discover this capability when the user reconnects. Providers without this capability keep their existing scope behavior. **Steps to reproduce** 1. Run `node scripts/mcp-fixtures/servers/oauth-refresh-fixture.mjs` from the repository root. 2. Add its MCP URL as a generic connection on a local Paperclip instance. 3. Approve the test consent page and call `read_status`. 4. Let the two-minute access token expire and call the tool again. 5. Before this fix, the connection needs another sign-in. With this fix, the call refreshes the token and succeeds. **Paperclip version or commit** The integration regression reproduced the missing-refresh-token failure on the parent of this PR's fix. The same test passes with the fix. **Deployment mode** Local development. Automated tests use a loopback HTTP MCP/OAuth server and a disposable PostgreSQL database. ## What Changed - Track offline-access capability separately from MCP tool scopes. - Add supported offline access and consent for generic connections. - Preserve the actual requested scopes through callback completion and reconnect. - Discover the capability for older connections with cached OAuth endpoints. - Add a reusable MCP/OAuth fixture with PKCE, token expiry, resource binding, and refresh-token rotation. - Test shared and personal gateway calls through two refresh rotations. Cover scope selection, unsupported refresh, and legacy reconnects. - Document the behavior and local test commands. ## Verification - The two real HTTP expiry tests failed before the fix with `oauth_refresh_missing` after the first token expired. - Tests passed on the current head: 76 generic MCP regressions, all 365 tool-access service tests, and 4 fixture controls. - Full workspace `pnpm -r typecheck` and `pnpm build` passed. Server TypeScript checks also passed after the review fixes. - All remote checks passed on `d22909bb34e9d54478c0002077c498ffe105932d`. Greptile gave 5/5 with both previous findings resolved. The complete local `pnpm test:run` is still running. - Run `node --test scripts/mcp-fixtures/servers/oauth-refresh-fixture.test.mjs` for the standalone provider controls. - Run `pnpm exec vitest run server/src/__tests__/generic-mcp-connection.test.ts` for the Paperclip integration tests. ## Risks - Users can see a consent prompt when a generic provider supports offline access. - The provider can still decline to issue a refresh token. Access works until expiry, then the user must reconnect. - A provider that advertises offline access but rejects the scope produces an OAuth error. This PR does not add an automatic retry without that scope. - Existing grants without refresh tokens need another sign-in. The fix does not change them in place. - Curated Apps keep their reviewed scope and authorization-parameter allowlists. No database migration is required. - This simulation verifies the suspected failure. The reported internal MCP server has not been tested. ## Model Used - OpenAI Codex, based on GPT-6, with reasoning, tool use, and code execution. The runtime did 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> |
||
|
|
7a52dcdc74 |
fix: repair MCP validation and cancelled execution recovery (#14951)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The tool gateway gives agents access to connected services. Recovery controls what happens when a run stops. > - Generated tool names can exceed the provider limit after the MCP client adds its prefix. > - The same invalid definition can fail each automatic retry. A cancelled run can also hold saved messages without showing its cause. > - This pull request bounds tool names, stops configuration retries, and retains cancellation evidence. > - It shows the stopped run and admits saved input only after the existing safety checks pass. > - The benefit is a clear recovery path that preserves operator Stop and prevents duplicate message delivery. ## Linked Issues or Issue Description **What happened?** A long connected MCP tool name makes the provider reject the entire request. Automatic recovery repeats the invalid request. Separately, unexpected legacy cancellations can leave saved input behind a recovery hold. The notice does not identify the stopped run or its cause. **Expected behavior** Complete MCP names fit the provider limit. Tool-definition errors require configuration repair. Cancelled runs retain their source and reason. The recovery notice shows the cause and saved-message count. Verified unexpected cancellations can start a fresh turn through the existing admission checks. **Steps to reproduce** 1. Assign an App gallery connection with a long application key and tool name to a Claude agent. 2. Start a run. The provider rejects a name over 128 characters, including its MCP prefix. 3. For cancellation recovery, stop a legacy provider turn without an operator Stop request and send a user message while the recovery hold is active. 4. Inspect the recovery notice and the deferred message queue. **Paperclip version or commit** Rebased onto master at `cf8ad63c806685bfd7c48e3ed4a919d61a7c55f1`. **Deployment mode** Hosted or self-hosted server with legacy Claude or Codex execution. Related public work: - Refs #14017. That PR caps name segments. This PR preserves existing short names and uses stable hash aliases for long complete names. It also covers classification and recovery. - Refs #4510. That PR adds a cancellation-source column. This PR records bounded evidence in the existing run result, without a migration. - Refs #12552 and #4506. Those PRs suppress recovery after operator cancellation. This PR preserves operator intent and uses the existing continuation gates. ## What Changed - Bound gateway names with the full provider prefix in the 128-character budget. Retain the original upstream tool name for dispatch and permissions. - Classify invalid tool definitions as configuration failures before diagnostic redaction. Stop automatic retries and continuation attempts for that error code. - Persist cancellation source, expectedness, initiator, reason, and time. Preserve recorded Stop intent when adapter results arrive. Report unexpected started cancellations with closed diagnostic labels. - Show the run cause, saved-message count, and Inspect run link. Offer Continue for eligible unexpected cancellations. Require verified provider stop, empty tool inventory, ownership, and the existing pause, budget, approval, and dependency gates. Use the existing queue for single delivery. - Add regression coverage and update the execution, MCP gateway, and run-log documentation. ## Verification - `pnpm -r typecheck` and `pnpm build` passed. - `pnpm check:token-gates` passed. - Ran `pnpm test:run` and completed its workspace and serialized groups. Initial resource and timing failures passed on isolated reruns. All 149 serialized route suites passed. - Reran the changed server, adapter, and UI suites after the rebase. Coverage includes long-name upstream dispatch, configuration retry suppression, cancellation evidence retention, privacy labels, oversized run projection, and concurrent saved-message delivery. - `pnpm test:e2e tests/e2e/legacy-failure-continuation.spec.ts` passed all six browser scenarios. The recovery notice shows the run cause and inspection link, and each recovery entry point reaches one new response. - Added database-backed checks for active, removed, paused, unavailable, and disabled chat connections. The final continuation and recovery-notice suites passed 167 tests. Externally bound chats hide board Continue and show a usable next action. - All 55 GitHub checks passed on `42afbf1371dcaeb72646e3d8f65c19ff7cddf8de`. Two unrelated Storybook jobs were skipped by their normal conditions. Greptile reviewed that commit at 5/5 with no findings and no open review threads. ## Risks - Long tool names change to aliases. Existing short names stay compatible. The original connection and upstream name remain the dispatch authority. - Invalid tool definitions no longer get automatic retries. An operator must repair the configuration before a new attempt. - Continuation changes apply only to positively identified unexpected legacy cancellations with complete empty tool inventory. Operator Stop, unknown historical cancellations, outstanding tools, and unverified provider termination keep their holds. - No database migration. The added projection fields are optional. Cancellation reason and initiator IDs remain local run evidence; Sentry receives only closed source and initiator-type labels and expectedness. ## Model Used - OpenAI GPT-6 through Codex, with reasoning, repository editing, shell execution, and GitHub tool use. The runtime does not expose the exact model variant 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> |
||
|
|
7d59de6113 |
feat(connections): probe provider usage limits on demand (#14936)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Connections store the AI accounts used by legacy and native runners. > - Subscription accounts can reach session, weekly, model, or paid usage limits. > - Operators need to read these limits for a specific stored account before making a routing decision. > - This pull request adds an on-demand usage probe to the connection service and account detail. > - The result preserves provider limits, reset times, paid usage, and unknown values for later consumers. ## Linked Issues or Issue Description **Subsystem affected** Shared contracts, the connection service and API, and the account detail UI. **Problem or motivation** Managed AI accounts lack a common operation to read their current usage limits. A local harness probe can read a different login from the account selected for an agent. **Proposed solution** Add `aiConnectionService.probeUsage()` and a board-only connection usage endpoint. Probe the selected credential grant on request. Support Codex, Claude, and Grok subscriptions, plus OpenRouter API key limits. **Alternatives considered** Harness-specific automatic polling would couple the read to execution and can read ambient credentials. This change uses the managed connection credential and leaves scheduling and admission decisions to later work. **Roadmap alignment** This extends the existing Personal & Shared AI Accounts capability. It adds no routing or quota enforcement. Related: Refs #14459 for managed OpenAI quota reads; Refs #14781 and Refs #13379 for downstream pacing and budget work. This operation reads one requested account across all three subscription providers. ## What Changed - Add typed usage snapshots and a probe capability flag to managed AI connections. - Normalize Codex, Claude, Grok, and OpenRouter responses. Keep model scopes, provider admission, reset periods, and paid allowances separate. Preserve unknown values. - Enforce company membership, credential audience, grant identity, and connection lifecycle before reading the stored secret. - Add a board-only `GET /api/companies/:companyId/ai-connections/:connectionId/usage` endpoint with `no-store` responses. - Add manual **Check usage** and **Refresh** actions to account details. Show compact usage bars, resets, admission and overage status; remove repeated descriptions and account-default copy. Clear previous results during a new request or error. - Add Storybook previews using the production account components for all four providers, initial checks, loading, and permission errors. - Add provider, authorization, runner selection, API, and UI coverage. Document provider sources and live qualification. ## Verification - Initial provider, authorization, selection, API, and UI validation passed (96 focused tests): `pnpm exec vitest run server/src/services/ai-connection-usage.test.ts server/src/__tests__/ai-connections.test.ts ui/src/components/ai-connections/AiConnectionUsagePanel.test.tsx server/src/__tests__/openapi-routes.test.ts`. - `pnpm -r typecheck` passes for the initial implementation. After simplifying the UI, 9 usage-panel and date-helper tests, UI typecheck, token gates, and Storybook build pass. The initial feature module boundary check also passed. - Real Codex, Claude, and Grok credentials were saved to encrypted disposable connections. The actual usage HTTP route returned 200 with `status: ok`. Legacy and native runner selection checks passed. The tests started no model turn and exchanged no refresh token. The disposable databases and vaults were removed. - Live Claude responses added structured scoped limits. Live Grok responses omitted included-plan usage. Tests now cover both shapes and preserve the Grok omission as unknown. - The full workspace build passes. A full local test run hit a heartbeat feedback timeout. That case passes in isolation. The duplicate local run was stopped after all remote checks passed. The Slack ordering and OpenCode transport CI flakes also pass in isolation and on the CI rerun. - Current head: `ff3d479029a1c4248190323e221b2803cfb0d79d`. All 54 active checks pass. Two Storybook checks are intentionally skipped by the workflow. Greptile is 5/5 with no unresolved review findings; the branch is mergeable. ## Risks - Subscription usage endpoints can change. Credentials can lack usage-read permission. The probe returns explicit errors without fresh limits in these cases. - A successful probe can contain partial data. Missing utilization or admission remains unknown. An enabled paid-usage switch does not prove a funded balance. - This change adds no migration. It does not change runner admission or automatic provider selection. Provider requests use fixed endpoints, disabled redirects, bounded response sizes, and a 15-second deadline. ## Model Used OpenAI Codex, GPT-6, with reasoning, file editing, shell execution, and HTTP tools. The session does not expose the exact runtime model variant or context window size. Real provider credentials were used only for the authorized live checks. ## 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> |
||
|
|
6c1a75da49 |
feat(connections): make AgentMail a default connection with inline setup (#14772)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Connections give agents access to external services. > - AgentMail needs both a saved key and an inbox assigned to the agent. > - Chat requests offered a setup link instead of an inline card and could treat a saved key as complete. > - Inbox setup also hid address conflicts behind a generic server error and a separate review step. > - This pull request makes AgentMail a default connection, adds the inline card, reduces setup to two steps, and shows conflicts beside the address. > - Shared native dropdown styles also give every caret a consistent inset. ## Linked Issues or Issue Description **What happened?** AgentMail requests in chat did not show a usable inline connection card. Manual setup required extra screens, ignored saved account keys, and could trap new-address setup in a locked inbox dropdown. Agent selectors omitted the avatar from the selected value. A taken address could produce an HTTP 403 from AgentMail and appear as an internal server error. Native dropdown arrows also touched the right edge of their fields. **Expected behavior** Make AgentMail available as a default connection. Ask for the API key inline, with a direct link to its provider page. Default human access to the company and agent access to the requesting agent. Resume the agent only after an assigned inbox is active. Manual setup should ask for an agent and email address, then finish. Address checks should run as the user types. Taken addresses should show clickable alternatives. A domain dropdown beside the name should prefer a verified custom domain. Setup should suggest authorized saved AgentMail keys and show agent avatars in the picker and selected value. **Steps to reproduce** 1. Ask an agent to connect AgentMail when it has no assigned inbox. 2. Check that an inline API-key card appears and links to the provider's API-key page. 3. Open AgentMail setup, choose an agent, and request an address that is already taken. 4. Correct the inline error, refresh, and finish setup with the same request ID. 5. Inspect native dropdown carets in light, dark, disabled, and right-to-left states. Uses the bounded provider-error parser merged in #14768. Related work: #13256 introduced AgentMail; #14725 expanded connection search. ## What Changed - Stop recurring email queries for tasks that have no email thread. Share the query between the thread provider and activity view. Keep email-task updates and invalidation-based discovery. - Make AgentMail available without the experimental chat setting. Keep the catalog, setup and management routes, agent Channels tab, task email feed, receiving worker, and agent tools available by default. Other experimental chat providers stay gated. - Make the email address and copy icon a single clickable action with the shared Copied! confirmation. Add View inbox linking directly to the matching AgentMail console inbox, with the address encoded as one URL path segment. - Reorganize inbox Settings around the copyable email address, usage instructions, and receiving status. Move reconnect credentials into a disclosure and separate the Disconnect action. Add production Settings stories for active, paused, unassigned-address, revoked, webhook, long-address, mobile, and reconnect states. Show repair controls when the inbox has an error. Keep usage instructions tied to an active inbox with an address. - Add AgentMail channel intents and an inline key field with the direct API-key URL. - Keep setup and retry state tied to the interaction. Require an active inbox for completion. Preserve company and agent access checks. - Reduce manual setup to agent selection and email selection. Put the domain dropdown beside the address and default to a verified custom domain. Preserve explicit choices across reloads. Keep receiving settings under Advanced options. - Check the initial address and edits after a 350 ms pause. Abort superseded requests and ignore stale responses. Show clickable suggestions and retain known creation conflicts across reloads. - Add a company-scoped, manager-only address check using the saved credential. Search the visible inbox list instead of fetching an uncreated inbox: live AgentMail retains negative lookups that can break subsequent access-key creation. Unlisted addresses remain unknown; creation is authoritative. - Suggest labeled saved AgentMail keys in both manual setup and the inline card. Filter by company, provider, active credential, and current-user grants on the server. Prefer an account key and preserve the selected key or an explicit new-key choice across refresh. Use verified scope metadata and bounded concurrent checks for legacy keys. Never return secret values. - Catch an inbox-only key before the email step. Allow its existing inbox only after an explicit choice. Recover old locked drafts at the key picker. Save the replacement key before retiring an empty draft, then use a new setup URL so refresh preserves the switched account; stop if cleanup fails. Preserve already allocated addresses and their original accounts. - Use the shared AgentSelect in email setup. Show the canonical agent avatar in each option and the selected value, including other consumers of the shared component. Add regression coverage for legacy and current Lucide agent-mention icon formats. - Start each catalog Add connection with a fresh setup identity. Honor Finish setup's exact draft/account/address instead of resuming an unrelated browser draft. Return Cancel and Done to Connectors and Email settings to the inbox. Group the task/thread explanation in a How it Works card. - Route AgentMail catalog removal through the email inbox control API, including unfinished drafts. Refresh both the catalog and inbox views. - Render each inbox management tab separately. Access uses the saved account grants and agent controls; Conversations and Activity use the shared persisted email feed. Activity lifecycle actions use the email API. Reconnect returns to inbox Settings. Conversation failures show a retry instead of a false empty state. Email delivery recovery stays in the task. - Map documented provider address conflicts to a field error. Preserve actionable messages for other failures. - Preserve non-secret draft fields across refresh, scoped to the requested agent. Never save API keys in browser storage. Resume partial inbox creation with the original agent, address, and request ID. - Show an already-created address with explicit retry and new-address recovery instead of locked inputs. Preserve the original inbox and resumable draft when choosing another address. Distinguish runtime-key 404 errors and log safe provider status/operation/code. - Apply final agent access once within email setup authorization for a new account whose original installs are unchanged. Preserve later permission edits and reused account installs. Support in-place retry of progress loading. - Let a failed inline setup change keys after retiring an empty draft. Persist its replacement setup identity without storing secrets. Recover a server-saved account when refresh interrupts the save response, while preserving intentional account changes. - Render the production setup in Storybook and add error, recovery, and mobile states. - Inset native select carets in shared CSS. Preserve custom icons, listboxes, keyboard behavior, and forced-color controls. - Add browser regression coverage and an AgentMail Product E2E case with persisted-state and rendered-card evidence. ## Verification - Full `pnpm -r typecheck`, `pnpm build`, `pnpm check:token-gates`, and `git diff --check` passed after the default-availability change. - All 485 focused tests passed. These cover setup, management, catalog and route gates, connection intents, email authorization, Cursor execution, and the OpenAPI contract. All 39 email integration tests run with the experimental chat setting off. - The shared polling change passed four behavioral tests, UI typecheck and build, and token gates. - `tests/e2e/agentmail.spec.ts` passed with the actual server setting off. This full-stack browser test uses simulated provider responses. It covers catalog entry, saved keys, editable address and domain controls, creation, conflicts, retry, all management tabs, clipboard feedback, the provider link, and task email rendering. - In the live local browser, Add connection reached the editable email step with the saved account key. The verified custom domain was selected by default. Both domain choices worked. The existing inbox Settings page remained available. Both active inboxes completed new mail checks with the setting off. No new provider inbox or email message was created for this pass. - Earlier live provider acceptance covered creation on a verified custom domain, Finish connecting on the reported draft, successful mail checks after refresh, and catalog removal of disposable draft and active connections. Clicking the email address copied the exact address and showed Copied!. View inbox opened the same inbox in AgentMail’s console. No email messages were sent. - Production setup and Settings Storybook builds and interactions passed. Settings states include active, paused, unassigned, revoked, webhook, long-address, mobile, and reconnect. Receiving and revoked-access stories had zero accessibility violations. - Full local `pnpm test:run` on an earlier revision completed with 14,709 passing, 87 skipped, and four transient failures. All four failed cases passed in focused reruns without product changes. That serial full local command was not repeated after each follow-up. The latest-head full CI suite is the final test gate. - CI found an obsolete browser assertion that hid every channel when the flag was off. Updated it to keep AgentMail and the Channels surface visible while preserving the GitHub chat route gates. All 11 provider browser tests passed locally after scoping the Channels selector to the agent sidebar. Two initial local attempts stopped at temporary Postgres initialization. The passing run used a separate disposable database on the existing local Postgres server; it was removed after the test. - Updated the remaining sidebar and aggregator discovery assertions for default AgentMail availability. Ordinary task fixtures now return no email thread. All 128 sidebar/task-page tests and all 42 aggregator tests passed locally. - Latest head `b42bb4cd5cc9f2d01a99ab8026832d5a956ea85f`: full CI passed, with 54 successful checks including Snyk and two intentional Storybook skips. The CI run is https://github.com/paperclipai/paperclip/actions/runs/37020833647. A fresh Greptile review scored 5/5 with no unresolved threads. Live model evaluations and inbound/outbound email delivery were not run. ## Risks - AgentMail no longer needs experimental opt-in. Setup still requires a human to connect an account and assign an inbox. Inline setup creates an inbox after a human submits a new or saved key. Company access, agent access, inbox assignment, and completion checks remain enforced. - AgentMail read APIs cannot prove global address availability. The visible-list check is bounded to 100 entries and cannot see inboxes outside the key’s scope. The UI reports this limitation, suggests alternatives without claiming they are free, and keeps final creation conflicts inline. Lookup outages show an error without preventing the authoritative creation attempt. - Native select CSS affects the whole app. Custom-icon selects and multi-row lists are excluded. Forced-color mode keeps the browser caret. - Saved-key discovery uses stored verified scope metadata and checks authorized legacy credentials concurrently within a shared three-second deadline. Provider outages mark legacy choices unavailable; users can still enter another key. Final use rechecks authorization and provider access. - No database migration or transport default change. Live connection remains the default. ## Model Used OpenAI Codex, GPT-6, with reasoning, tool use, and code execution. The exact served 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 (focused suites; full-suite limitation 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 (latest head `b42bb4cd5cc9f2d01a99ab8026832d5a956ea85f`) - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups (latest head `b42bb4cd5cc9f2d01a99ab8026832d5a956ea85f`) - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
e00d10d5d5 |
fix(connections): repair stale AI defaults from agent settings (#14916)
## Thinking Path > - Paperclip manages AI agents and controls the credentials used for their work. > - Managed AI connections resolve each responsible user's provider default. > - Agent settings created another account but kept the old default selected. > - A rejected provider test left the old account marked as connected. > - Claude ACP reported a typed login failure as a generic terminal-access error. > - This pull request repairs the selected account or selects the new login explicitly. > - Agents can save and run with the repaired credential, and failed logins request sign-in. ## Linked Issues or Issue Description - Fixes #14831. - Refs #13867. Environment failures remain separate from credential-health failures. ## What Changed - Add an agent-settings action to reconnect an unavailable personal default in place. Keep its connection, grant, default, and agent access. - State that a new account becomes the user's provider default. Select its returned grant before changing the agent binding. Keep the actual sign-in method. - Show default-update errors and allow retry without another provider login. - Show the agent-access choice. Connection managers start with company-wide access for their own tasks. Other members start with access for the current agent. - Use the server's connection-manager permission in the shared list response. This includes members with a custom management grant. - Mark credentials as needing attention after an explicit login rejection in Test or Save. This includes API-key 401 and 403 responses. Network, quota, and server failures keep the credential health unchanged. - Reuse the credential-generation check so an old failure cannot invalidate a newer reconnect. - Route Claude's typed provider `access` failure to the existing login-recovery flow. Replace its generic terminal-access fallback with a sign-in message. - Add regression tests and update the AI Connections documentation. ## Verification - Red: the UI tests failed on the missing reconnect action, unused returned grant, missing access choice, and lost default-update error. The server tests failed because rejected credentials stayed connected. The real ACP fixture returned `acpx_turn_failed` for typed login failures. - Green: 156 tests passed across the AI connection, hiring, agent field, and New Agent suites. All 37 environment-route tests passed. The Claude ACP authentication fixtures also passed. - `pnpm check:token-gates` passed. - `pnpm -r typecheck` passed. - `pnpm build` passed. - The full local `pnpm test:run` passed 707 files and 14,503 tests, then exited with an agent-conversation timeout and embedded PostgreSQL startup failures in unchanged suites. The isolated conversation and migration tests passed on rerun. Later local test groups did not run after this failure. - [All CI gates passed](https://github.com/paperclipai/paperclip/actions/runs/37012669356) on commit `38513dfe2`. This includes the full test matrix, browser tests, typecheck, build, Runner checks, and canary dry run. - Greptile reviewed commit `38513dfe2` and returned 5/5 with no open findings. - The regression tests use a real embedded database and a real ACP fixture process. Live provider sign-in requires a valid account and was not run. ## Risks - Connecting a new account from agent settings changes the user's provider default. The dialog states this before sign-in. - The displayed access choice can allow all company agents to use the account for its owner's tasks. Reconnect keeps the existing access. Server permissions still control installs. - Claude's typed `access` category maps to the provider's `auth_required` signal. Tool and workspace request failures retain their existing classification. - No database migration or provider credential format changes are required. ## Model Used - OpenAI GPT-6 through Codex. The exact served model identifier and context window are not exposed in this session. Capabilities used: reasoning, repository tools, code editing, and command execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
c46e41e81c |
fix(heartbeat): validate native MCP gateway ownership (#14914)
## Thinking Path > - Paperclip lets people manage agents and govern their tool access. > - Native runs receive an immutable MCP tool assignment for one agent. > - The gateway must enforce that owner when it authenticates a run token. > - Older gateway rows stored the owner only in metadata. > - This change validates the gateway and profile, binds new rows, and repairs valid older rows on reuse. > - It also delivers each native assignment once. > - Other agents cannot use the assignment, and explicit shared gateways keep their configured scope. ## Linked Issues or Issue Description Builds on #14012 by @busla (Jón Levy). That PR adds agent binding and seven regressions. This PR carries that fix onto current master and adds legacy authentication, profile validation, and duplicate-delivery coverage. Related: #14864 improves discovery memory use. **What happened?** Native gateway creation stored an owner in metadata but left `agentId` null. Authentication could therefore accept another agent's run token. Managed discovery could also deliver historical native assignments again. **Expected behavior** A native assignment accepts only its owner's run token. The gateway and profile must refer to the same immutable assignment. The current assignment enters the run configuration once. **Steps to reproduce** 1. Run the database fixtures in `heartbeat-runtime-mcp-servers.test.ts` on the baseline. 2. Create a native assignment and inspect its stored gateway owner. 3. Authenticate with another agent's run token, then inspect legacy reuse and managed delivery. 4. The baseline fails six ownership and delivery cases. The fix passes all twelve cases. **Paperclip version or commit** The red baseline is `f2e0f1963`. This PR is based on `cad26c6bf`, which includes the merged discovery fix. **Deployment mode** Native Paperclip Runner execution and managed Codex MCP delivery. Reproduction uses isolated database and HTTP fixtures. ## What Changed - Store the agent owner and agent context on new native gateways. - Validate profile and gateway assignment metadata before reuse or token creation. - Bind valid legacy rows with a company-scoped, null-owner update and validate the result. - Reject mismatched run tokens before legacy repair. - Identify native assignments by gateway metadata, the reserved profile key, or profile source. Reject missing or malformed provenance, including JSON null. - Exclude historical native assignments from managed gateway delivery. Keep their rows for existing runs. - Add twelve database and HTTP regressions and document the runtime contract. ## Verification - Red baseline: six regressions fail and four controls pass before the initial fix. Two additional regressions reproduce metadata-loss admission and a JSON-null TypeError before the review fix. - All twelve ownership regressions pass on the final code, including owner admission, cross-agent rejection, metadata loss, JSON-null HTTP 401, and explicit shared-gateway admission. Policy, listing-memory, and discovery HTTP coverage also passes. - Full workspace typecheck and build pass locally. Server typecheck and compilation pass again after the review fix. The final ownership and grant patches pass 42 combined database and HTTP regressions. - [Full CI](https://github.com/paperclipai/paperclip/actions/runs/37011383657) passes for `626a08ae66361cf586105877e24d806b1a7a9c20`: all 54 checks succeed; two optional Storybook checks skip. This includes full typecheck, build, all test shards, all eight E2E shards, runner verification, and the canary dry run. - Greptile scores that exact head 5/5. No review threads remain unresolved. ## Risks Invalid historical native gateway or profile metadata now rejects authentication. Valid unbound rows are repaired only when their owner reuses the assignment. Conflicting owners are never overwritten. Historical rows are retained for existing runs. Explicit shared gateways use ordinary profiles and keep their configured scopes. The reserved native profile namespace remains agent-owned even when gateway metadata is cleared. No schema or dependency changes are included. ## Model Used Original fix and seven regressions in #14012: Anthropic Claude Opus 5.5, `claude-opus-5-5`, 1M context, as reported by @busla. Extensions and verification: OpenAI Codex (GPT-6), with reasoning, repository inspection, code execution, and tests. This session does not expose the exact serving model identifier or context window. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
483dbc8890 |
fix(tool-access): enforce stored grant restrictions (#14915)
## Thinking Path > - Paperclip governs the tools that agents can discover and call. > - Stored grants can limit access to a tool, connection, or application. > - The grant matcher must enforce every restriction in that scope. > - A nonmatching allow list fell through to a policy selector matcher that ignores allow. > - This change requires an explicit allow match and validates additional selectors. > - Malformed and unknown restrictions deny access. > - Discovery and execution now enforce the same stored grant limits. ## Linked Issues or Issue Description Related: #14864 adds the shared database and HTTP discovery fixture used here. Searched existing public PRs for tool grant scope fixes. No duplicate scope-validation fix was found. **What happened?** A stored grant with a nonmatching `scope.allow` could authorize a tool. Empty or malformed allow lists, unknown selectors, and combined mismatching selectors could also authorize access. The fallback policy matcher does not validate stored grant JSON. **Expected behavior** An explicit allow list must match the requested tool, connection, or application. Every additional selector must also match. Unknown or malformed restrictions must deny access. Existing null and empty-object scopes keep their broad grant behavior. **Steps to reproduce** 1. Run `tool-grant-scope.test.ts` on the baseline. 2. Create a deny profile and a grant that names another tool. 3. Attempt discovery or a call for the tool outside the grant. 4. The baseline authorizes access. The fix denies it. **Paperclip version or commit** The red baseline is `f2e0f1963`. This PR is based on `cad26c6bf`, which includes the merged discovery fix. **Deployment mode** The company-scoped MCP gateway. Reproduction uses isolated database fixtures and a deterministic HTTP provider. ## What Changed - Require an explicit allow entry to match the gateway or upstream tool name, connection, or application. - Apply all additional selectors after the allow match. - Reject unknown selectors, invalid value types, empty restrictions, and non-object scopes. - Preserve null and empty-object scope compatibility. - Add sixteen regressions, including discovery, successful execution, and revocation through the HTTP gateway. - Document stored grant scope behavior. ## Verification - Red baseline: seven restricted-scope cases and three malformed-root cases fail. HTTP discovery also exposes tools outside the grant. - All 16 grant regressions and 35 adjacent policy tests pass locally. The HTTP test excludes an ungranted tool from discovery, returns 403 for its call, and verifies that no provider call occurs. It also checks successful execution and later revocation. - Server typecheck passes. The final ownership and grant patches also pass 42 combined database and HTTP regressions. - [Full CI](https://github.com/paperclipai/paperclip/actions/runs/37011177989) passes for `803fa9440111742672c94c4471e5b98f15dd3b97`: all 54 checks succeed; two optional Storybook checks skip. This includes full typecheck, build, all test shards, all eight E2E shards, runner verification, and the canary dry run. - Greptile scores that exact head 5/5. No review threads remain unresolved. ## Risks Stored scopes with unknown keys or malformed restrictions now deny access. Operators must correct those grants before they can authorize tools. Null and empty-object scopes keep their previous broad behavior. There are no schema, dependency, or API changes. ## Model Used OpenAI Codex (GPT-6), with reasoning, repository inspection, code execution, database regressions, and HTTP tests. This session does not expose the exact serving model identifier or context window. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
cad26c6bfb |
fix(tool-gateway): bound MCP discovery memory and concurrency (#14864)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agents discover governed tools through the MCP gateway. > - A listing repeated policy and full run-row reads for each catalog tool. > - Parallel listings multiplied those allocations during run startup. > - One 900-tool baseline listing used 11,489 queries and about 1.7 GiB of extra heap in a fixture. > - This pull request shares reads within a listing and bounds whole listings across the process. > - The benefit is lower discovery memory use while execution still checks current policy. ## Linked Issues or Issue Description Refs #13115. Its on-demand target change affects the same listing loop. **What happened?** MCP discovery repeated roughly 13 reads per tool. Full run snapshots and repeated connection configurations caused large allocations. Per-listing bounds alone did not limit concurrent listings across gateways. **Expected behavior** Discovery reads shared inputs once per listing. The process bounds active and queued listings. Catalog payload size and policy evaluation still grow with the catalog. Tool execution checks current access rules. **Steps to reproduce** Create a company with a remote MCP connection, 900 catalog tools, large schemas, and a large run snapshot. Send concurrent tools/list requests using a run-bound gateway token. Run the committed benchmark for a deterministic reproduction. **Paperclip version or commit** Baseline: |
||
|
|
4a999089ef |
Retry transient failures in dashboard reads (#14873)
## Thinking Path > - Paperclip shows company activity in the dashboard. > - The dashboard reads company, task, approval, and cost data. > - A pooled database connection can close during one of these reads. > - The driver must reject ambiguous statements because writes may have committed. > - These four dashboard queries are known to be read-only. > - This change retries only the failed read and preserves completed work. ## Linked Issues or Issue Description Refs #14773, which correctly removed automatic replay of ambiguous database statements. Searched existing database and dashboard PRs. Related #8780 changes pool recycling and logging; #13925 adds dashboard consistency coverage. Neither provides these per-query retries. **What happened?** A dashboard request returns a server error when its company lookup, task count, approval count, or monthly spend query loses its database connection. Drizzle wraps the driver's connection error in `cause`. **Expected behavior** A transient connection failure gets a bounded retry of the specific read. Completed reads and budget processing are not replayed. Persistent outages and non-connection errors still fail the request. **Steps to reproduce** Inject a typed `CONNECTION_CLOSED` error into one of these reads. Then allow the next query to succeed. Before this change, the dashboard request fails immediately. ## What Changed - Apply independent retries to the company lookup, task counts, pending approval count, and monthly spend query. Each callback rebuilds its own query with the same company scope. - Extract the existing authentication retry helper as `retryIdempotentDatabaseOperation`. Preserve authentication behavior and its existing exports. - Retain the existing limit of three total attempts with 50 ms and 100 ms pauses. Match typed connection codes through the error cause chain. - Test later-read failures, unchanged query parameters, retry exhaustion, missing companies, and errors that must not retry. Document the boundary. ## Verification - Final focused dashboard, authentication, and real database wire suites: 38 tests passed. Six initial recovery regressions failed before the implementation. - `pnpm -r typecheck`: passed on the final source. - Independent review: no actionable findings. The reviewer separately passed all 38 focused tests and checked the code allowlist, attempt bounds, pauses, and final error identity. - `pnpm test:run`: the general-server group completed with 14,738 tests passed, 13 failed, and 87 skipped. All 13 failures match the previously reproduced clean-base macOS skill-cache failures. The two test files and their implementations are unchanged from that baseline. The runner exited after this group, so the remaining local workspace and serialized groups did not run. All corresponding Linux CI groups passed on this commit. - `pnpm build`: passed on the final source. - Full CI: 53 successful checks and 2 skips on `6a113529c0`. Greptile: 5/5 on that commit, with no review threads or remaining findings. - Merge compatibility with master `f2e0f19630`, including #14866: no conflicts. The five reviewed files are unchanged in the resulting merge tree. ## Risks A persistent outage adds at most two retries per covered query. Each connection attempt retains the configured driver timeout. The change does not repair the underlying network or database failure. Agent counts, run-activity queries, and the budget workflow stay outside these retry boundaries. General database statements and disconnected transactions are not replayed. There is no schema or authorization change. ## Model Used OpenAI GPT-6 through Codex, with reasoning, repository inspection, code editing, and test execution. The runtime does not expose a more specific serving model identifier 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 (38 focused tests; the full local run has the baseline limitation 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> |
||
|
|
427e048405 |
fix(company-skills): approve managed-checkout project dirs for local skill import (#10329)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - Company skills can be imported into a company from a local folder;
`companySkillService.importFromSource` guards this with
`assertLocalImportSourceAllowed`, which only permits import sources
inside an approved set of roots (managed skills root + registered
project-workspace cwds), realpath-resolved and `${root}${sep}`-anchored
to prevent path traversal/escape
> - A project can exist as a `managed_checkout` (server-managed clone)
with **no registered `project_workspaces` row** — its `primaryWorkspace`
is `null` and `workspaces` is `[]`, so its only real on-disk location is
the server-derived `codebase.managedFolder`
> - Because `configuredRoots` was built solely from the managed skills
root and `workspaces[].cwd`, a `managed_checkout` project's
`managedFolder` was never an approved root, so importing a skill from
that project's own folder was rejected with
`skill_workspace_boundary_denied`
> - This PR adds each project's server-derived `codebase.managedFolder`
to `configuredRoots` so in-place skill imports from managed-checkout
projects are allowed
> - The benefit is that managed-checkout projects can re-import their
own skills in place, without weakening the traversal/escape protections
(the new roots are server-derived and matched exactly like the existing
ones)
## Linked Issues or Issue Description
No public GitHub issue. Describing in-PR (bug):
**What's wrong:** `assertLocalImportSourceAllowed` denies a legitimate
local skill import (`skill_workspace_boundary_denied`) for any project
that is a `managed_checkout` with no registered workspace row.
**Repro:** Create/import a company skill from a `managed_checkout`
project's own folder (`codebase.managedFolder/.agents/skills/<skill>`).
The import is rejected even though the source is inside the project's
server-managed checkout.
**Expected:** The import from a managed-checkout project's own
`managedFolder` subtree should be allowed, while paths outside that
subtree remain denied.
Related context (already merged): #9564 introduced the open-by-default
skill policy / this import boundary. This PR does not change that
boundary's matching logic — it only adds a missing, server-derived
approved root.
## What Changed
- `server/src/services/company-skills.ts`: add
`...projectRows.map((project) => project.codebase.managedFolder)` to
`configuredRoots` in `assertLocalImportSourceAllowed`. `managedFolder`
is server-derived (`resolveManagedProjectWorkspaceDir(companyId,
projectId)` → instance root + sanitized ids); it is
`fs.realpath`-resolved and `${root}${sep}`-prefix matched exactly like
every existing root. `managedFolder` is used rather than
`effectiveLocalFolder` because the latter can fall through to a
user-registered `localFolder`, which is already covered by the
registered workspace cwds.
- `server/src/__tests__/company-skill-import-boundary.test.ts`: add a
regression test — a managed-checkout project's `managedFolder/<skill>`
import is **allowed**, and a **prefix-adjacent sibling** (`managedFolder
+ "-evil"`) stays **denied**.
## Verification
- `cd server && ./node_modules/.bin/vitest run
src/__tests__/company-skill-import-boundary.test.ts` → **2/2 pass**
(embedded-Postgres suite). Covers both the new allow case and the
prefix-adjacent deny case, alongside the existing out-of-tree /
symlink-escape / non-file-scheme rejections.
## Risks
Low risk. The change only **adds** approved roots; it does not alter the
realpath + `${root}${sep}`-anchored matching that closes
traversal/prefix-adjacency escapes. The added roots are fully
server-derived from the instance root + sanitized company/project ids
(same trust class as the existing `resolveManagedSkillsRoot`) — no value
derived from the import `source` argument reaches them. Sanitization
(`[^a-zA-Z0-9._-]+ → -`) prevents separator/level injection, and the
only user-influenced segment (repo name) is normalized via `new
URL(...)`. The regression test's prefix-adjacent (`-evil`) case asserts
the escape class stays closed.
## Model Used
Claude Opus 4.8 (`claude-opus-4-8`), extended thinking + tool use (code
execution, git). Implementation and security review were produced with
Claude; this integration/PR was prepared with `claude-opus-4-8`.
## 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
- [ ] I have updated relevant documentation to reflect my changes (N/A —
internal boundary fix, no user-facing docs)
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green (CI in progress)
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
(pending review)
- [x] I will address all Greptile and reviewer comments before
requesting merge
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: brandonburr <brandonburr@gmail.com>
|
||
|
|
f2e0f19630 |
Defer agent directory cleanup until stop proof is available (#14866)
## Thinking Path > - Paperclip manages agents and their persistent files. > - Each run owns a temporary agent directory and a save receipt. > - Cleanup needs independent proof that the owning process stopped. > - A cleanup call without that proof currently waits for the directory lock anyway. > - A second lock failure can prevent environment release after the run already reported a failed save. > - This change skips cleanup that has no authority and retries unavailable remote copies after exact destruction proof. > - The save failure stays visible. Existing lock owners remain protected. ## Linked Issues or Issue Description Related work: Refs #14787 (lock diagnostics), #14695 (warm instruction ownership), #9667 (stale lock proposal), and #9872 (control-plane ownership proposal). I checked open PRs and issues. This change leaves the shared filesystem lock protocol in place and does not duplicate the warm-retention work in #14695. **What happened?** Heartbeat cleanup records an explicit unavailable instruction-save warning, then calls directory release before releasing the environment lease. Release can wait for a lock even though the copy has no process-stop proof and cannot be removed. That secondary timeout prevents the following lease-release step. If destruction proof arrives later, the unavailable copy is excluded from both recovery queries. **Expected behavior** Skip a release that cannot remove anything. Preserve the failed-save receipt and candidate fields. Once exact remote destruction is recorded, recover remote cleanup without running a provider command. Unavailable local copies retain their potentially uncollected edits even if local stop proof arrives later. A blocked cleanup must not prevent cleanup for other agents. **Steps to reproduce** 1. Prepare an agent directory, report its save unavailable, and leave process-stop proof absent. 2. Hold the shared directory lock and call release. Before this change, release waits and fails although removal is not authorized. 3. Record destruction of the copy's exact remote lease. Before this change, neither recovery sweep selects the unavailable copy. **Paperclip version or commit** Reproduced against `efc2e6810e9bc0dc8cb412b0e7647c0db9821caa`. **Deployment mode** Local and remote execution with persistent agent directories. Tests use an isolated embedded PostgreSQL database and fixture transports. ## What Changed - Re-read receipts and skip release before lock acquisition when stop proof is absent, the copy is superseded, or cleanup is complete. Keep the same checks inside the lock. - Recover unavailable remote copies only after exact destruction proof. Preserve their unavailable state, errors, candidate hash, and candidate bytes. Keep unavailable local copies and their uncollected edits unchanged. - Store destruction-only cleanup authority with the stop proof. Later cleanup honors it after a lost database response or restart, including when a transport remains cached. - Defer failed or unproven cleanup with bounded batches and a retry delay. Keep failed cleanup visible in logs and its receipt. - Serialize preparation of an existing run with cleanup. Fresh run preparation keeps its existing admission path. - Cover held locks, receipt scope, delayed proof, batch fairness, lost update responses, cached transports, and concurrent same-run preparation with database regressions. ## Verification - Focused directory, legacy instruction-copy, shared lock, and bounded diagnostic suites: 169 tests passed across four files. - `pnpm -r typecheck`: passed on the final source. - `pnpm build`: passed on the final source. - Completed all selected local `pnpm test:run` groups: 733 general server suites, 149 serialized suites, and 14 workspace projects. There are 13 known macOS `EACCES` failures in the unchanged runtime skill cache tests. Their exact signatures match earlier clean-base results, and the cache source and test blobs match both that base and this PR base (existing fix: #14290). One CLI import test timed out under concurrent load; its full file passed separately (17 tests). Broad coverage began before the review corrections; the final source has the focused 169-test run, typecheck, and build. This is a local verification limit, not a passing full local suite. - `git diff --check` and local Gitleaks plus private-identifier/PII diff scans passed. - Independent review of the final source found no remaining actionable issue. Its 17 targeted tests cover crash recovery, cached transports, same-run preparation, real local edit preservation, proof scope, and batch fairness. The main focused run also covers contained scheduling failures. - Final commit `35a24085f7`: Greptile 5/5 with no recommendations and zero unresolved review threads. - Final commit `35a24085f7`: all 53 checks passed, including Canary Dry Run and the security scan; two visual checks were intentionally skipped. The workspace shard passed on retry after GitHub reported that its first runner lost communication. An earlier Canary runner shut down after the release dry run passed. Neither interruption recorded an application assertion failure; the exact final-head checks are now green. ## Risks - This repairs cleanup ordering and recovery eligibility. It does not repair an ambiguous legacy lock owner or restore unsaved files. Actual collection still fails visibly when its lock cannot be acquired. - An unavailable remote copy is recovered only after exact destruction proof. A stopped but retained environment stays protected; recovery does not execute a command that could restart it. - Unavailable local copies with later stop proof still retain potentially uncollected edits. A general local recollection or reclamation policy remains outside this change. - Existing-run preparation now waits for the same lock as cleanup. The fresh-run path is unchanged. - The cleanup mode is stored in the existing private receipt JSON. No schema migration or public API change is required. - No deployment, task replay, or runtime lock deletion was performed. ## Model Used OpenAI GPT-6 (Codex), with reasoning, repository tools, and test execution. The runtime does not expose a more specific model suffix 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 #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub references) - [x] My branch name describes the change and contains no internal Paperclip ticket id - [ ] 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> |