mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-31 14:16:39 +01:00
52e846f2f3bc1313f19be1a72f54e454c8d1ddb9
6003
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
52e846f2f3 |
perf(ci): select affected Vitest files before allocating test runners (#18348)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Its CI must catch regressions without running unrelated work on every pull request. > - The existing task planner selects package lanes, but each selected lane still runs all its test files. > - Vitest can find related imports, but that graph misses tests that read files or launch processes. > - This pull request combines the real Vitest graph with conservative dependency checks before CI allocates test runners. > - The result runs fewer test files and can allocate fewer jobs while retaining tests with unknown dependencies. ## Linked Issues or Issue Description Refs #18214. The repository and PR search found no duplicate file-selection implementation. **What existing behavior does this improve?** The general and serialized Vitest lanes in pull request CI. **Current behavior** An affected package schedules its complete test lane and its fixed shard count. **Proposed behavior** For source-only diffs, select related tests plus conservative filesystem, process, network and opaque consumers. Repartition those files within their existing lane owners. Keep the complete original plan when selection cannot be trusted. **Reason and benefit** Avoid unrelated test execution and allocate fewer runners when the selected workload fits fewer existing job budgets. Report file counts and job counts separately. **Breaking changes** No product or API changes. The set of PR test files and jobs changes for eligible diffs. Full CI and the kill switch retain the original coverage. ## What Changed - Add a separate selection job on the gate-approved test fleet. The metadata gate does not load PR code. - Inspect real Vitest/Vite dependency edges. Retain opaque consumers and unchanged downstream projects. Respect only complete local mock factories. Reject unknown setup dependencies and source mutations during dependency setup. - Declare `oxc-parser` directly for AST inspection. This exact version is already a transitive dependency in the checked-in lockfile; the direct declaration avoids relying on pnpm's internal dependency layout. - Produce a merge-SHA-bound manifest with exact lane ownership and duration-aware partitions. Preserve serialized execution, chat shards and native Runner ownership. - Execute exact Vitest test specifications. Positional substring filters cannot accidentally run a similarly named file from another shard. - Use the original matrix if selection fails or times out. Fail selected jobs if their published artifact is missing or invalid. - Save the uploaded artifact ID in the executable plan. Failed-job retries reuse that artifact even when GitHub increments the attempt number. - Hash selected assignments into Turbo cache inputs. A subset cannot satisfy a full run or another subset. - Add graph, workflow, real-runner and real-Turbo qualification. The regression fixture proves a filesystem contract fails even when raw Vitest selection misses it. - Document selection limits, audit artifacts and `CI_VITEST_SELECTION=off`. ## Verification - All 138 affected routing, sharding, workflow, manifest, real Vitest and real Turbo checks passed under Node 24 on the final implementation. Additional release workflow checks passed. Cases cover opaque setup, remocking, generated inputs, Node's builtin loader, artifact retries, and exact execution of similarly named files. - Repository-wide `pnpm -r typecheck` and `pnpm build` passed before the clean rebase onto current master. The full remote typecheck and build are required on the current head. - `actionlint` passed for both changed workflows. `git diff --check` passed. - The Linux qualification run passed and selected 699 of 911 workspace test files for an Inbox change. UI graph construction took 16.1 seconds. This still uses two jobs. Synthetic partition coverage proves a 15-of-120 selection uses two of twelve jobs without dropping or duplicating files. - Both selected workspace shards passed locally. After tightening execution to exact specifications, the real colliding UI test ran as exactly one file with two passing assertions; the real server auth middleware test ran as exactly one file with 28 passing assertions. - The server probe selected 1,158 of 1,260 general files and 161 of 163 serialized files for an auth middleware change. Those conservative selections retain 12 general and nine serialized jobs. The server's temporary-home setup exception is pinned to reviewed content hashes; changed setup fails closed. - Full `pnpm test:run` has not been run locally. The full PR test matrix is required because this change modifies global CI inputs. Final-head CI is pending at runner allocation, and both qualification jobs are queued. Other recent repository workflows are also queued. Superseded runs of this PR were cancelled; this PR remains in draft until the required checks execute. - Greptile reviewed final commit `31b484fc5b412da245cffb52a8ac8977228c5651` at 5/5 with no unresolved findings. The earlier qualification run passed; it does not replace checks on the final commit. ## Risks - Dependency analysis adds setup and graph time. Fewer files do not guarantee a shorter critical path. CI summaries expose the actual file and job counts. - Static dependency graphs cannot describe all runtime inputs. Unknown inputs retain tests or use the original plan. The pure-package allowlist requires conservative review. - The trusted workflow runs from master. This PR exercises the new selector in the qualification workflow; ordinary PR selection starts after merge. Set `CI_VITEST_SELECTION=off`, use `full-ci`, or select full/shadow mode to disable narrowing. - The lockfile remains managed by the existing repository actions and is not changed here. ## Model Used OpenAI Codex, based on GPT-6, with repository tools 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 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> |
||
|
|
aa58fa1073 |
perf(ui): restore fast Coordinator task and inbox loading (#18323)
## Thinking Path > - Paperclip lets people manage work done by agents. > - Tasks, Inbox, and Needs You must stay usable as work history grows. > - The Coordinator views bypassed some existing collection optimizations. > - Navigation fetched complete decision cards for a count, and Tasks mounted every loaded row. > - This PR uses the canonical attention rules for small count and task-ID responses. It also restores bounded rendering and the optimized Inbox selection. > - The benefit is less data and less initial rendering work without a second definition of pending work. ## Linked Issues or Issue Description **What happened?** Coordinator navigation fetched the full attention feed on every cold collection visit. Tasks rendered the entire loaded collection. Coordinator could also select the old Inbox loader when Streamlined UI was off. **Expected behavior** Fetch only the projection needed by each surface. Start with a bounded set of rows. Keep complete task membership, accurate counts, current permissions, and stable loaded rows. **Steps to reproduce** 1. Enable Coordinator and open Tasks or Inbox with an empty browser query cache. 2. Observe a complete attention-card download for the navigation badge. 3. Open a large task list and observe that every loaded row mounts at once. 4. Disable Streamlined UI while keeping Coordinator enabled, then open Mine and observe three overlapping compact task reads. Related work: #17756, #3744, #17983, and #18312. ## What Changed - Add board-only attention count and complete task-ID projections. Reuse canonical company, privacy, addressee, deduplication, dismissal, snooze, and archive rules. Skip card bodies, plan/image reads, and presentation roster lookup. - Share the small count read across desktop and mobile navigation. Reuse the page-owned response on Needs You and Needs attention. Keep the newest known count through navigation, including zero. - Use the task-ID index for Needs attention and keep task row hydration in batches of at most 100. - Render 100 task rows initially, across the whole expanded tree. Reveal 150 more at a time through scrolling or a button. Keep existing rows through refresh and append. Defer offscreen leaf layout with shared tokens. - Keep Coordinator on the optimized Inbox when Streamlined UI is off. Use index reads for expanded project recents. - Add real-database, component, and production-build browser regression checks. Update the access and feature maps. ## Verification - All required CI checks pass on `1c68ac8957490a6c8585ba0939355f536c8120bf`: typecheck, build, server/workspace tests, serialized database suites, and eight E2E shards. Greptile is **5/5**, with its row-retention finding fixed and the review thread resolved. Storybook checks were intentionally skipped; Paperclip Review completed neutral. - Workspace typecheck and production build passed locally. The final rebased source also passed UI typecheck and production build. Token gates and map checks passed. - The attention service suite passed all 34 tests on disposable PostgreSQL. Final targeted checks cover compact projections, complete-set counts, quality approvals, snoozes, private tasks, and board/company access. Database response capture confirms compact projections do not read plans or images. All 31 OpenAPI tests passed after registering both endpoint contracts. - Six production-build browser journeys passed: desktop, mobile, Coordinator Inbox with Streamlined UI off, Needs You, Needs attention, and an older server page followed by task open/Back. They verify the initial 100-row budget, scrolling, retained DOM identity/height, one owner per attention read, complete task membership, 220 retained rows on Back, and less than 2 px of return-position difference. - The row-budget and Inbox regressions fail against original source and pass with this change. The final three affected UI suites passed 40 tests, and the broader Inbox/IssuesList suites passed 101 tests serially. ### Controlled production-build comparison Baseline `b31ec0a2dc079e32272a8f618425fe92b68bbaec` versus PR head `1c68ac8957490a6c8585ba0939355f536c8120bf`. Isolated baseline asset `index-CS9uPxMx.js`; candidate asset `index-BxJeTQ30.js`. Both UI builds used the same warm disposable API server and database, with 220 tasks and 110 pending board approvals. Chromium **151.0.7922.34**, 1440 × 900 viewport, **4× CPU throttle**, loopback with no added network latency, alternating baseline/candidate order. Cold cases use a new browser context with network cache disabled; warm cases navigate within the same context. Other host workloads are uncontrolled. Readiness requires the destination collection's first visible task row, then two animation frames. Inbox readiness waits for its canonical Mine route so previous-page rows cannot satisfy the measurement. Five paired samples per case; cold Inbox has a second five-pair confirmation wave because the first result was slower. Times below are **milliseconds**; parentheses show min–max. Paired savings are the median of individual before-minus-after pairs, not the difference between medians. | Journey | Pairs | Baseline median (range) | Candidate median (range) | Median paired saving | Faster pairs | | --- | ---: | ---: | ---: | ---: | ---: | | Cold Tasks | 5 | 2752 (2542–3025) | 2300 (2275–2524) | 328 | 5/5 | | Cold Inbox | 10 | 2536 (2283–2927) | 2582 (2117–2856) | 37 | 5/10 | | Warm Tasks navigation | 5 | 2054 (1826–2479) | 1448 (1419–1548) | 635 | 5/5 | | Warm Inbox navigation | 5 | 2020 (1485–2254) | 1568 (1289–1848) | 350 | 5/5 | | Task → Back to Tasks | 5 | 1747 (1609–1948) | 1327 (1238–1355) | 472 | 5/5 | Cold Tasks, warm Tasks, warm Inbox, and Back improved in every measured pair. **Cold Inbox latency is inconclusive:** the two waves pointed in opposite directions, with the candidate faster in 5/10 pairs. This PR claims less badge work there, not a proven cold Inbox latency improvement. The canonical badge response shrank from **200,039 to 359 decoded bytes** (encoded HTTP transfer: **8,125 to 598 bytes**). The compact response also skips card payloads, plans, images, and presentation-only roster work. These are measured mechanism reductions, separate from end-to-end latency. Needs You still owns its full card feed; Needs attention owns its complete task-ID projection. Reproduction setup and assertions are in `tests/perf/collections/README.md`. <details> <summary>Individual paired readiness measurements (ms)</summary> | Journey | Pair | Baseline | Candidate | | --- | ---: | ---: | ---: | | Cold Tasks | 1 | 3025 | 2283 | | Cold Tasks | 2 | 2542 | 2275 | | Cold Tasks | 3 | 2752 | 2424 | | Cold Tasks | 4 | 2783 | 2300 | | Cold Tasks | 5 | 2641 | 2524 | | Cold Inbox | 1 | 2927 | 2702 | | Cold Inbox | 2 | 2422 | 2629 | | Cold Inbox | 3 | 2409 | 2606 | | Cold Inbox | 4 | 2621 | 2769 | | Cold Inbox | 5 | 2539 | 2856 | | Cold Inbox | 6 | 2283 | 2117 | | Cold Inbox | 7 | 2466 | 2558 | | Cold Inbox | 8 | 2674 | 2286 | | Cold Inbox | 9 | 2696 | 2389 | | Cold Inbox | 10 | 2533 | 2183 | | Warm Tasks navigation | 1 | 2479 | 1423 | | Warm Tasks navigation | 2 | 2228 | 1548 | | Warm Tasks navigation | 3 | 2054 | 1419 | | Warm Tasks navigation | 4 | 1826 | 1448 | | Warm Tasks navigation | 5 | 1954 | 1518 | | Warm Inbox navigation | 1 | 2020 | 1661 | | Warm Inbox navigation | 2 | 2198 | 1848 | | Warm Inbox navigation | 3 | 1733 | 1497 | | Warm Inbox navigation | 4 | 2254 | 1568 | | Warm Inbox navigation | 5 | 1485 | 1289 | | Task → Back to Tasks | 1 | 1721 | 1330 | | Task → Back to Tasks | 2 | 1747 | 1275 | | Task → Back to Tasks | 3 | 1948 | 1355 | | Task → Back to Tasks | 4 | 1609 | 1327 | | Task → Back to Tasks | 5 | 1790 | 1238 | </details> ### Failed attempts and limits - The local full repository command hit embedded PostgreSQL startup failures and 16 failures in the untouched native session executor suite; it was stopped. The full local suite is not claimed green. CI on the final revision provides the broad test result. - A concurrent local UI run hit timing failures under host contention. Inbox/IssuesList subsequently passed all 101 tests serially. No tests were weakened to address these timeouts. - CI caught two integration gaps introduced during this work: missing OpenAPI entries for the new endpoints, and an attention fixture incompatible with the routine filters added on master. Both were fixed; the affected 31 OpenAPI and 40 UI tests pass. - The final revision's first CI attempt failed two untouched tests: scheduled-retry batch cancellation and the tool-access audience/archive race. Both failed jobs passed when rerun without changing the revision. Their original failed attempts remain visible in [the workflow history](https://github.com/paperclipai/paperclip/actions/runs/41083379875). - Browser evidence uses synthetic disposable data. This PR is not deployed staging or production verification. ## Risks - New attention sources must preserve canonical eligibility. Both projections call the existing collector, so they share its permissions and complete-set behavior. - The count and task-ID caches must not stand in for full decision cards. Each projection has its own key under the existing attention invalidation prefix. - A row budget can omit descendants if applied per parent. The tests cover one global budget across a large expanded tree, refresh, append, reset, and incremental loading. - Local browser evidence uses synthetic data and is not staging deployment proof. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, tool use, and code execution. The exact backend model deployment 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 (affected suites; broad-run limitations are listed 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>canary/v2026.1030.0-canary.15 |
||
|
|
ebd05e9f4c |
perf: avoid scanning unused provider pack trees during archive upload (#18340)
## Thinking Path > - Paperclip manages AI agents and their work. > - Native agents need verified provider files in remote sandboxes. > - A fresh sandbox can need the bundled provider-pack archive. > - The upload path also hashes the expanded controller tree, which it does not upload. > - That synchronous scan blocks the server event loop and delays other requests. > - This change verifies the archive source and the installed pack, and keeps source-tree checks for directory uploads. ## Linked Issues or Issue Description **What happened?** Provider-pack archive fallback scans and hashes the full expanded controller tree before reading the build archive. The archive is the source sent to the sandbox. The extra scan blocks the Node event loop for several seconds. An overlapping asynchronous operation can then appear to take as long as that scan. **Expected behavior** Verify the bytes used by the selected upload path. Keep full verification of the installed pack against the selected manifest before a provider can use it. **Steps to reproduce** 1. Use a packaged provider pack with a build archive. 2. Start a remote native run whose sandbox needs that pack. 3. Inspect `provider_pack.archive.verify` and event-loop delay on the controller. Related: #18308 adds timing detail for workspace preparation. A search found no duplicate archive-verification fix. ## What Changed - Use the verified archive without scanning the unused expanded directory. - Keep full directory verification when no archive exists or the remote lacks archive support. - Keep archive digest checks and full verification of installed bytes. - Add `provider_pack.directory.verify` for directory fallback. - Add regression cases for both archive formats, fallback, and final verification failure. ## Verification - Both archive regressions failed before the change and passed after it. - 80 focused archive, selection, and verification cases pass on the rebased branch. - 20 native manifest and admission cases pass. - Server typecheck, server build, and the runtime bundle pass. - A disposable sandbox from the recorded image exercised the real uploader and full installed-pack verifier. It accepted the unchanged build bytes and rejected an altered proxy file. No model was called. The sandbox was deleted and its absence was verified. - A local baseline/archive/archive/baseline probe used the same unchanged public build pack. Preparation took 30.673 s, 84 ms, 106 ms, and 5.371 s. The slow baseline outlier is retained. This measures one controller phase; it does not establish a whole-turn or hosted speedup. ## Risks The archive path no longer checks expanded files that it does not send. Archive checks still fail closed, and the installed files must pass the same full manifest verification. Directory fallback keeps its source-tree check. Installs without archives retain that synchronous scan. The local sandbox probe tests upload and installed-content checks; it does not qualify admission of an older pack by a newer controller. ## Model Used OpenAI Codex, GPT-6 family, with tool use and local code execution. The exact runtime 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) --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
6d61990692 |
fix: allow managed Git helpers to select a private interpreter (#18337)
## Thinking Path > - Paperclip manages AI agents and their execution environments. > - Managed Git helpers run next to those agents. > - Some environments keep their Node interpreter outside the agent PATH. > - The current generator always emits an env-based Node shebang. > - This pull request lets the environment select an absolute interpreter path. > - Existing callers keep the same default behavior. ## Linked Issues or Issue Description Refs #18212. **What happened?** A managed helper can fail when Node exists only as a private runtime binary. The caller must currently alter generated source or expose that runtime through PATH. **Expected behavior** The source generator accepts an optional interpreter path. The environment can keep its own runtime private. **Steps to reproduce** Generate a helper in an environment whose PATH has no usable Node. Run a local Git command through that helper. The env-based shebang cannot select the private interpreter. ## What Changed - Add optional `interpreterPath` to `githubLauncherSource`. - Preserve `/usr/bin/env node` when the option is absent. - Reject relative paths, whitespace and NUL bytes. - Document the option and test actual execution with an unusable Node on PATH. ## Verification - The affected adapter-utils package typecheck passed. - All 26 tests in `packages/adapter-utils/src/github-launcher.test.ts` passed. - The new test runs a generated helper as a child process. It proves that the selected interpreter bypasses a failing PATH-selected Node and that the helper body stays unchanged. - Invalid-path tests passed. Existing broker and local-Git tests passed. - Full checks run in GitHub CI per the user's request. No full local suite was run. ## Risks The option changes only the shebang. Callers own interpreter installation and immutability. Default behavior, PATH, credentials and permission policy stay unchanged. No schema or workflow changes. ## Model Used OpenAI GPT-6.1 Sol (`gpt-6.1-sol`), high reasoning, with source inspection and targeted execution. The host does not expose an exact 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>canary/v2026.1030.0-canary.14 |
||
|
|
abc270ee4c |
fix(runner): attest upstream releases and bind ACPX uniformly for every harness (#18325)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Native ACPX runs admit a provider only when its saved profile and `commandDigest` match the current profile exactly. > - For Copilot, Grok and Pi, `commandDigest` hashed dozens of Paperclip source files. Claude, Codex, Cursor and Antigravity hash only their upstream release. > - Any change to a bound source therefore advanced these profiles. #18212 alone moved Copilot from v88 to v91 and Grok from v15 to v19. Each bump reset in-flight sessions and added immutable identity fixtures (about 160 on master). > - #18237 added the provider pack `contractDigest`, which now guards Runner source compatibility at the pack boundary. > - This pull request changes the Copilot, Grok and Pi digests to upstream release attestations, as the other providers already use. > - It also binds the shared ACPX layer the same way for every ACPX harness: the profile's `acpxVersion` and the pack `contractDigest`, which now covers the Runner's ACPX patch. > - The benefit is that Runner source changes no longer reset these sessions or need new profile versions and fixtures. ## Linked Issues or Issue Description Refs #18237, #18212, #17972. **What happened?** A Runner change that touched a bound source file changed the Copilot, Grok or Pi `commandDigest`. The author had to advance the profile version, regenerate an identity fixture and keep every old fixture. On deploy, saved sessions for that provider failed the exact admission check and started fresh. **Expected behavior** A provider's `commandDigest` changes only when its upstream release changes: an upstream version, a platform closure, the ACPX patch or the Grok launcher. Runner source compatibility is the job of the pack `contractDigest`. **Steps to reproduce** 1. On master, change a comment in `src/drivers/acpx/runtime-host.ts`. 2. Run `node packages/paperclip-runner/scripts/grok-profile-identity.mjs --check`. 3. The check fails. The Grok profile must advance, and the next deploy resets Grok sessions. ## What Changed - Add `packages/paperclip-runner/scripts/acpx-release-attestations.mjs`. It computes the release attestation for each provider: - Copilot and Pi: a canonical-JSON hash of the profile version, upstream package versions and the platform closure pins (Pi also binds its Node version). - Grok: the SHA-256 of `launcher.cjs`. Admission already hashes these bytes. - The attestation binds no Paperclip source, shared ACPX layer, absolute path, pack manifest digest or install layout. - Bind the shared ACPX layer once for every ACPX harness (Claude, Codex, Copilot, Cursor, Grok, Pi, Antigravity): - Add the Runner's ACPX patch (`patches/acpx@<runner acpx version>.patch`) to the pack `contractDigest`. A patch change now retires older image packs for every harness. Other packages' ACPX patches are not read. A build context without the Runner's patch fails. - Remove the ACPX patch hash from Cursor's release declaration (`cursor-contract.json`) and advance Cursor once to profile 17. Copilot, Pi and Cursor no longer bind ACPX in their own digests, like Claude, Codex, Grok and Antigravity. - Saved inputs for every harness already must match the current `acpxVersion`. - Claude and Codex digests do not change. - `generate-acpx-profiles.mjs` writes these digests to `acpx-profiles.json`. `check:acpx-profiles` refuses a stale digest. - Move the Copilot closure pins to `copilot-closure-pins.ts`, so that the generator can import them. `copilot-installation.ts` re-exports them. - Advance each profile once and then freeze it: Copilot 92, Grok 20, Pi 37. A version change at the switch keeps the rollout on the same path as every earlier profile bump. - Replace the historical version lists in `profile-compatibility.ts` with a range. Every revision from 1 through the current one decodes. Claude and Codex still decode revisions 1 through 5. Launch and recovery admission still require the exact current profile and digest. - Delete: - `scripts/copilot-profile-identity.mjs`, `scripts/grok-profile-identity.mjs` and its test - the Grok launcher source stamp - 159 Copilot, Grok and Pi identity fixtures, including three unreferenced `copilot-mainline-v*` fixtures. The Cursor fixtures stay. - Rewrite the affected tests as behaviour checks: - Each provider admits only the exact current profile. Every earlier version decodes and is refused at admission. - The last source-bound digests, and a changed digest at the current version, are refused by recovery and by the backend factory. - The Rust Pi descriptor test uses the generated profile instead of fixtures. - New `acpx-release-attestations.test.mjs`: a relocated copy of the inputs gives the same digests, each upstream input changes only its own providers, and the generator refreshes and checks the manifest. - Remove the fixture exceptions from `.dockerignore`. Add the attestation script and the generator to the Daytona image content inputs. - Update the Pi install probe and the Rust integration constant for the new Pi digest. - Update the docs to describe the current attestation model: `doc/grok-native-runner.md`, `doc/RUNNER-INTEGRATION-PLAYBOOK.md`, `doc/observability.md`, `packages/paperclip-runner/docs/durable-recovery.md`, and the Copilot, Pi and rich ACP architecture reports. Each report now opens with the current profile identity; earlier source-bound profiles remain as dated chronology. No doc references a deleted file. ## Verification - In `packages/paperclip-runner`: - `node --test scripts/acpx-release-attestations.test.mjs scripts/contracts/contract-fingerprints.test.mjs`: 19 tests pass, including a Runner ACPX patch edit that changes the contract digest, other patch edits (including `acpx@0.12.0` for `adapter-utils`) that do not, and a build context without the patch that fails. - `node scripts/generate-acpx-profiles.mjs --check` passes. - `vitest run src/drivers/acpx src/backends src/contracts`: 1647 tests pass, 9 skipped. - `tsc -p tsconfig.json --noEmit` passes. - From the repository root, `vitest run --config tests/runner-e2e/vitest.config.ts tests/runner-e2e/daytona-image.test.ts`: 11 tests pass. - In `server`, the 8 test files that use ACPX profiles, pack digests or `contractDigest`: 1617 tests pass. - Not run locally: the Rust tests and `cargo fmt`, because this machine has no Rust toolchain. CI runs them. - Before this change, a synthetic upgrade check built two Runner revisions that differ only in shared source. A Claude checkpoint saved under the first revision rebinds under the second, and a changed Claude `commandDigest` starts fresh. This confirms that the provider JSON has no other build-dependent field. ## Risks - **One reset at rollout.** The Copilot, Grok, Pi and Cursor digests and versions change once. Saved sessions for these providers start fresh on their next run, as after any earlier profile bump. After this change, Runner source changes no longer cause this reset. - **Lost "source changed, so requalify" signal.** The old digest forced a new profile version when bound source changed. Nothing enforced requalification: Copilot was last qualified at v47. Pack-boundary contract changes are now caught by the pack `contractDigest`. - **Image packs are retired once for every provider.** Adding the ACPX patch changes the pack `contractDigest`, so the controller uploads its bundled pack (about 16 s per remote start) until images are refreshed. Claude and Codex sessions are not reset: their digests and versions do not change. - **Grok launcher and closure pins.** The Grok digest covers only the launcher bytes. Grok's runtime version is still checked separately at admission, as before. - **Grok digest equals early Grok profiles.** The launcher bytes have not changed since profile 1, so the new Grok digest equals the published profile 1 digest. The profile version still separates them: launch, recovery and the backend factory require profile 20. An image pack from that period has no `contractDigest`, so the pack gate refuses it. `remote-provider-pack-verification.test.ts` now covers this case. - **Docker context checks** run `generate-acpx-profiles.mjs --check`, which now imports `.ts` pin files through Node type stripping. `materialize-pi-distribution.mjs` already relies on this on Node 24. ## Model Used - Claude Opus 5.5 (`claude-opus-5-5`) in Claude Code, with tool use (shell, file edits, local test runs). ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
f5e5b05a33 |
Preserve native workspace recovery across Stop and sandbox reuse (#18332)
Land the thirteen-file native recovery fix independently from #18245. Retain verified Stop evidence and queued user comments. Retire stale preparation ownership atomically and require paired sandbox lease handoff receipts before workspace recovery. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
75666224d4 |
fix(native): use the deadline for remote health retries (#18324)
## Thinking Path > - Paperclip manages agent work and its execution state. > - Remote Runner processes use health reads to check their saved process identity. > - A failed health request cannot prove that the process stopped. > - Three fast gateway errors can exhaust the old retry limit in half a second. > - The caller already gives these reads a shared 30-second recovery budget. > - This pull request uses that budget with backoff for read-only failures. > - A short gateway outage can then clear without stopping the existing turn. ## Linked Issues or Issue Description **What happened?** A transient HTTP 502 during sandbox process supervision caused an active native Codex turn to fail. The probe stopped after three attempts, even when most of its 30-second budget remained. The run reported `notification_transport_failed` and required workspace recovery. **Expected behavior** Retry read-only transport failures within the existing deadline. Keep process identity conflicts authoritative. Do not repeat a signal after a lost acknowledgement. **Steps to reproduce** 1. Start a read-only process verification with a 30-second deadline. 2. Return HTTP 502 from its first three transport reads, then allow the next read to succeed. 3. The old helper rejects after three reads. The fixed helper returns the successful observation. Related repairs: #16451 introduced bounded remote probes. #16835 and #17799 require proof of process exit before replacement. This change retains those guards. ## What Changed - Use the existing absolute deadline instead of a three-attempt limit for read-only probe failures. - Back off from 250 milliseconds to two seconds. Clip each request to ten seconds or the remaining budget. - Preserve the original error and diagnostic when the deadline is exhausted. Reject non-finite deadlines before an RPC. - Add a red/green regression and a repeated-gateway-failure case around a real listening process. - Update execution semantics and both recovery maps. ## Verification - Before the fix: the new probe suite failed two behavioral assertions. The gateway case returned its HTTP 502 error instead of the later successful observation. - After the fix: 75 focused probe, diagnostic, process-supervision and adoption tests pass. The diagnostic failure tests use a controlled clock for their full 30-second budget. Their error and redaction assertions stay unchanged. - Map alignment and module-boundary checks pass. - Full workspace typecheck and build pass at final commit `ddd42f66378ebc36ec1d7e0ca1f45943473561b3`. - The broader affected suite against disposable PostgreSQL passed 994 of 997 tests; its three startup/database timeouts passed unchanged in isolation. The initial full default local run encountered embedded PostgreSQL startup failures and did not complete. The four diagnostic tests that assumed the old short retry timing now use a controlled clock without weakening their assertions. - Incident evidence came from Linux AMD64, Node 24.22.2, Core commit `0c70cedce9a803bdc201324528abb35e423e7cd0`, native Codex `gpt-6.1-sol`, and a shared ChatGPT subscription. Two separate runs recorded the same supervision HTTP 502 within one second. - A disposable live Daytona sandbox check passed on Linux x86_64 and Node 24.22.1. Three injected gateway failures recovered in 3.31 seconds on production source from `e54a355fa179022caaa6854302ff56bd85de0229` (unchanged by the final test-only commit). The real Node listening process had one launch, retained its exact identity and saved file across a second read, and produced a confirmed Stop receipt. Sandbox deletion succeeded. This is process-supervision integration evidence, not a Codex task or model execution. - Fixed-revision hosted acceptance and recovery of the original conversation require rollout. This PR does not claim either. The duration of the original provider outage remains unknown. - Final commit `ddd42f66378ebc36ec1d7e0ca1f45943473561b3`: required `ci / verify` and `ci / e2e` checks pass; Greptile is 5/5 with no inline findings. The separate Paperclip Review service has not completed an assessment and remains queued. It is not a required branch check. ## Risks - Persistent fast transport failures cause more read-only requests within the same deadline. Capped backoff limits their rate. - Missing or changed identity still returns immediately. Failed health reads still cannot authorize replacement, process signals, or provider replay. - Signal requests still have one attempt. The timeout budget and execution permissions do not change. - No schema or package changes. ## Model Used - OpenAI GPT-6, through Codex, with reasoning, repository inspection, and shell tool use. The exact deployment 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> |
||
|
|
1511c92965 |
fix(evals): account for superseded delegation wakes (#18319)
## Thinking Path > - Paperclip lets people ask agents to delegate work and return the result. > - The chat feature eval checks task creation, worker execution, saved output, and delivery to the source chat. > - A task can first belong to the CEO and then move to Morgan. > - Paperclip correctly cancels the old assignment wake before it starts. > - The eval treats that queue record as a failed provider run and stops before Morgan works. > - This change accounts for that record separately and preserves the complete outcome checks. > - The report also keeps partial check results when an attempt fails. ## Linked Issues or Issue Description **What happened?** The delegation journey stopped on an unstarted queue record with `issue_assignee_changed`. The CEO had created a task, assigned Morgan, saved the brief, and returned a task link. The test stopped before worker execution. Its report showed no individual checks even though the saved observation contained partial results. [Original public measurement](https://d1p6rlowie26tp.cloudfront.net/runner-e2e/campaigns/chat-progress-39e-112-latest-121-measurements-with-screenshots-40649033672/?view=case&case=chat-features.delegate-announcement). **Expected behavior** Keep the obsolete queue record and its events. Continue observing the intended worker. Pass only after three successful native work runs, a current Morgan-authored announcement, a completed task, automatic source-chat delivery, and browser readback. **Steps to reproduce** 1. Ask the CEO to have Morgan write and save a launch announcement, then return it to chat. 2. Create the task under the CEO, then assign Morgan before the queued CEO run starts. 3. Observe the cancelled old assignment. The previous eval aborts at that point. **Paperclip version or commit** Based on `6da112ab40d7b3cc0bcb79e08ddbb9b915a268a4` from `origin/master`. **Deployment mode** Disposable Product E2E fixtures. The live check uses the trusted default-branch workflow and AWS fleet. Related contribution: #17794 introduced these two journeys. The open-PR search found no separate fix for this queue-accounting defect. ## What Changed - Recognize only explicit dispatch-gate reassignment cancellations with a null start time and no native issue. Verify the company, prior CEO owner, and target task now assigned to Morgan before excluding that record from work-run counts. - Keep every queue record in the full observation and final ledger. Retain its events with an explicit reason for the absent provider log. - Let the feature flow own its complete saved-state and browser oracle. Return only actual work runs to the common provider checks. - Record saved-state checks on failures as well as successes. Capture the required `final-state.png` after the feature-specific browser readback. - Add two explicit local OpenCode cells alongside the two existing Codex subscription cells. Use the current production-qualified model. The earlier linked campaign used a different model, so this is a new measurement. - Advance the grader and suite versions. Keep the original request, output requirements, 120-second run cap, five-minute observation bound, budgets, and single-attempt policy. ## Verification - Red/green regressions cover queue accounting, missing-log collection, partial checks on evidence failure, and the required final screenshot. Flow tests invoke the actual polling callbacks: restoring the original callback reproduces both early-stop errors. Started cancellations still fail. - All 87 focused flow/grading/queue tests pass. Catalog/report checks and the 137 additional Node checks pass. Eval typechecking passes on final commit `0a6e11408c4470683417e6bf7965c73cec2a9a60`. - All current CI tests/builds pass. Greptile is 5/5 on the final commit, with no unresolved review threads. - The final commit adds only flow test coverage. Its registered definition digest equals live target `e4e0be875ee12c134fe8dd2ce15a88bfcbb100ef`: `ac6bba21d4b9cb86088be5d00df6442af90268186d6e94c9bea7d611d0488563`. - Replaying the original saved observation still fails for missing Morgan execution and delivery. Its stale queue record no longer counts as provider work. | Operation | Selected coverage | Observed result | | --- | --- | --- | | [41071710105](https://github.com/paperclipai/paperclip/actions/runs/41071710105), `b8dff816` | Backlog and delegation | Refused at the exact private-retention gate before fixtures or providers. Preserved without feature coverage. | | [41073708150](https://github.com/paperclipai/paperclip/actions/runs/41073708150), `39be9e45` | Backlog and delegation | Both passed their full product/browser oracles. Retained grades correctly fail missing `final-state.png`; the feature flow had saved the image under another name. Fixed in `e4e0be87`. Each original archive remains private and intact; later workflow concurrency superseded only the report aggregation. | | [41076854978](https://github.com/paperclipai/paperclip/actions/runs/41076854978), `e4e0be87` | Backlog and delegation | Backlog passed in 92.576 seconds, with a 47.388-second native run, complete required artifacts and passed cleanup. Delegation was interrupted by a runner-host shutdown at 15:19:23 UTC; all later evidence-upload steps were skipped. Its private archive is absent, so behavior, usage and cost remain unverified. | | [41080065077](https://github.com/paperclipai/paperclip/actions/runs/41080065077), `0a6e1140` | Delegation only | Passed on the final commit in 240.786 seconds. All 14 product checks plus browser readback passed; exact private identity, current worker output, Done state, correlated source-chat reply, required screenshot and cleanup verified. The three native runs took 42–60 seconds each. Passing control was not repeated. One-cell workflow and report enforcement passed. | The completed delegation in `41073708150` passed all 14 product checks plus browser readback in 222.593 seconds. Morgan saved the current two-sentence announcement, the task reached Done, and the CEO automatically delivered that saved text to the original chat. Its three successful native runs took 49.117, 40.060 and 39.107 seconds. The failed required screenshot remains a failed result in that measurement. All live operations use explicit IDs, concurrency one, no automatic retries, the unchanged 120-second per-run cap, and scoped private evidence retention bound to the exact workflow, target, original run, selector and launcher digest. These narrow measurements do not qualify the full catalog or establish repeated-run reliability. The broad local support suite passed 5,139 tests, with two skipped. Two database tests hit exhausted host semaphore capacity after the installed Postgres package's missing library symlinks were repaired. Their recheck reported `could not create semaphores: No space left on device`. No host IPC resources or kernel settings were changed. The corresponding full CI tests passed on a fresh host. ## Risks - A broad cancellation exception could hide failed work. This exception requires the dispatch gate's exact receipt, a null start time, the expected company and prior owner, and the actual reassigned task. Started and unproved cancellations still fail. Backlog creation permits no task wake. - New manual OpenCode cells can spend provider money only when explicitly selected. Default scheduled selection is unchanged. - This changes eval interpretation and evidence collection. It does not change product scheduling or task ownership. ## Model Used OpenAI Codex, GPT-6 family, with code execution and tool use. The exact model ID and context-window size are not exposed to this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [ ] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
b31ec0a2dc |
feat(ui): link routines to a filtered task list (#18317)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Routines create tasks that people need to inspect and manage. > - The routines list sends its View all runs link to Audit. > - Tasks already supports routine origin filters in its API, but the page has no control for them. > - This pull request adds a Routine tasks checkbox and links to that selection. > - People can inspect routine work in the normal task list, search, and board views. ## Linked Issues or Issue Description **What existing behavior does this improve?** The routines list link and the Tasks filters. **Current behavior** View all runs opens Audit. People cannot select routine-created tasks in the Tasks filter menu. **Proposed behavior** View all tasks opens `/issues?view=all&originKind=routine_execution`. Routine tasks is selected. People can toggle or clear it from Tasks. **Reason and benefit** People can use normal task controls to inspect work created by routines. The filter includes manually started routine runs. It excludes manual tasks and other automatic work. **Breaking changes** The routines list link changes its label and destination. No API, schema, authorization, or routine execution contract changes. ## What Changed - Add Routine tasks under Visibility in the current, streamlined, and legacy Tasks filters. Keep Live runs only in the same group and use Show agent-created tasks with proper capitalization where that control is available. - Keep the selection in the URL through reload, search, task navigation, and checkbox changes. - Apply the existing API origin filter before pagination. Include routine tasks even when other automatic tasks are hidden. - Keep source filtering in the shared task filter module and collection owners. Reuse the existing company-scoped issue-list contract. Hide the live-run control in the design sandbox, which does not load live-run IDs. - Update regression coverage, product docs, feature/access maps, and the toolbar preview. ## Verification - All 58 final-head checks are complete with no failures for `f46c2e409b20fa372d166f4721601a0471894fb0`, including successful `ci / verify` and `ci / e2e` gates. Greptile and Paperclip Review rate this commit 5/5 with no actionable findings or unresolved review threads. [CI run](https://github.com/paperclipai/paperclip/actions/runs/41078093110). - Local checks pass: full repo typecheck/build for the feature, UI typecheck/build after the final refinements, token gates, feature-map checks, and Storybook catalog generation. - Regression coverage exercises both real list implementations, filter grouping and selection, search and all board columns, URL/pagination state, and mixed pending-decision batches. The Visibility update passed all 89 relevant tests across separate runs. The final sandbox correction passes all 10 filter-menu tests, including three cases that reproduced the bug before the fix. The earlier broad UI run passed 10,043 tests across 845 files. - Browser proof used the actual local app with disposable PostgreSQL data: three tasks created through the routine-run API and one manual task. Followed View all tasks; verified the selected Routine tasks checkbox under Visibility, toggling, reload, search, and board view. Checked current, streamlined, and legacy filter presentations. Screenshots show the link, routine-only results, and requested capitalization/grouping. - Failure accounting: the initial broad UI run found two preference expectations that needed the new false default; those were corrected before the full UI pass. Scrolling tests hit five-second timeouts in combined runs and passed in isolated reruns without timeout changes. A duplicate full local UI run was stopped after the earlier final-commit CI UI lanes passed, with no failures reported in that stopped run. - Full local `pnpm test:run` could not complete because native PostgreSQL initialization exhausted the host semaphore pool. A direct initdb probe confirmed `could not create semaphores: No space left on device`. Browser verification used a disposable container; no host settings or other workspace processes were changed. - Review found that the newly exposed live-run control could empty the design sandbox, which has no live-run IDs. The sandbox now disables that unsupported control; its regression test failed before the fix and passes after it. ## Risks - Low risk. The change uses the existing routine origin and read permissions. A routine task remains automatic work, including when a person starts it manually. - The routine checkbox is exposed only on the Tasks collection. Other filter consumers retain their controls and normalize the new field to false. - Routine histories and Audit run links inside routine details keep their current behavior. ## Model Used - OpenAI GPT-6, through Codex, assisted with implementation and verification. The exact runtime model ID and context window are not exposed in this session. Capabilities used: repository editing, command execution, tests, and browser interaction. ## 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> |
||
|
|
5c807d11fa |
fix(github): prevent duplicate review score headings (#18321)
Clarify the shared GitHub review submission contract for new and existing bots. Remove copied score headings while preserving the structured score and saved assessment. Co-Authored-By: Paperclip <noreply@paperclip.ing>canary/v2026.1030.0-canary.13 |
||
|
|
59e191c368 |
Limit first onboarding to Claude and Codex (#18309)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - First onboarding helps a new user connect the first agent. > - Its provider picker currently includes GitHub Copilot. > - The first setup should offer only Claude and Codex. > - This pull request limits that picker to those two providers. > - Users can still choose other providers when they add more agents. ## Linked Issues or Issue Description **What existing behavior does this improve?** The model-source picker in first-agent onboarding. **Subsystem affected** `ui/` — the onboarding wizard and its tests. **Current behavior** First onboarding offers GitHub Copilot. It can also expose other providers when their display metadata marks them as recommended. **Proposed behavior** Show only enabled Claude and Codex choices in first onboarding. Keep their automatic native-runner routing on qualified execution environments and the silent legacy fallback on native Windows, with the same provider UI. Keep all supported providers in the later Add Agent flow. Require a visible provider choice when an old draft names a provider that is no longer offered. **Reason and benefit** Keep the first setup focused while preserving provider choice for an existing company. **Breaking changes** Old Copilot or other provider drafts require a new choice in first onboarding. Existing agents, provider APIs, and the Add Agent flow keep their current behavior. **Additional context** Related provider setup work: #15562. This change only narrows the first-onboarding picker. Searches for onboarding/Copilot and first-onboarding PRs found no duplicate change. This is a small improvement to the existing setup flow, consistent with ROADMAP.md. ## What Changed - Limit first-onboarding adapters to Claude and Codex, with existing availability checks. - Remove the Copilot tile, login card, connection state, model discovery, and creation guards from first onboarding. - Retain only migration handling for old Copilot drafts: clear the retired selection/model/flag, restore automatic runner choice, and avoid reusing GitHub bindings when the user selects Claude or Codex. This also works when both onboarding providers are disabled. - Update coverage for provider choices, disabled adapters, and old Copilot and Gemini drafts. - Clear the model when an unavailable saved provider changes to Codex. - Explain how to proceed when both first-onboarding providers are unavailable. - Update the onboarding feature and access maps. - Document the Windows fallback beside automatic runner discovery, with an explicit note to default Windows to native when its runner support is qualified. This inline migration note is an explicit requirement of the change. - Extend both providers' setup coverage for native and legacy availability without forcing a runtime from the browser. ## Verification - 282 tests passed across all onboarding component/route tests and `NewAgentDialog.test.tsx`. This includes the separate adapter-draft suite that CI identified as still expecting Copilot in first onboarding. - The existing server runner-selection suite passed: 231 tests, including native Claude/Codex runtime translation and Windows legacy fallback. This is automated routing coverage; no native Windows end-to-end run is claimed. - UI TypeScript checks and the production UI build passed. - Token gates, feature/access map validation, module-boundary checks, and `git diff --check` passed. - Reviewer command from `ui/`: `pnpm exec vitest run src/components/OnboardingWizard.test.tsx src/components/OnboardingWizard.adapters.test.tsx src/components/OnboardingWizard.step.test.tsx src/components/OnboardingWizardVariant.test.tsx src/components/NewAgentDialog.test.tsx src/lib/onboarding-route.test.ts`. - A separate browser walkthrough on staging completed the Add Agent flow with Codex and confirmed Copilot remained available. That walkthrough used an existing deployment; it does not prove this branch's first-onboarding change. - Ponytail Paperclip Review and Greptile both scored the latest commit `b470f7023ecb6657bd77edefbcaf2ab12fd89414` 5/5. All review threads are resolved. - All latest-head PR checks are complete: 55 passed and 3 neutral/skipped, with no failures or pending checks. Two server shards passed on a single retry after an unchanged timing-sensitive test exceeded its limit and a self-hosted runner lost its connection. No code or test changes were made for the retry. ## Risks - Low scope: the provider filter belongs only to the onboarding wizard. Native Windows runner support is still unmerged (#18250 is only its build/CI baseline), so automatic selection must retain the existing legacy fallback. Platform selection is based on the execution target, not the browser OS. - Users with an old draft for another provider must choose Claude or Codex. Existing agent configuration is not removed. - Instances that disable both providers have no first-onboarding choice. The wizard explains how to enable a provider or use New Agent from the Agents page. ## Model Used OpenAI GPT-6 through Codex. The exact runtime model ID and context-window size are not exposed in this session. Capabilities used: reasoning, repository edits, shell commands, and browser UI 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> |
||
|
|
fba0ab8162 | fix(runner): preserve GitHub helpers and Codex probe policy (#18212) | ||
|
|
e345b9217d |
fix(runner): paginate native task searches without hidden truncation (#18282)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Native agents search tasks to find work that already exists. > - The search schema permits 200 results, but the server returns at most 100. > - The response does not tell the agent that more results exist. > - This pull request adds pages and reports the page size and continuation cursor. > - Agents can read the full accessible inventory before they decide that a task does not exist. ## Linked Issues or Issue Description **What happened?** A native `search_tasks` request with `limit: 200` returns only 100 tasks. Historical scans recovered 167 and 173 tasks with status partitions. This proves missing inventory and extra work. It does not prove duplicate task creation. **Expected behavior** Honor the declared limit. Report more results and give the caller a continuation cursor. **Steps to reproduce** Create 205 matching tasks in a test company. Call `search_tasks` with `limit: 200`. The baseline returns 100. The fixed path returns 200, then five when the caller uses `nextCursor`. **Paperclip version or commit** Baseline: `81ebe479e8db8a3d59c86cdfb894bd917734492f`. Related changes: #16979 changes UI status filters before pagination. #13699 adds public task URLs. Neither repairs this native limit. An exact `search_tasks` plus pagination PR search returned no result. Pattern: [Task searches omit cases beyond the first hundred](https://www.braintrust.dev/app/Paperclip/p/Paperclip%20Staging/patterns/c20462d6-05fd-4862-bfbd-7bec1f2bc159). ### Hypothesis and thesis for a fix The native authority uses `boundedLimit` with its default maximum of 100. The tool schema permits 200. The response contains only `tasks`. The raw request and result counts agree with this cause. Fix the native authority and its canonical tool contract. Keep the existing `tasks` field. Add `limit`, `returnedCount`, `hasMore` and `nextCursor`. Use ascending task IDs so task activity does not move results between pages. Apply current company, privacy and Muse read checks before each page. A cursor grants no access. Callers must keep the same filters and read every page. Concurrent task changes require a fresh scan. ## What Changed - Honor the native search limit of 1 to 200, with a default of 50. - Add ID cursor pagination and page metadata. - Describe complete inventory reads in the tool contract and access map. - Refresh the generated semantic contracts and seeded catalog identity. - Add regression coverage for complete inventories and access-filtered pages. ## Verification - Red: the database integration test requested 200 of 205 persisted tasks. Baseline returned 100. - Green: the same regression returns pages of 200 and five without duplicate IDs. - The native authority and Muse suites cover company exclusion, status filters, empty pages, invalid cursors and readable-only metadata. - Command: `pnpm --filter @paperclipai/server exec vitest run src/services/native-runtime/paperclip-runner-tool-authority.test.ts src/services/native-runtime/muse-native-visibility.test.ts`. - The test uses the real run-bound native authority and disposable PostgreSQL. It does not use an external model or change a deployed scanner. - Both native authority and Muse suites pass: 71 tests. Server direct `tsc --noEmit`, Runner `typecheck:typescript`, `node scripts/check-maps.mjs` and generated semantic contract checks pass. - Full typecheck and build cannot finish here because `cargo` is absent. The full local test command was stopped after about five minutes when the complete CI matrix was running. It has no complete verdict. Current-head CI passed, including typecheck, build, all general/serialized/Runner test suites and E2E. Greptile is 5/5 with no actionable findings at `392cb7424a1fa0ec73401d5e8a10a22b504fde32`. Optional Storybook and manual Docker workflows were skipped and are not executed coverage. The success-example correction also passed all 82 contract tests locally. ## Risks Task order changes to ascending ID. Pagination is not a snapshot. New or changed tasks can require a fresh scan. Each page retains the existing full company-list read and Muse authorization cost. This change adds no database query loop or new background work. Existing callers can still read `tasks`, but must follow `nextCursor` for a complete inventory. No scanner implementation was supplied. No migration or deployment is included. ## Model Used OpenAI GPT-6 through Codex, with tool use and code execution. The exact provider deployment ID and context 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) - [ ] 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 The task requires the supplied branch to stay unchanged. All applicable CI and review checks pass at the current head. Unmerged and not deployed. --------- Co-authored-by: devinfoley <139239+devinfoley@users.noreply.github.com> Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
6da112ab40 |
perf: avoid flushing separate Git cache seed archives (#18308)
## Thinking Path > - Paperclip manages work done by AI agents. > - Native sandbox runs prepare a workspace before the agent can respond. > - A shared seed cache avoids repeated Git copies and archive preparation. > - Cache publication also flushes a branch-neutral Git seed that is separate from recovery archives. > - This cache can be rebuilt. Each reader checks the archive bytes before reuse. > - This change omits that separate cache file flush and measures the remaining preparation gaps. > - The benefit is less work before agent execution and clearer timing evidence. ## Linked Issues or Issue Description Refs #18240. **What existing behavior does this improve?** Workspace seed cache publication and latency diagnostics for native sandbox preparation. **Current behavior** Publication flushes both cache archives to disk under the company lock. Slow storage can delay the publishing run and cache readers. A cache hit also combines private copying, hashing, and last-used bookkeeping in one span. Early controller preparation has gaps before environment selection. **Proposed behavior** Keep the existing flush for recovery-backed workspace and Git archives. Omit the flush only for a separate branch-neutral Git cache archive. Reject an alternate cache file that is the recovery file or its hardlink. Keep archive checksums, private copies, atomic publication, quotas, and company locking. Measure cache read steps and the existing early preparation operations. ## What Changed - Skip the flush only for the separate branch-neutral Git seed used by the company cache. - Preserve the existing flush for recovery-backed archives, including hardlink storage. Reject cache-only files that alias recovery bytes before or during publication. - Add a regression with a blocked cache-only Git flush. The deployed code waits; the new code publishes verified cache bytes without waiting. Test storage failure for both recovery-backed archives and same-path, hardlink, and replacement alias cases. - Add cache copy, hash, and bookkeeping spans beneath seed lookup. - Add timing around existing agent, conversation, runtime, issue, identity, trust, and task context preparation. Keep their execution order. - Update the trust-order guard to recognize the timed call while continuing to assert trust resolution precedes workspace selection and credential setup. - Document the cache contract and the new spans. Keep the old flush span in the allowlist for compatibility with older observations. ## Verification - The blocked-flush regression fails on the old code and passes with this change. - Focused tests (`vitest run` on the six affected cache, timing, and native-sync suites) cover cache corruption, private-copy integrity, quota and eviction races, branch binding, per-run recovery, native workspace synchronization, trace parentage, and tracing disabled or failing. - 115 focused tests and both typechecks pass after rebase on current master. The tests include recovery storage failures and an archive replaced with a recovery hardlink during verification. - All seven trust tests pass with the actual service and migrations, using a fresh database on an existing local PostgreSQL server. The local embedded server could not allocate host semaphores, so only its test startup helper was substituted; assertions and service code were unchanged. - A real SDK export with a retained public seed verifies that cache-read detail spans have the lookup as their parent. The endpoint-off control produces no spans. - Current revision `28dea63432d462cad160906f8dfc2d21c81d3446`: all 53 checks pass, two optional checks are skipped, Greptile is 5/5, and no review threads are open. - No new staging latency claim is made by this PR. Hosted measurement remains necessary after delivery. ## Risks A crash or power loss can discard the cache-only Git seed. A later read rejects missing or corrupt cache bytes and prepares the workspace again. Recovery-backed archives retain their previous flush behavior. The change adds no flush to warm per-run persistence. Hashes and private-copy checks remain required. The new spans use the existing opt-in exporter and closed names; they record no task content. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, tool use, and code execution. The session does not expose the exact model SKU 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> |
||
|
|
65554ee596 |
refactor(adapters): remove dead vitest setup from hermes-gateway shim (#18281)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The `packages/adapters/hermes-gateway` package is a deprecated compatibility shim. It forwards to `@paperclipai/hermes-paperclip-adapter/gateway`. > - The shim carries a `vitest.config.ts` file and a `test` script. The package contains no test files. It has contained none since it was created in #8543. > - The root Vitest project list does not select this package. No workflow and no repository command runs its `test` script. The script starts Vitest with no test files, so it can only fail. > - This pull request deletes the dead Vitest config file and the broken `test` script line. The package code, its exports, and its release-manifest entry stay unchanged. > - The benefit is less dead test support and one less broken entry point in a deprecated package. ## Linked Issues or Issue Description **Current behavior** The deprecated `@paperclipai/adapter-hermes-gateway` shim has a `vitest.config.ts` file and a `test` script. The package has no test files. No CI lane and no repository command selects the package for tests. The script cannot pass, because Vitest exits with an error when it finds no test files. **Proposed behavior** Delete the unused Vitest config file. Remove the `test` script from the package manifest. Keep the published code and the release-manifest entry unchanged. **Reason and benefit** This is dead test support. It protects no contract, because no test exists in the package. The `test` script misleads a reader: it looks like a test entry point, but it always fails. The real Hermes Gateway coverage lives in `packages/adapters/hermes`, which the default test run selects. This change came out of a test-suite maintenance audit. (Refs #8543, which added the shim with this config.) **Breaking changes** None. No command, workflow, or package invokes the removed script or config. The published package code does not change. The `vitest` dev dependency stays, because pull requests may not edit the lockfile. ## What Changed - Deleted `packages/adapters/hermes-gateway/vitest.config.ts`. The package has no test files, so the config selects nothing. - Removed the `test` script from `packages/adapters/hermes-gateway/package.json`. The script ran `vitest run` with no test files and could only fail. ## Verification - Searched the repository for references to the deleted config and the removed script. The search `rg 'hermes-gateway/vitest|vitest.*hermes-gateway'` returns no match outside the lockfile. No workflow, script, or document names them. - Confirmed that the root Vitest project list (`vitest.config.ts`) and the shard runner (`scripts/run-vitest-stable.mjs`) do not select this package. - Confirmed that no open pull request changes these two files. The check read the file list of every open pull request. - Ran locally, without an install: `node --test scripts/release-package-map.test.mjs`. It passes. It asserts the shim's release-manifest entry. `node scripts/release-package-map.mjs check` also passes: "30 enabled for CI publish, 5 disabled pending bootstrap". - Parsed `packages/adapters/hermes-gateway/package.json` with Node. The JSON is valid. - Not run locally: `pnpm -r typecheck`, `pnpm test:run`, `pnpm build`. The execution workspace has no installed dependencies. The pull request CI runs these lanes against this change. ## Risks - Low risk. The deleted config file is outside the package `tsconfig.json` include list (`["src"]`), so typecheck output does not change. - If a future change adds tests to this package, it must add a test script again. The removed config held only default settings, so a new one is trivial to write. - The `vitest` dev dependency remains. Removing it would change `pnpm-lock.yaml`, which pull requests may not edit. > 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`](CONTRIBUTING.md). ## Model Used - Z.ai GLM-5.3 served through OpenRouter. Exact model ID: `z-ai/glm-5.3` (route `openrouter/z-ai/glm-5.3`). - Standard agent mode with tool use: file search, file edit, shell, and GitHub CLI in a sandboxed Linux workspace. - Context window size: not independently verified. The change did not rely on a large context. ## 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 (release-package-map tests; broad suites run in PR CI — see Verification) - [x] I have added or updated tests where applicable (not applicable: test-support deletion only; the retained release-manifest test still covers the manifest contract) - [x] I have updated relevant documentation to reflect my changes (not applicable: no document references the removed script or config) - [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 |
||
|
|
5a7a6b32ba |
fix(ui): restore compact Coordinator task loading and responder continuity (#18312)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - People open tasks from their personal workspace and send replies to agents. > - Cold task opens should load recent conversation before older history. > - Classic settings could expand history before the Coordinator preference arrived. > - Coordinator lists also read full tasks, and response startup used the previous assignee. > - This pull request restores compact reads and keeps the selected responder visible through runtime discovery. > - People can read and reply without waiting for unrelated history or losing response feedback. ## Linked Issues or Issue Description Related: #17593, #17751, #17756, #17885, #17983, and #18092. **What happened?** A cold task could select Classic full history while its personal workspace preference was pending. The full-history choice stayed cached after Coordinator became active. Coordinator Tasks used full task reads. Needs attention fetched one enriched task per pending task. Sending to a newly selected agent could show no responder, show the previous assignee, or clear feedback when assignment changed. Legacy runtime discovery then replaced the startup identity with a generic activity line. **Expected behavior** Wait for the workspace preference before selecting Classic history. Show the task instruction and recent conversation with **More messages** for older content. Read collection indexes and fetch diagnostics for visible rows. Keep the selected responder mounted from Send through saved input and runtime startup. **Steps to reproduce** 1. Enable Classic task UI and Coordinator. Delay the personal workspace preference on a cold task open. 2. Open Coordinator Tasks or its Needs attention view with many pending tasks. 3. Open a task assigned to a person. Select another agent in the composer and send a message. 4. Let the message save before runtime reads return. Then allow a legacy run to appear. ## What Changed - Wait for task interface settings before persisting Classic history expansion. - Use lightweight indexes for Coordinator Tasks. Resolve pending task IDs in batches of at most 100. Keep search and participant filters on the server. Enrich at most 50 visible rows through the existing hook without replacing list membership or order. - Preserve an error when a pending task cannot load, instead of showing a false all-clear. - Register board cards for row enrichment. Observe newly mounted cards after column expansion or pagination, and track visibility by element so hidden list rows cannot clear visible board cards with the same task ID. - Track the recipient of each submitted message through reassignment. A later draft's recipient does not change the response already starting. - Share a stable response header across startup, native runtime, and legacy runtime rendering. Keep the existing transcript renderers. - Add regression tests, production-browser checks, design guidance, and feature-map notes. ## Verification - Red/green: delayed Coordinator preference started a full comments read before the fix. It now retains compact history and still expands on request. - Red/green: sends from human or other-agent assignment showed no identity or the wrong identity. Both now retain the selected responder through assignment, acknowledgement, later draft selection, and native/legacy startup. - In a 105-task Needs attention fixture, the previous code made 105 enriched detail requests. The fixed code makes two bounded index requests. - All 659 final affected tests pass across task detail, thread, runner turn, history window, Inbox, board, row enrichment, and Coordinator collection suites. - Review follow-up: the production board lost its next-step badge before card registration. The regression now passes, along with column pagination. The focused 82-test enrichment run and 371-test header/thread run also pass. - All 12 compact-startup browser checks pass against the production UI and an isolated PostgreSQL container. They cover delayed preferences, list navigation, saved-card geometry, document/comment anchors, history expansion, draft retention, retry, and actual legacy process startup. The final deterministic process case recorded 118 frames with zero missing or replaced responder identities. It does not call a model provider. - Full workspace build and typecheck pass. Final UI build and typecheck pass after the shared-header change. Token gates, map checks, module boundaries, and diff checks pass. - The full UI rerun before the board review follow-up passed all 10,034 tests across 844 files. The 659 affected tests pass after that follow-up. The first full UI run passed 10,030 tests and timed out in one unchanged IssuesList large-tree test. Its two variants pass in an isolated rerun and in the full rerun. Those later passes establish recovery; the earlier timeout's cause remains unproven. - The full `pnpm test:run` attempt was stopped after repeated embedded PostgreSQL initialization failures in server fixtures. No complete local server-suite pass is claimed. Browser verification recovered with a disposable container database. - A later avatar browser rerun reused the previous same-title task and its cancelled run through the existing 48-hour title deduplication. That fixture never reached fresh runtime startup. The test now uses a unique title and checks its initial assignment/status; a full 12-case rerun and a second avatar run on the same instance pass. The failed trace is retained locally. - Final commit `7a18372da3` has 55 successful checks, two intentionally skipped Storybook checks, and one neutral Paperclip Review. All required verification gates are green. Greptile is 5/5 with no actionable findings or open review threads. The advisory Paperclip review paused without a complete assessment; no passing Paperclip assessment is claimed. - These checks establish bounded reads and stable rendering. No reliable staging latency benchmark or staging deployment is claimed. ## Risks - Collection projections omit task bodies. Detail navigation must retain its normal core/full task reads. Search remains server-side. - Startup feedback must end on rejection, unavailable agents, terminal outcomes, or a visible run. Existing cases cover those transitions. - The shared header changes the legacy live-turn layout to retain identity beside its existing status line. - No migration, mutation permission, provider protocol, or execution authority change. ## Model Used OpenAI Codex, GPT-6 family. The exact serving deployment ID and context-window size are not exposed in this session. The model used reasoning, code editing, shell tools, automated Chromium checks, and manual 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 (focused suites and browser checks; full-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> |
||
|
|
ac4f13d205 |
fix(e2e): report committed child blockers promptly (#18306)
## Thinking Path > - Paperclip manages AI agents and their work. > - Product E2E checks the ordinary onboarding conversation and its delivered work. > - A native run can finish successfully while its task remains blocked for a human. > - The onboarding journey kept waiting for such a child until the campaign deadline. > - This pull request reports the committed child blocker when no owned work remains pending. > - The journey still requires the same independent checks before it can pass. ## Linked Issues or Issue Description **What happened?** An approved child can stop with a committed current-track blocker owned by the board. Its native run succeeds, but the child task stays blocked. The onboarding journey reports a deadline failure instead of the observed child blocker. **Expected behavior** Report `onboarding_child_task_blocked` when the latest child run commits that blocker at the child's current status version. Keep waiting for parent dependencies and pending native or workspace recovery. **Steps to reproduce** Use the existing onboarding fixture with an approved blocked child. Give its latest native run a succeeded status, committed finalization, blocked work disposition, and the matching task status version. The old journey waits until its deadline. The new journey fails at that settled blocker without downloading or accepting any delivery. Related public context: #18298. Public issue and PR searches found no duplicate blocked-child harness fix. This change reports the failure boundary; it does not repair artifact delivery. ## What Changed - Check the owned child's board blocker after the existing run and recovery checks. - Require a unique latest producer, native committed results, and the current task status version. - Preserve parent dependency waits and all artifact, document, download, link, scope, and budget checks. - Add a behavioral regression and controls for active work, native recovery, workspace replacement, stale versions, newer producers, and agent-owned blockers. - Document the distinct failure code and the existing control-plane writers for its metadata. ## Verification - The new behavioral regression failed on the old code with `onboarding_first_task_deadline`; 147 controls passed. - The current head passed all 148 onboarding tests, including the valid agent-owner object control. - The initial implementation passed 305 tests across all 10 Product E2E files. The later update changes only writer links and the owner control; its 148 focused tests and harness typecheck also pass. - `pnpm test:e2e:runner:typecheck` passed after building the isolated checkout's workspace declarations. - `git diff --check` passed. - All required CI checks passed on `1b3bd04d193fc98d0d9f2eb3b826a4ef4bdb6dea`, including full tests and build. They were not repeated locally. Greptile reviewed that exact head at 5/5. - The full Cloud journey remains unverified by these source and CI checks. This change does not claim that the underlying artifact delivery issue is fixed. ## Risks The early failure depends on the public task and run projections. Missing, stale, or ambiguous producer metadata keeps the existing bounded wait. A pending recovery or newer producer prevents the old blocker from ending the journey. No success requirement changes. ## Model Used OpenAI Codex, exact model ID `gpt-6.1-sol`, reasoning effort `ultra`. The model used source inspection, code editing, and local test tools. The runtime did not expose its context window size. Root supplied the model and effort metadata for this agent 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> |
||
|
|
0c70cedce9 |
Wait for the saved Studio file before editing a skill (#18305)
## Thinking Path > - Paperclip lets people manage AI agents and use their saved work. > - Product E2E journeys check these user paths in classic and Cloud environments. > - The shared Skill Studio helper edits a skill created by an agent. > - Studio can mount the editor before its saved file finishes loading. > - Typing into that empty draft can replace or lose content when the file arrives. > - This change waits for the existing saved body before it starts the edit. > - Browser regressions check delayed loading and refusal to edit an unloaded file. ## Linked Issues or Issue Description Refs #18222 for the shared Product E2E journeys. No duplicate hydration fix was found. **What happened?** The shared Studio helper started typing as soon as the editor control was visible. A delayed file query could replace that draft. The helper could then lose the original content or fail to save its complete marker. **Expected behavior** The helper must load the original file before editing it. It must preserve that content, save the new marker, reload, and read the result from the task card. **Steps to reproduce** Run the controlled Studio browser fixture with a 1.5-second file load. The old helper saves the marker without the original `Verify checks.` body. With no file load, it still sends input events to the empty editor. ## What Changed - Wait for the original saved body before typing in the shared Studio helper. - Add browser checks for immediate load, delayed load, and an unavailable file. - Include these checks in the credential-free browser support suite. - Document the saved-file readiness requirement. ## Verification - Against the old helper, both new failure cases fail: the delayed case loses the original body, and the unloaded case sends 13 input events. - With the change, all three browser checks pass. They verify the saved original body and marker, reload, task-card readback, and zero input or save calls for an unloaded file. - `node node_modules/typescript/bin/tsc -p tests/runner-e2e/tsconfig.json --noEmit` passes. - `git diff --check` passes. Full repository CI passes in [41058312896](https://github.com/paperclipai/paperclip/actions/runs/41058312896), including typecheck, tests, build and all eight E2E shards. Greptile reviewed this exact head at 5/5 with no open threads. No live acceptance result is claimed by these controlled fixtures. ## Risks This adds a readiness assertion to an existing test helper. Both callers already use the same skill fixture and verify `Verify checks.` in the task card. An unavailable file now fails before an edit can occur. The change does not alter application behavior, model instructions, grading, or deadlines. ## Model Used OpenAI Codex, GPT-6 family, with reasoning and code execution. The host does not expose the exact underlying model version or context-window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have described the issue in-PR following the bug template - [x] I have not referenced internal/instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal ticket id - [x] I have run tests locally and they pass - [x] I have added tests where applicable - [x] I have updated relevant documentation - [x] I have considered and documented risks - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all reviewer comments before merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
cd5f930558 |
Add shareable image galleries to task documents (#18157)
<!-- entire-trail-link-start --> https://entire.com/gh/paperclipai/-/trails/247/changes/paperclip/247 <!-- entire-trail-link-end --> ## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Task documents hold plans, reports, and image evidence. > - Task attachments already have an image gallery. > - Inline document images had no gallery navigation or image links. > - This change gives each document a gallery that uses the existing modal. > - People can review the image sequence and share a link to one image. ## Linked Issues or Issue Description **What existing behavior does this improve?** Image review in task documents, including the side panel and Classic interface. **Current behavior** Inline document images do not open a gallery. People cannot move through them with arrow keys or share a link to one image. **Proposed behavior** Select an image to open the gallery. Use arrow keys or Previous and Next. The URL records its one-based position, for example `#document-report&image=2`. Reloading that URL opens the selected image. Revision links keep their exact saved content. **Reason and benefit** People can inspect a document's image evidence in reading order and share the exact view. No matching issue was found. The latest 300 open PR titles were checked for related document gallery work. ## What Changed - Add a document renderer that collects rendered images in reading order, including reference-style and repeated images. - Reuse the gallery modal with optional index-change and focus-return controls. - Keep the document owner in the saved tab identity when people switch between local and other-task documents. - Match explicit current-task document owners with local document tabs. Keep review and viewer parameters during gallery navigation. - Treat another Classic review receipt as a new request while image navigation retains the selected revision. - Make inline image controls work with a keyboard. Keep focus in the modal and restore focus on close. - Keep document, revision, review, and maximized-view link parameters during image navigation. - Fix a Classic revision-cache race found by the browser test. Recheck a pinned revision when the saved document head changes. - Update the feature and agent access maps. No new server API or permission is needed. ## Verification - Passed 119 focused tests for document galleries, the shared gallery, document rendering, the revision panel, and hash routing. - Passed all 3 Chromium journeys: desktop, mobile, and Classic. These use real uploads and saved document revisions. - The browser journeys also check explicit current-task owners, review parameters after reopening, other-task links after tab switches, and a second Classic review link after Return to latest. - Browser checks cover keyboard and button navigation, wraparound, shared-link reload, exact historical content, invalid positions, focus return and containment, scroll locking, and Escape, Close, and backdrop dismissal. - UI typecheck, token gates, map checks, and diff whitespace checks passed. - The UI production build passed in the browser harness. - Earlier browser runs found and then verified the Classic revision-cache fix. A later build exited 137 while the full test suite ran. The browser run passed after that suite stopped. - Full repository typecheck and build could not complete because Cargo is absent. The full repository test run did not complete within this sandbox. These checks remain subject to CI. ## Risks - Image positions follow document reading order. Editing an unpinned document can change those positions. A revision link retains the saved sequence. - The shared modal now uses Radix Escape handling. The existing gallery tests and nested mobile dialog journey pass. - No schema change or migration. ## Model Used OpenAI GPT-6 through Codex. The runtime did not expose a more specific model ID or context window size. Used reasoning, code editing, shell commands, and browser automation. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [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> |
||
|
|
2a221e8e80 |
fix(sentry): keep scheduled native model capacity retries out of run-failure reports (#18295)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - The run-failure reporter sends terminal run failures to Sentry when
an operator sets `PAPERCLIP_SENTRY_RUN_FAILURES=unexpected`
> - In `unexpected` mode, the reporter skips failures that a bounded
automatic retry already owns. The Codex ACP model capacity failure
(`codex_transient_upstream`) is one of these
> - The native runner has the same capacity failure: Codex
`serverOverloaded` ("Selected model is at capacity"). Native
finalization schedules a bounded automatic retry for it (#15347)
> - The reporter has no matching exclusion for the native path. Each
scheduled capacity retry also sends a Sentry error, even when the retry
recovers the task
> - This pull request skips the report only when the native failure has
typed capacity evidence, a committed retry decision, and the retry run
that the decision created
> - The benefit is that Sentry shows capacity failures only when
automatic recovery stops (retries are exhausted, held, or not scheduled)
## Linked Issues or Issue Description
Refs #15347 (native capacity retry). Refs #16407 (Codex ACP capacity
exclusion).
**What happened?**
A native Codex run failed with "Selected model is at capacity. Please
try a different model." (`native_provider_overloaded`). Native
finalization scheduled the automatic capacity retry. The retry run
succeeded and the task completed. The run-failure reporter still sent a
Sentry error event for the first run.
**Expected behavior**
When the automatic capacity retry owns recovery, the run failure stays
in the local run log and does not go to Sentry. This is the same as the
Codex ACP capacity path. When retries are exhausted or held, or when no
retry is scheduled, the failure goes to Sentry.
**Steps to reproduce**
1. Set `PAPERCLIP_SENTRY_RUN_FAILURES=unexpected` with a backend Sentry
DSN.
2. Run a native Codex agent turn that ends with a Codex
`serverOverloaded` terminal error.
3. See that native finalization creates a `scheduled_retry` run with
`scheduledRetryReason=native_provider_overloaded`.
4. See that Sentry also receives a run-failure event for the failed run.
## What Changed
- `server/src/services/run-failure-report.ts`: add
`isScheduledNativeCapacityRetry`. In `unexpected` mode it skips the
report only when all of these are true:
- the run is native, `failed`, has
`errorCode=native_provider_overloaded`, and has a native task
(`nativeIssueId`);
- `resultJson.nativeProviderFailure` is the closed
`codex`/`server_overloaded` diagnostic;
- `resultJson.finalizationPhase` is `committed` and
`finalizationReasonCode` is `native_provider_overloaded`;
- the report is not from setup, and the run has no signal;
- a successor run for the same task exists with `retryOfRunId=run.id`
and `scheduledRetryReason=native_provider_overloaded`. The same status
transaction creates this run.
- The successor lookup filters on `company_id`, `context_snapshot ->>
'issueId'` and `created_at >= run.createdAt`, so the existing
`heartbeat_runs_company_ctx_issue_created_idx` bounds it to that task's
runs since the failure. No migration is needed.
- A failed read of the retry evidence logs a warning and reports the
failure.
- `doc/observability.md`: document the new exclusion in the run failure
context section.
- Unit tests: the exclusion, and twelve cases that must still report
(exhausted, held, no retry run, another retry lane, successor for
another task, run with no native task, finalization not committed, wrong
or missing diagnostic, legacy run, signal, timeout). Also setup phase,
`all` mode, and an unreadable retry record.
- Integration test (real native finalizer): no Sentry event for retries
1 and 2, one event when retries are exhausted, and one event when
reassignment prevents a retry.
## Verification
- `pnpm --filter @paperclipai/server exec vitest run
src/services/__tests__/run-failure-report.test.ts
src/services/native-runtime/native-provider-overload.integration.test.ts
src/services/native-runtime/native-provider-failure.test.ts
src/services/__tests__/status-arbiter.test.ts`: 359 tests pass.
- Red/green: before the fix, the new unit test captured 2 events, and
the integration test captured an event on the first scheduled retry.
After the fix, both pass.
- `EXPLAIN` on the migrated schema: `Index Scan using
heartbeat_runs_company_ctx_issue_created_idx` with company, context
issue and created time in `Index Cond`.
- CI provides the full workspace typecheck.
## Risks
- Low risk. The change applies only in `unexpected` mode and only to
native runs with typed capacity evidence and an existing retry run.
`all` mode still reports every failure.
- The check adds one index-bounded read of `heartbeat_runs` for runs
that match the in-memory capacity checks. Other runs do not do this
read.
- If a scheduled retry later fails, that retry run reports its own
outcome. When retries are exhausted, the final failure reports.
> 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 Opus 5.5 (`claude-opus-5-5`), Anthropic. Agentic coding with
tool use (shell, file edits, test execution) and extended thinking.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
canary/v2026.1030.0-canary.12
|
||
|
|
8f50704135 |
fix(e2e): wait for pending native recovery (#18298)
## Thinking Path
> - Paperclip manages agents and their work.
> - Native runs can retain a bounded automatic recovery on the same run.
> - Product E2E observes those runs before it checks the delivered work.
> - The onboarding journey treated every failed run as a final failure,
even when the server had saved its next recovery attempt.
> - This pull request waits only for the explicit agent-owned native
recovery projection.
> - The journey still requires successful execution and the same
independent delivery checks.
## Linked Issues or Issue Description
**What happened?**
The onboarding journey can stop after a native turn completes without
its semantic result. The server marks that attempt failed and saves a
same-run retry. The journey rejects the failed row before the saved
retry is due. This also affects a native child that follows a proven
workspace deferral.
**Expected behavior**
Observe the saved automatic recovery within the original campaign
deadline and run cap. A pending recovery cannot satisfy completion.
Ordinary failures and exhausted, terminal, or board-owned recovery must
still fail.
**Steps to reproduce**
Use the existing onboarding fixture with a native failed row whose
nativePhase is retryable_failure. Give it the server-owned
native_session_interrupted cause, an agent-owned retry_scheduled
projection, a valid retry time, and attempt 1 of 3. Transition that same
row through reconnecting and running to success. The old journey rejects
the first row.
Related public context: #18292. A search of related native-recovery PRs
found no duplicate harness fix.
## What Changed
- Observe the authenticated native recovery state in the existing
workspace-deferral module. Require matching nonempty cause strings and
every owner, phase, attempt, schedule, deadline, scope, and successor
guard.
- Apply it to the proposal wait, failed native rows, workspace successor
tails, and final settlement.
- Keep defensive rejection of known permanent, permission-declined, and
exhausted causes. Diagnostic cause strings are not a positive retry
policy.
- Add behavioral recovery, deadline, and rejection controls to the
existing workflow tests.
- Document that this wait preserves the original campaign and final
delivery requirements.
## Verification
- Baseline workflow regression: 4 expected premature failures with 90
controls passing. The final structural calibration rejected 20 valid
pending-recovery cases before the correction, with 120 controls passing.
- Final regression: 140/140 pass, including existing and new diagnostic
causes on direct and workspace-successor paths. Known terminal,
ambiguous, malformed, mismatched, and exhausted states still fail.
- Focused Product E2E compatibility: 297/297 pass across 10 files.
- pnpm test:e2e:runner:typecheck: pass after building the normal SDK and
Runner TypeScript dependencies.
- git diff --check: pass.
- Final source passed these checks before the reviewed commit.
- Full repository tests/build and live Cloud acceptance were not run
locally for this harness-only change. Required CI run 41049692194 passed
on
canary/v2026.1030.0-canary.11
|
||
|
|
8035f8b245 |
test: require saved onboarding approval cards (#18292)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Product E2E tests exercise real user workflows through the browser. > - The onboarding journey requires a human to accept one proposed child task. > - A live agent tried to create the child before it saved a proposal card. The product correctly rejected that action. > - The scripted request named the required result but did not name the proposal tool or require its saved receipt. > - This pull request makes that handoff explicit. It keeps the existing human approval and independent result checks. > - The benefit is a clearer scripted workflow without a change to product authority. ## Linked Issues or Issue Description Refs #18288 and #18266. **What happened?** The agent treated the opening task request as a step toward acceptance without first saving a proposal. It then stopped after child creation was denied. Its visible response referred to a pending proposal, but no proposal card existed. **Expected behavior** The agent saves a native confirmation card, checks its receipt, and waits for the human to accept it through the browser. It must not record its own approval. Only an accepted card authorizes the child task. **Steps to reproduce** Run the scripted Cloud onboarding journey. Give the canonical onboarding task its first task request. The observed agent skipped the saved proposal and tried to create the child. Model behavior varies, so this is a fixture guidance change rather than a deterministic product defect claim. **Paperclip version or commit** Fixture base: `7a7ade4b9360aaf8e1a2808bb2b1a752c080f564`. The serving product was Core `965184d2968f40b1183803529b88f288264c832f`. **Deployment mode** Testing Cloud workspace with native Codex. This pull request selects no product release or deployment. ## What Changed - Name the existing `request_human_input` confirmation or revision-bound checkbox contract and `wake_assignee` policy in the parent request. - Require a saved pending-card receipt. Require corrections when tool arguments are rejected. - Forbid self-approval. Require the actual accepted human card decision before child creation. - Document this scripted handoff. Keep the child brief, final download links, browser actions, and all grading assertions. ## Verification - Focused onboarding and Cloud journey tests: 79 passed. - Shared evidence, campaign, and contract tests: 66 passed. - `pnpm test:e2e:runner:typecheck`: passed after building the existing workspace type dependencies. - Credential-free preview under a network-deny guard: passed with zero external calls. Its preparation plan matches the base fixture. - `git diff --check`: passed. - No prompt-string test was added. Existing tests continue to enforce approval order, child scope, independent file checks, and real result links. - Full local repository build and database suites were not repeated for this fixture text change. Required PR CI must pass before merge. - The original live result remains unchanged. This local work does not prove that a later model run will comply. ## Risks - The model can still ignore the instructions. A new real campaign must prove the workflow. - More explicit guidance makes this a scripted product journey. It is not a model discovery benchmark. - There are no product runtime, schema, credential, model, budget, or approval-policy changes. ## Model Used OpenAI Codex, exact model `gpt-6.1-sol`, ultra reasoning effort. Parent runtime metadata confirmed this model. Context window size was not reported. Used source inspection, local code execution, and an independent agent review. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (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>canary/v2026.1030.0-canary.10 |
||
|
|
7a7ade4b93 |
test: require real onboarding result links (#18288)
## Thinking Path > - Paperclip lets people assign work to agents and use their saved results. > - The Cloud onboarding journey tests this handoff through a real parent and child task. > - The child can publish a correct file while the parent names that file without linking it. > - The existing journey correctly rejects that reply because the user cannot download the named result from it. > - This pull request makes the scripted parent request explicit about real Markdown links and returned attachment paths. > - The independent artifact and parent-link checks remain unchanged. ## Linked Issues or Issue Description Refs #18266 and #18258. **What happened?** A Cloud onboarding attempt produced a correct child artifact and saved document. The parent then named the child, document key, and filename in inline code. It omitted the attachment URL. The attempt failed with `onboarding_parent_result_links_missing`. **Expected behavior** The parent's final reply must link the saved child results. The file link must use the real published attachment reference. **Steps to reproduce** Run the existing explicit Cloud onboarding journey. A reply that only names the file must remain a failure, even when the child artifact is correct. **Paperclip version or commit** The branch starts from `965184d2968f40b1183803529b88f288264c832f`. ## What Changed - Ask the parent for real Markdown links in its final reply. Use the published attachment's returned content or download path. Do not invent IDs or URLs. - Add a filename-only reply to the existing negative oracle cases. - Document this scripted fixture requirement. ## Verification - Focused onboarding tests: 79 passed. - Shared task, campaign, and contract tests: 66 passed. - Existing artifact and native-completion Node checks: 137 passed. - `git diff --check`: passed. - Harness typecheck, `pnpm -r typecheck`, and `pnpm build`: passed after building the existing workspace dependencies. The initial missing-declaration and local-IPC setup failures remain recorded. - The full local database test suite was not rerun. Required repository CI runs the broader suites on Linux. - Required repository CI passed on the exact PR head. No paid model calls or Cloud operations were run for this patch. - [Initial CI](https://github.com/paperclipai/paperclip/actions/runs/41027635545/attempts/1) failed one unchanged retention timing test (3310 ms versus the strict 3000 ms bound). The unchanged case passed once on an isolated local Postgres17 fixture. One failed-jobs-only rerun passed in [attempt 2](https://github.com/paperclipai/paperclip/actions/runs/41027635545/attempts/2). The original failure remains visible. No timing threshold or retention source changed. - The previous live attempt stays failed. Local tests do not prove that a model follows the revised request. A new bounded live attempt must establish that result. ## Risks - The extra instruction can still be ignored by a model. The unchanged oracle will reject missing links. - This changes the fixture definition hash. Historical attempts retain their original source and result. - No product runtime, API, approval policy, model profile, budget, or cleanup behavior changes. ## Model Used OpenAI `gpt-6.1-sol`, ultra reasoning, with code execution and repository tools. Model metadata was confirmed in the parent task. The context window size is not exposed. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing>canary/v2026.1030.0-canary.9 |
||
|
|
965184d296 |
fix(runner): reuse accepted confirmations on native continuation (#18283)
## Thinking Path > - Paperclip coordinates agent work and human decisions. > - Native agents receive accepted confirmations when their task resumes. > - A resumed run can repeat the original confirmation with the same key and scope. > - The interaction service rejects that replay because the source run changed. > - This PR returns the original acceptance only to its bound native continuation. > - Changed requests and newer proposals keep their existing approval gates. ## Linked Issues or Issue Description **What happened?** A native agent received a human acceptance, then repeated the same confirmation key and request. Paperclip returned a conflict because `sourceRunId` differed. The agent then used a new key and created a second pending confirmation. The task waited for another answer. **Expected behavior** An exact replay from the native run that received the accepted response returns the original accepted record. It creates no request or wake. Changed scope, another creator, an unrelated continuation, and a newer proposal must still fail. **Steps to reproduce** 1. Create a confirmation from a native run. 2. Accept it as a human. 3. Resume the same task with that accepted response in its saved native input. 4. Repeat the original confirmation key and request. Before this fix, step 4 returns `409 Interaction idempotency key already exists for a different request`. **Paperclip version or commit** Reproduced against source `81ebe479`. The deployed failure was also confirmed against Core `6a674716`. **Deployment mode** The failure occurred on Cloud. The regression uses the real native tool authority and PostgreSQL 17 with synthetic data. The full fresh Cloud journey is not yet verified with this fix. No duplicate open PR or issue was found in the related confirmation-replay and interaction-idempotency searches. ## What Changed - Let the current run's parsed, identity-bound accepted response nominate an internal replay of a plain confirmation or checkbox. Exclude governed tool, secret, connection, and quality-review cards. - Reuse the original accepted record only when the key, creator, and full normalized request match. Preserve its source run. Reject a newer confirmation. - Keep ordinary source-run comparison and mutation receipts. Recheck accepted cross-run reuse on cached calls and lost-ack recovery. An absent original cannot create a replacement. - Add real database regressions and document the replay contract. ## Verification - Real PostgreSQL regression: the original replay failed with the observed conflict, then passed. - Cached replay regressions: two controls first returned stale acceptance. Both now reject it. - Final replay and recovery suite: 27 passed. This covers both plain and checkbox confirmations, governed-payload exclusion, identity, company, request changes, newer proposals, revised plans, absent receipts, absent originals, and tool-key conflicts. - Existing native-tool and onboarding admission suites passed with the first 24 replay controls: 109 tests at `3cfd58e7`. The scope follow-up reran all 27 replay controls. - Existing interaction service and policy suites: 122 passed. - Full `pnpm build` and `pnpm -r typecheck` passed at `3cfd58e7`. After the scope follow-up, the focused 27 tests and server TypeScript check passed. Required full Linux CI passed on the final head `eabdbd6b`. - The full local Vitest suite was not repeated because the macOS embedded PostgreSQL bootstrap failure is already documented. Relevant suites used the supported external test database paths. Required Linux CI remains pending. - Final-head CI attempt 1 failed only the unchanged Antigravity login success fixture. Its implementation and test match a previous passing head. The exact failure cause is not retained. The original [failed job](https://github.com/paperclipai/paperclip/actions/runs/41014308876/job/123927423551) is preserved. The one failed-jobs-only retry request passed on the unchanged final head. This confirms recovery, not the cause of the original failure, and is separate from the Cloud journey. - Full fresh Cloud onboarding and its dependent journey remain unverified at this revision. ## Risks An approval replay must not authorize new work. The service keeps exact request and creator checks under the task lock. Newer confirmations and ordinary downstream task and target checks remain effective. Normal API callers cannot supply the internal replay nomination. No database migration or public request-schema change is included. ## Model Used OpenAI `gpt-6.1-sol`, ultra reasoning, with repository and shell tools. The parent runtime metadata supplies this model identity. The context window is not exposed. Independent review used the same model family. ## 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>nightly/v2026.1030.0-nightly.0 canary/v2026.1030.0-canary.8 |
||
|
|
81ebe479e8 |
fix(evals): bind rendered Markdown replies to saved run evidence (#18264)
## Thinking Path > - Paperclip lets people assign work to AI agents and read saved results. > - Product journeys must prove that a result is visible and belongs to the completed run. > - The shared observer compares stored Markdown with browser text. > - A document link can render as an issue chip, so those strings differ. > - This PR keeps run and comment attribution, then compares full text and exact link destinations. > - The benefit is a valid browser result without a false timeout or a weaker provenance check. ## Linked Issues or Issue Description Refs: #18248, #18255. **What happened?** The protected-action story completed both decisions and all four native turns. Its final explanation contained a document link. The browser rendered that link as an issue chip. The observer waited for raw Markdown to equal rendered text, so it could not accept the valid result. **Expected behavior** Accept complete matching content from the final run after reload. Keep the exact link destination, task anchor, author, run and durable final-message checks. Reject missing or changed content. **Steps to reproduce** 1. Save an attributed reply with bold text and a Markdown document link. 2. Render the link as an issue chip in the task bubble. 3. Run `readBoundTaskFinalReply`. The original observer times out. The new browser regression preserves that failure. ## What Changed - Add a UI-owned content projection using its existing Markdown renderer and GFM/issue-reference plugins. Keep DOM observation, attribution and destination checks in the task-reply observer. Keep source Markdown and observed text separately. - Read visible DOM text, link labels and destinations. Require the structured projection to match the actual visible text. Allow only recognized product chips to replace a link label. Ordinary links keep their source label. Reuse the production issue-reference and company-route helpers, plus the current task URL. Ordinary root-relative anchors keep their original path. Preserve exact marker checks and all run/comment/native-event attribution checks. - Check visible decline explanations and unread data in preserved native source text. - Add browser regressions and source/content tests. Reuse the UI’s existing `react-markdown` and `remark-gfm` dependencies. The final diff changes no package manifest or lockfile. - Match generated GFM checkbox states and reject changed states. Document supported content and fail-closed behavior. ## Verification - Original observer: the decorated-link browser regression fails at the final-reply predicate. - Fixed observer: all 21 browser regressions pass, without credentials or model calls. - Focused observer, decline, content and journey contract suites: 64 tests pass. - E2E and UI TypeScript checks pass. All UI token gates pass. The unchanged frozen install passes. - Full CI passed on the preceding |
||
|
|
fa760dbce4 |
fix(runner): reuse image packs only with matching contract digest (#18237)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Remote native runs use a provider pack. The controller reuses a protected pack from the sandbox image when the pack is compatible. > - #17749 gates this reuse on a hand-maintained interface revision in `provider-pack-contract.json`. > - Later changes altered the runner/pack boundary (#17922, #18188), but nobody bumped the revision. A stale Claude or Codex image pack can still be reused across a sidecar contract change. This is the failure class of #17972. > - A manual revision has a "forgot to bump" failure mode. Source-byte hashes change on every refactor, so they are too brittle. > - This pull request declares the sidecar `session.open` contract in its JSON schema and computes a contract digest from the JSON contracts and Rust shapes. > - Image-pack reuse now requires an equal digest. > - The benefit is that an incidental change keeps image packs reusable, and a real contract change retires them automatically. ## Linked Issues or Issue Description Refs #17749, #17972, #17922, #18188. **What happened?** The controller reused an image provider pack when `compatibility.acpx` and the selected agent's profile digest matched. For Claude and Codex, that profile digest binds only the upstream executable. The ACPX interface revision stayed at 1 after later sidecar contract changes. A pack built before those changes passed the reuse check. **Expected behavior** The controller reuses an image pack only when the pack uses the same runner/pack contracts as the controller's bundled pack. Comments, formatting and refactors do not change that result. **Steps to reproduce** 1. Build an image pack from a commit before a sidecar input change, such as a new `session.open` field. 2. Run a controller from a later commit that sends the new field, with the same interface revision and Claude version. 3. Before this fix, `verifyRemoteProviderPack` accepts the old image pack. ## What Changed - Declare the sidecar `session.open` parameter set as a closed `sessionOpenParams` definition in `acpx-sidecar.schema.json`. - `generate-acpx-sidecar-contract.mjs` now generates `GENERATED_ACPX_SIDECAR_OPEN_PARAMS` from it. - `parseOpenParams` uses the generated list instead of an inline `Set`. The accepted set is unchanged. - This is the surface of #17972. The schema is now its source of truth. - Declare the nested `session.open` contracts that the sidecar parses strictly: - `protocol/provider-schemas/runtime-context.schema.json` closes every runtime context object. `parseNativeRuntimeContext` uses the field lists that `scripts/generate-runtime-context-contract.mjs` generates from it. - The sidecar schema declares the closed `providerPolicy` object, and `parseProviderPolicy` uses its generated field list. - The accepted fields do not change. - Add `packages/paperclip-runner/scripts/contracts/contract-fingerprints.mjs`. It fingerprints these contracts: - the PRP and sidecar JSON schemas, with annotation text removed - the generated catalogs in `generated/` - the Rust serde shapes, `json!` payload keys, match literals and env keys in `runner-core/src`, without test-only modules - the reserved env key lists in `configured_environment.rs` - Read only the trees that every pack build context contains. Fail when a registered source is missing, so two build contexts cannot silently produce different digests. - Use only Node built-ins. The registry adds no dependency. - Write `contractDigest` as a top-level payload field in `build-provider-pack.mjs`. The manifest digest algorithm and the existing field layout do not change. - Require an equal `contractDigest` for image-pack reuse in `remote-provider-pack-verification.ts`. A pack without a digest is not reused. The controller uploads its bundled pack, as it does today for any incompatible pack. - Re-attest the source-hashed profiles, because this PR changes their bound sidecar sources: - Grok becomes profile 15 and now also binds the generated allowlist, so a Grok field change in the schema still invalidates the Grok identity. - Copilot becomes profile 88, and also binds the generated runtime context fields. - Earlier profiles stay decodable. - Add the registry script and `generated/` to the Daytona image content inputs. - Document the digest and the schema-first rule in `docker/daytona-runner/README.md` and `doc/DEVELOPING.md`. ## Verification - `node --test scripts/contracts/contract-fingerprints.test.mjs` (in `packages/paperclip-runner`): 4 tests pass. - These changes keep the digest: - schema description text - schema reformatting - renaming `parseOpenParams` - Rust comments, `#[serde(skip)]` fields and `#[cfg(test)]` modules - edits to the `#[path]` test module `tests/provider_api_validation.rs` - These changes alter the digest: - a new `session.open` schema field - a changed constraint on the `remainingWork[].description` property - a new reserved env key - a new sidecar env key - a new checkpoint field - A build context without a registered source fails. - `node --test test/acpx-sidecar-contract.test.mjs`: 13 tests pass. A new case rejects an unknown `session.open` parameter and accepts each declared parameter. - `node --test scripts/grok-profile-identity.test.mjs`: 4 tests pass. A change to the Grok field in the generated allowlist invalidates the Grok identity. - `generate-acpx-profiles.mjs --check`, `generate-acpx-sidecar-contract.mjs --check` and `generate-protocol-manifest.mjs --check` pass. - Runner vitest suites pass: 470 passed, 1 skipped. They cover the sidecar, sidecar input and protocol, Copilot and Pi installation, profile compatibility, native execution, recovery identity, the backend factory and the environment. - Server tests: pack verification, executor and artifact preparation pass (1,004 tests). - `tsc --noEmit` passes for `packages/paperclip-runner` and `server`. - `tests/runner-e2e/daytona-image.test.ts`: 10 of 11 tests pass. The failing test also fails on `master`. It expects a literal `profile-v19-identity.json` line in `.dockerignore`, which uses a `profile-v*` glob. - Not run locally: - A complete `build-provider-pack.mjs` run. The builder rejects the local Homebrew Node because it is not portable after relocation. - Rust tests and `acpx-controller-recovery.test.ts`, because `cargo` is not installed. - The full `pnpm -r typecheck`, `pnpm test:run` and `pnpm build`. ## Risks - Only JSON contracts and Rust shapes are part of the digest. The remaining TypeScript-only definitions are the `paperclip_finish` and `paperclip_block` tool schemas in `completion-result.ts` and the TypeScript env key lists. They are not covered until they move into a schema. The nested `expectedIdentity` and `tools` values ignore unknown fields, so a change there cannot cause a startup rejection. - A change there can let a stale image pack be reused. The sidecar then rejects the input with its strict parser error. - Today, Claude and Codex image packs have no contract check at all. - The digest covers all registered contracts for the whole pack. A contract change for one provider kind also retires image packs for the other. Each replacement costs about 16 s per remote start until the image is refreshed. - Existing image packs have no digest. After deploy, the controller uploads its bundled pack until the image is rebuilt. - The Grok and Copilot re-attestations start fresh sessions for those agents once after deploy, as each profile bump does today. - The Daytona image content ID formula changes, so the next image build does not reuse a cached image. > 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 Anthropic Claude Opus 5.5 (`claude-opus-5-5`) through Claude Code in the desktop app, with repository tools, shell execution and research subagents. The session does not expose the context window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [ ] 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: Claude Opus 5.5 <noreply@anthropic.com>canary/v2026.1030.0-canary.7 |
||
|
|
145214201d |
test: preserve the onboarding child brief at delegation (#18266)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Product E2E journeys check onboarding through the real app. > - The onboarding story asks a parent agent to delegate a file and document task. > - A parent can preserve the goal but omit the exact tool instructions from its child description. > - The child can then publish a note instead of the required JSON file and task document. > - This pull request asks the parent to copy the full child brief without changing it. > - The existing independent checks still decide whether the result passes. ## Linked Issues or Issue Description Refs #18258. Includes merged prerequisite #18270 for the existing retention scheduling failure found by required CI. **What happened?** The scripted onboarding request gave the parent an ordered tool recipe. It did not require the parent to keep that recipe in the child description. A delegated child could compute the result but publish a Markdown note and omit the Paperclip task document. **Expected behavior** The child receives the full approved brief. It must publish `connection-proof.json`, save its Paperclip task document with the returned file link, and report completion through the current contract. **Steps to reproduce** Run the explicit Cloud onboarding journey. Inspect the approved child description and its published result when the parent summarizes the request. **Paperclip version or commit** This change is based on public master `b3c2172d417ea6b783e0c796aaed4a91e1f9d381`. **Deployment mode** Scripted Product E2E against a live Cloud testing workspace. ## What Changed - Put the existing ordered instructions in one marked child brief. - Require the parent to copy that brief verbatim into `create_task.description`. - State the exact JSON filename and workspace-relative content reference for `register_deliverable`. - State that a Markdown workspace note does not replace the `write_document` step. - Document this scripted scope in the Product journey guide. ## Verification - Existing focused Product journey tests: 227 passed in 10 files. - Credential-free Product journey discovery passed through the direct tsx loader. - Source comparison confirms that all code after the opening reply is unchanged. The download, calculation, hash, provenance, document, parent-link, approval and run-limit checks retain their original behavior. - No prompt word-matching tests were added. This is an instruction-only change. - `pnpm build`, `pnpm -r typecheck`, and `pnpm test:e2e:runner:typecheck` passed. - Full support Vitest check: 5,042 passed, 2 skipped, 2 failed. Both failures occur during embedded PostgreSQL startup in the controller database lifecycle fixtures. The log includes a missing bundled `libzstd.1.dylib`. The separate Node support checks passed all 137 tests. - `pnpm test:run` was attempted. It reached the general server suite and repeated embedded PostgreSQL startup failures. I stopped only this owned local test process group. The full local test command is incomplete. Required Linux CI remains the merge gate. - The first harness typecheck ran before workspace build outputs existed and reported missing workspace modules. It passed after the full build. The earlier failure remains recorded. - The initial CLI discovery wrapper hit a local tsx IPC permission error. The direct loader passed with the same source and arguments. - The original required CI run found an existing skill-retention page delay. Its unchanged test passed once against a dedicated local PostgreSQL fixture. Separate PR #18270 added a deterministic regression and fixed the scheduler. After that PR merged, this branch received one normal merge from master. Its diff remains two fixture files. The original failed CI run remains preserved. - After the branch refresh, all 70 onboarding first-task tests and 7 retention/deadline controls passed. Harness typecheck passed. Fresh required CI and review passed on head `608e266c6567c19981fd3f8a07305c785346753b`. - The refreshed CI run passed the retention shard but failed one unchanged Antigravity authentication fixture. The same Runner lane passed on the prior fixture head and the merged prerequisite. The exact test passed once locally. Source review identified a possible stdout/stderr ordering race, but the failed run did not retain its exact error subtype. The one approved retry of the failed CI job and its verification aggregate passed on unchanged source. The original failure remains preserved. This proves recovery, not its cause. - The live Cloud journey has not been rerun with this source. Historical failed attempts retain their original results. ## Risks - An agent can still fail to follow the brief. Existing independent assertions will reject the wrong file or missing task document. - The fixture definition changes. A later live attempt must record this new harness revision. - No application, model, effort, budget, cleanup or acceptance rule changes. ## Model Used - OpenAI `gpt-6.1-sol`, ultra reasoning effort, with repository tools and code execution. The parent verified this model ID from current runtime metadata. The context window size is not exposed. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
7df1656dda |
fix(server): continue retention pages after overdue grace deadlines (#18270)
## Thinking Path > - Paperclip manages AI agents and their shared work. > - Skill snapshots need safe cleanup after their retention grace period. > - The retention worker scans large directories in pages. > - Another company's grace deadline can expire while a page is still running. > - The shared deadline helper then uses the worker's 30-second failure retry for successful continuation. > - This pull request gives this worker a one-second continuation delay. > - Directory scans keep moving while failure retries retain their existing delay. ## Linked Issues or Issue Description Refs #18266. Its unrelated fixture checks exposed this scheduling bug. **What happened?** A successful directory page can wait 30 seconds before the next page when another company's grace deadline becomes overdue during the scan. **Expected behavior** Continue successful paging within one second. Process the overdue company. Stop scheduling when all work settles. Keep the existing 30-second failure retry. **Steps to reproduce** Hold the second successful page with a deferred promise. Advance the fake clock past another company's saved five-second deadline. Release the page. Before this fix, the next wake is still 25 seconds away. The regression also requires all pages, the overdue rescan, and an idle worker after settlement. **Paperclip version or commit** Reproduced on `b3c2172d417ea6b783e0c796aaed4a91e1f9d381`. **Deployment mode** Core retention worker. The deterministic test uses the real coordinator, deadline helper, and retention worker with controlled service results. It needs no external database or provider. ## What Changed - Set `continuationMs: 1000` on the skill retention worker. - Add a controlled regression for a grace deadline that expires during a successful page. - Keep the shared deadline helper and the worker's failure retry unchanged. ## Verification - Red: the new regression fails on unchanged production code with a 25,000 ms remaining delay. The existing control passes. - Green: retention worker, deadline worker, and scoped deadline worker suites pass: 7 tests. - `pnpm build` and `pnpm -r typecheck` pass. All required checks pass on the current head. Greptile reports 5/5 with no review threads. - The full local test suite is not complete. The bundled macOS PostgreSQL runtime lacks `libzstd.1.dylib`, as confirmed in the existing host diagnostic. The deterministic worker tests do not need PostgreSQL. Full repository tests must pass in CI. - No live Cloud, provider, model, or deployment test is selected. ## Risks Successful overdue continuation can run sooner. The existing one-second page interval still applies. The test requires the remaining pages, the overdue rescan, and no more work after settlement. Failure retry remains 30 seconds. This change adds no schema, API, or product command. ## Model Used OpenAI `gpt-6.1-sol`, ultra reasoning, through Codex. Parent runtime metadata confirms this model. The context window is not exposed. Terminal tools assisted source review and testing. A separate agent reviewed the source and regression. ## 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>canary/v2026.1030.0-canary.6 |
||
|
|
b3c2172d41 |
fix(evals): verify native protected-action outcomes (#18255)
## Thinking Path > - Paperclip manages work assigned to agents. > - Product E2E stories ask for useful user-facing results. > - Classic runner and deployed QA reuse the same service approve/decline task prompts. > - The service returns a receipt marker that belongs in a saved briefing document. > - State that destination explicitly and ask for the document link when complete. > - The deployed decline path also needs the same durable final-reply proof as Plan and Stop. ## Linked Issues or Issue Description Refs #18222. Builds on the merged reply observer in #18248. **What happened?** The shared service tasks ask for titles and a “verification code” without specifying that the code belongs in the document or asking for its final link. A native QA attempt created its briefing but then repeatedly failed the completion tool’s array validation. Those invalid arguments remain a separate observed failure; the wording change does not establish their cause or relax validation. Source inspection also found that the declined-action oracle requires a projected comment even when the settled native thread renders a durable final message. **Expected behavior** Ask for page titles and the service receipt code in the saved briefing, then a document link. After a declined action, require the existing explanation-only fallback without another service call. **Steps to reproduce** Run the shared service-approve/service-decline stories through the classic runner or QA Product E2E adapter. ## What Changed - Clarify the natural-language task for both shared service stories: put page titles and service receipt code in the document and provide its link. - Use the reloaded run-bound final reply for QA service declines. Pass an explicit native receipt to the existing decline oracle; do not synthesize issue comments. Require the final native run to start after the saved decline and keep exact decision, truthful explanation, no unread marker, zero calls and unchanged connection checks. - Keep classic callers on their existing attributed-comment path. No internal tool instructions are added to the user prompt; ownership, service data and model/runtime limits stay strict. ## Verification - Decline regression observed RED: two cases reject a valid saved native explanation without projected comments. After the repair, 79 focused tests passed across native reply, decline guidance, agent evidence and journey contracts. A two-successful-run control rejects the earlier receipt and accepts the later one. Negatives cover stale/wrong run, wrong agent/task, missing final proof, summary/unsettled/hidden output, false explanations and unread service data. - Product E2E TypeScript and `git diff --check` passed. - Live protected-action qualification is required after merging this and the companion private service/cleanup fixes. The previous failed result remains failed; this is a bounded task-clarity experiment, not a claimed model or completion-schema repair. - Current-head Greptile and Paperclip reviews are 5/5 with zero open threads. CI initially failed the unrelated agent-chat-projects cleanup POST with a PostgreSQL lock timeout after its assertions completed. One bounded retry passed on unchanged source; all current-head gates passed at `64bc169e147290ed4dbaa18221e0268362ce81ee`. The original failing attempt and its logs remain available. The task-clarity change is still a bounded experiment; the observer repair addresses a demonstrated storage-assumption defect. ## Risks A clearer task can still fail with the selected model. All acceptance checks and completion input validation remain strict; a saved briefing alone cannot qualify the complete journey. Only test prompts and test evidence code change. Missing or contradictory native evidence fails closed. ## Model Used OpenAI Codex, GPT-6 family. The exact serving model ID and context window are not exposed by this session. Used reasoning, source editing, shell execution and test 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>canary/v2026.1030.0-canary.5 |
||
|
|
59b76777db |
test: clarify onboarding artifact completion instructions (#18258)
## Thinking Path > - Paperclip helps people manage AI agents and inspect their work. > - Product E2E journeys test that work through normal browser and API controls. > - The Cloud onboarding journey asks one native child to publish a file and save a document. > - Its task request did not explain the completion report format or make each output step distinct. > - A live attempt published the file, then submitted an invalid finish report and declared a blocker. > - This change orders the scripted request and explains the existing completion contract. > - The agent must still produce the result and pass the same independent checks. ## Linked Issues or Issue Description Refs #17940. Refs #18228. **What happened?** The scripted onboarding request left completion details implicit. A live child published its proof file, then submitted a finish payload without verification and with an invalid schema value. Its later blocked report also listed local paths as artifacts. This does not establish a Core validator defect. **Expected behavior** The request should explain the existing tool contract. The child must publish the file, save the document with its returned link, then submit a valid completion report. Argument correction must not replace artifact verification or bypass approval. **Steps to reproduce** Run the explicit Cloud onboarding Product E2E journey through its private target provider. Approve the proposed child through the UI. Inspect the native finish report and the independently checked attachment, document, and parent links. **Paperclip version or commit** The observed deployment used public Core `6a674716447e8fa268c5cdeb1db1020319368a77`. This fixture change starts from `a8e07500db68f187b19de83823eb7fabf1196021`. **Deployment mode** Cloud testing with the scripted Product E2E harness. ## What Changed - Order the child request: create files, publish the proof, save its document, then finish. - Require verification for actual checks and omit the optional schema field. - Explain receipt-derived references in evidence and file artifacts. Keep local input paths in verification details. - Document same-attempt argument correction and preserve historical failed results. ## Verification - Existing onboarding-first-task and artifact-evidence suites: 83 checks passed. - The maintained harness unit wrapper also passed 137 Node contract checks. - Independent source review found no contract, privacy, or oracle change. - Full `pnpm build` and `pnpm -r typecheck` passed at the preceding commit `c3900cf2`. The only later change names the filename required by the existing document assertion. - Current `d75180b4`: the 83 fixture/artifact checks, 137 contract checks, and `pnpm test:e2e:runner:typecheck` passed again. - Credential-free `--list --suite product-journeys` passed. - The local full repository Vitest run at `c3900cf2` was stopped before the filename correction. It is incomplete and is not reported as a pass. Current-head CI passed: 54 successful checks and two optional Storybook skips. The separate advisory review is still running and is not reported as passed. Initial fresh-worktree dependency and sandbox IPC failures remain recorded. - No paid model, Cloud workspace, release, or deployment was run for this change. These checks establish harness compatibility, not a live model pass. The prior failed campaign remains failed. ## Risks The model may still submit an invalid report or fail another step. A fresh live journey is required to measure the instruction change. This PR changes fixture text and documentation only. It supplies no result, checksum, real attachment ID, or successful status. Models, limits, validators, and independent assertions stay the same. ## Model Used OpenAI Codex, `gpt-6.1-sol`, ultra reasoning. The model identity comes from confirmed parent runtime metadata. Context window size is unavailable. Tools and code execution assisted the change and review. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (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>canary/v2026.1030.0-canary.4 |
||
|
|
2badf8a4a5 |
fix(evals): verify native QA replies on the reloaded task thread (#18248)
## Thinking Path > - Paperclip manages AI agents that do work for users. > - Product E2E journeys check user outcomes on real deployments. > - Native task threads can render saved final replies from a settled run. > - The new QA Plan and Stop checks looked only for agent comments. > - Both flows reached the requested terminal state and showed the correct reply, but that storage assumption rejected them. > - This PR checks the reloaded visible reply and binds it to the final successful run. Explicit presentation decisions remain authoritative. ## Linked Issues or Issue Description Refs #18222 and #18244. **What happened?** The deployed Plan journey completed all three native runs, including revision and approval. Stop completed native cancellation, resource release and a new direction. Their final-answer checks failed because the comments endpoint did not contain the rendered native reply. The original failed grades remain unchanged. **Expected behavior** Require exactly one correct visible final answer after reload, attributed to the final successful owned run. Reject an earlier run, progress text, hidden content, duplicate answers or a cancelled run. If its selected completion comment is projected, require that comment and matching author/run/text. Otherwise require a single durable final assistant message and its settled native final-response anchor. **Steps to reproduce** Run the Plan or Stop journey on a native deployment whose task thread renders the settled run before a completion comment is projected. ## What Changed - Add a narrow reply observer over the existing task-thread hooks. It reloads the page and refreshes saved run/comment metadata while waiting. - Bind native replies to a validated durable final assistant event and the successful run's settled final-response anchor. Require the selected comment when projected; support pending or suppressed projection without accepting a summary fallback. Accept payload and item-normalized finals, rejecting contradictory fields. - Use the observer for Plan completion and Stop's new direction. Keep existing run counts, deployment binding, cancellation and artifact checks. - Add negative grading tests, include the helper in the definition hash, and document its evidence contract. Classic protocol comment matchers are unchanged. ## Verification - 63 focused tests passed across native reply evidence, agent evidence and journey contracts. - Product E2E TypeScript passed. The reply observer uses the remaining journey deadline and backs off polling. - Live Plan and Stop attempts exposed this grading failure. Their original outcomes remain failed; fresh qualification is required after merge. - Full current-head CI passed at `40840ed742977853630d733292461ad7003fc7fb`; Greptile and Paperclip Review both scored 5/5, with zero unresolved review threads. ## Risks The observer depends on existing task-thread test hooks and run anchors. Missing or changed hooks fail closed. It reads rendered user-facing text; a finish summary alone cannot satisfy it. Native event provenance, run ownership and exact reply equality are required. No backend, model, provider, budget or cancellation policy changes are included. ## Model Used OpenAI Codex, GPT-6 family. The exact serving model ID and context window are not exposed by this session. Used reasoning, source editing, shell execution and test 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> |
||
|
|
a8e07500db | fix(runner): preserve runtime activity through the native bridge (#18239) canary/v2026.1030.0-canary.3 | ||
|
|
8941db9ce6 |
fix(evals): accept editor escapes and cancel sensitive QA requests (#18244)
## Thinking Path > - Paperclip manages AI agents that do work for users. > - Product E2E journeys check real browser actions and saved results. > - A rich editor can store plain underscores as escaped Markdown. > - The QA reply check treated that valid saved message as a failure. > - A private target adapter also needs to cancel credential-safe HTTP requests before cleanup. > - This PR fixes reply comparison and adds abort and timeout options to the existing sensitive transport. ## Linked Issues or Issue Description Refs #18222. **What happened?** The artifact revision and Stop journeys rejected the correct single user reply because its underscore was stored as `\_`. Sensitive connection setup also lacked a way to pass its lifecycle signal to the actual HTTP request. **Expected behavior** The check accepts the editor's underscore escape and still rejects changed, duplicate, missing, or foreign replies. A cancelled sensitive request closes before setup cleanup proceeds. **Steps to reproduce** Run an artifact revision with an underscore in the reply. For the transport case, abort a pending sensitive request or let its deadline expire. ## What Changed - Compare the fixture reply after undoing only underscore escaping. Keep exact text, count, and author checks. - Let `ConnectionApi.postSensitive` accept a bounded timeout and abort signal. Check cancellation again after cookie loading and before dispatch. - Test the retained reply failure and both cancellation paths with an actual loopback HTTP server. Document the adapter contract. ## Verification - Focused Product E2E tests: 30 passed across two files. - Product E2E TypeScript check passed. After rebase, a final check first found four diagnostics from stale runner/plugin SDK declarations; rebuilding those two workspace packages cleared all four, and the unchanged E2E check passed. - The first sandbox run failed because loopback `listen` returned `EPERM`. The unchanged HTTP tests passed with loopback permission. The test now reports listener errors directly. - Both independent reviewers found a possible pre-arrival deadline-test hang. The follow-up races arrival against request settlement and adds one second of deadline headroom. All 30 affected tests passed after that fix. - Full current-head CI passed in run 40982914525. Greptile and Paperclip Review both scored 5/5 at `f0526f5fbbf13de5ea43e868eb012069ca3d8907`; all review threads are resolved. Live QA requalification follows the merged public and private fixes; no live pass is claimed here. ## Risks The text normalization applies only to plain fixture replies and only removes underscore escapes. It does not remove arbitrary Markdown. Sensitive calls retain their existing 30-second default and closed error messages. API wrappers must forward the optional signal and await the actual request. ## Model Used OpenAI Codex, GPT-6 family. The serving model ID and context window are not exposed by this session. Used reasoning, code editing, shell execution, and test 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>canary/v2026.1030.0-canary.2 |
||
|
|
ed8fae8dbb |
fix(workspaces): preserve completed shallow sandbox exports (#18221)
## Thinking Path > - Paperclip coordinates agent work and preserves its results. > - Remote execution copies completed workspace changes back to the host. > - An agent can fetch a published branch with shallow Git history. > - A full Git bundle omits the shallow boundary metadata and can fail host connectivity checks. > - This pull request carries the boundaries through the full-bundle fallback and imports through normal Git fetch. > - Recovery must also recognize completed native work on a reusable lease without treating it as ordinary executor reuse. > - Completed work can be saved without another provider turn, while existing host history remains connected. ## Linked Issues or Issue Description **What happened?** Sandbox finalization can fail with a missing parent commit after an agent checks out a separately fetched shallow branch. Re-exporting a full bundle repeats the failure because Git bundles do not encode shallow boundaries. **Expected behavior** Import the completed branch and saved files. Preserve existing host ancestry and concurrent host edits. Keep normal Git connectivity and workspace merge checks. **Steps to reproduce** 1. Prepare a sandbox from one host commit. 2. Fetch a different published branch with depth one and check it out. 3. Save a result file and restore the sandbox workspace. **Paperclip version or commit** Reproduced against master before this repair. The regression fails with the missing-parent error before the production change. Related public context: #15268 covers rewritten history integration. This repair handles shallow bundle transport before integration. Searches found no equivalent open repair. ## What Changed - Export shallow boundaries beside the full bundle when the delta import lacks history. - Unpack into a temporary shared bare repository. Keep parent connections already available on the host and import with Git's shallow fetch protocol. - Reject malformed boundary values and retain existing connectivity, branch, and concurrent-work merge guards. Keep boundary probes within 15 seconds without consuming the separate 60-second Git import budget. - Let source-bound preservation recover reusable leases only for the finalizer-selected, accepted successful native result and matching completion contract. Retain provider-stop, physical ownership and host-writer checks; ordinary reusable sources remain blocked. - Classify invalid Git metadata separately from omittable unsafe archives. Keep native finalization failed and preserve service-owned file recovery; carry the sender's dedicated rejection across the command boundary without transient retries. - Share the failure allowlist across bounded run/activity projections and cancelled-preservation selection. Migration `0416` rebuilds the matching partial index; task chat retains the non-retryable recovery notice. - Add real Git, filesystem sandbox and database recovery regressions. Update execution semantics and affected verification maps. ## Verification - Red: real filesystem sandbox restore failed with the same missing-parent/revision-walk error before the export repair. - Green: 240 focused Git, workspace restore, sandbox transport and native-finalization tests pass. Coverage includes both transfer paths, malformed/oversized metadata, a genuinely shallow host with its original boundary intact, and concurrent host work with both merge parents verified. - Red/green: a 14-second simulated probe left the final real Git fetch only 45,893 ms before the budget split. It now retains over 55 seconds after the probes; a 16-second probe exhausts its own budget before host import. - Red/green: an oversized read progress report was retried three times before its distinct metadata classification. It now aborts the first read before payload consumption, leaves the host tip unchanged and does not retry. - Red/green: the real metadata error was swallowed by best-effort export and native finalization incorrectly returned success. Both regressions now pass; all 240 focused Git/restore/native-finalization tests pass. A PostgreSQL/filesystem fault-injection test also verifies retained files, failed run, service-owned recovery barrier, no preservation receipt and no new wake. - Red/green: duplicate metadata produced 47 Git process starts before deduplication; the bounded-work regression now passes. Oversized byte and boundary inputs fail before Git probes. - Recovery red: both reusable lease policies exhausted recovery despite a selected accepted successful result. The assembled PostgreSQL/filesystem path now passes for retained and both reusable policies, including idempotent re-admission after exhausted automatic recovery, saved files, no agent wake, and once-only existing-result finalization. - Source verification controls reject ordinary reusable leases, rejected/failed/unselected results, another physical allocation owner, and an active host writer without changing recorded state. - The 78-test PostgreSQL/filesystem recovery/source suite passed before the metadata classification correction. Its new persisted metadata-failure regression also passes. Full workspace typecheck and build pass at final head `69f10daab2`. - `node scripts/check-maps.mjs` and `git diff --check` pass. - Full local `pnpm test:run` attempts did not finish. They are not counted as passes. Early focused runs exceeded 5-second and 30-second fixture deadlines; the final serial suite passed all 176 tests with a 30-second per-test budget in 56.8 seconds. - Red/green: both bounded PostgreSQL projections dropped the new code in oversized results. All 19 source/projection cases now pass, plus an actual index-predicate test that excludes a metadata repair hold and still selects ordinary cancelled work. - Red/green: an oversized sender `.git/shallow` lost its error type before host validation. The real transport test now verifies one typed rejection, no shallow-payload read, and an unchanged host tip. All 465 command/sandbox/task-chat tests pass, and token/migration gates pass. - Full typecheck/build pass after these final contract corrections at `69f10daab2`; all 20 PostgreSQL source/projection/index contracts pass. All current-head CI checks passed; Greptile is 5/5 with no unresolved review threads. Merged #18230 supplies the CI-cache and Linux shell-fixture baseline repairs; their duplicate changes have been removed from this PR. The final Runner lane passed after one justified rerun of an unchanged authentication fixture timeout (all 11 fixture tests also pass locally). Previous CI failures and incomplete local runs remain recorded; live deployment and retained-run recovery remain separate verification. ## Risks - The fallback creates a temporary shared bare clone. Metadata is limited to 64 KiB and 256 unique boundaries, duplicate/parent probes are cached, and Git import has a 60-second command budget plus a separate 15-second boundary-probe budget. It runs only after a missing-history import failure. - Incorrect boundaries could hide real host ancestry. The importer retains available parent connections, and regressions cover that case. - The full-bundle fallback can transfer a bundle twice. This preserves the existing fast delta path; removing that extra transfer is outside this correctness repair. - Preservation eligibility expands only for completed native exports on reusable leases. It creates no provider turn and leaves ordinary reusable leases ineligible. Database/filesystem regressions cover result selection and competing physical/host ownership. - The migration rebuilds one partial index; no tables, columns or user records change. There are no agent execution admission, model, trust, recovery permission, workflow or lockfile changes. ## Model Used OpenAI Codex, GPT-6, with reasoning, code execution, and browser tools. The exact serving variant and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
7d194e901f |
feat(ci): merge lockfile refresh PRs through a dedicated bot (#18238)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - CI owns `pnpm-lock.yaml`. Contributors do not commit it, so a poisoned lockfile cannot come in from a community PR. > - `refresh-lockfile.yml` regenerates the lockfile from the manifests on master and opens a PR. > - That PR waits on required checks and code owner review. A `GITHUB_TOKEN` push does not start the checks, so a maintainer must merge each PR by hand. > - The PR content comes only from manifests that maintainers already reviewed on master. A human review adds little. > - This pull request lets a dedicated GitHub App merge the refresh PR at once, without CI or review. > - A release-age gate holds the merge when the refresh adds a package version that is less than 3 days old on npm. > - The benefit is a lockfile loop that closes itself, without a bypass for any identity that other workflows can use. ## Linked Issues or Issue Description Refs #12115 (the same stuck-PR problem, fixed there by starting the checks). Refs #18219 (an example refresh PR that needed a manual approval and merge). **What happened?** Each lockfile refresh PR stays open until a code owner approves it and a maintainer merges it. The required checks `ci / verify` and `ci / e2e` also do not start, because the workflow pushes with `GITHUB_TOKEN`. **Expected behavior** The refresh PR merges with no human action and no CI run, unless it adds a package version that is too new to trust without review. **Steps to reproduce** Merge a manifest change to master. Look at the `chore/refresh-lockfile` PR that the workflow opens. It stays blocked. ## What Changed - `refresh-lockfile.yml` runs in a new `lockfile-refresh` environment. Only `master` can use this environment. - The workflow creates a token for a dedicated lockfile bot app after dependency resolution is complete. The token has only contents and pull request write access. - The workflow merges with `gh pr merge --squash --admin --match-head-commit <sha>`, not `--auto`. It merges only the commit that it pushed. - New `.github/scripts/check-lockfile-release-age.mjs` compares the base and refreshed lockfiles. It looks up the npm publish time of each added package version. The bot merges only when every version is at least 3 days old. A lookup error, a missing publish time, a non-registry version, or a resolution that is not a plain registry tarball also holds the merge. - When the gate holds the PR, the workflow posts or updates one report comment on the PR and does not merge. - A daily schedule runs the refresh again, so a held PR merges after its versions are old enough. - A held run uploads its lockfile as a `held-pnpm-lock` artifact. The artifact records the hash of the master lockfile it started from. The next master run resolves from it only while master still has that lockfile, so held versions stay while their manifests do not change, and a maintainer's lockfile correction replaces them. The workflow does not read the PR branch for this, because users with write access can push to it. - The generated PR body now describes the gate. - `tests/runner-e2e/OPERATIONS.md` now says that the bot can merge the report-lock correction without review, under the same gate. - New `lockfile-refresh-merge.test.mjs` pins the merge safeguards: the environment, the step order, the gate conditions, and `--match-head-commit`. - `doc/RELEASE-AUTOMATION-SETUP.md` §8.1 tells an admin how to create the app, the environment, and the ruleset bypass. It also tells why we do not use `github-actions` or `commitperclip` for the bypass. ## Verification - `node --test .github/scripts/tests/check-lockfile-release-age.test.mjs .github/scripts/tests/lockfile-refresh-*.test.mjs` passes (17/17). - I ran the gate against the real lockfile diff of #18219 and the live npm registry. With 3 days, all 7 added versions passed (`eligible=true`). With 60 days, it held all 7 `turbo` 2.11.10 versions (9.1 days old) and wrote the report. - The workflow YAML parses. actionlint did not run, because it is not installed locally and Docker was not available. - No live run yet. After the admin setup in §8.1, run the workflow with `workflow_dispatch` on master, or merge a manifest change. Then make sure that the bot opens and merges the refresh PR. ## Risks - **Setup order.** An org admin must do the steps in §8.1 before this PR merges. If not, the next refresh fails at the token step, and the PR stays open for a manual merge, as it does now. - **No CI on lockfile changes.** A bad resolution can land on master without a check. The next manifest PR or the canary release shows the problem. - **Release-age gate limits.** The gate stops only fast-detected attacks on new versions. A malicious version that stays undetected for more than 3 days still merges without review. Lockfile changes that add very new versions now wait for a maintainer or up to 3 days. - **Bypass scope.** The app bypasses the master ruleset only in pull request mode. It cannot push to master directly. Only the master-only `lockfile-refresh` environment holds its key. If the key leaks, the holder can merge any open PR past review. Rotate the key if you think it leaked. - **More master runs.** A merge by an app token starts push workflows on master. A merge by `GITHUB_TOKEN` does not. After each lockfile merge, the canary release runs, and the refresh workflow runs again with no change. ## Model Used - Claude Opus 5.5 (`claude-opus-5-5`), Anthropic, in Claude Code with tool use (shell, file edit, GitHub CLI). ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
ebed7f5237 |
test(evals): protect Antigravity setup and two-turn delivery (#18190)
## Thinking Path > - Paperclip manages agents and their work. > - A provider integration must work through ordinary agent setup and task controls. > - The recorded Antigravity walkthrough exposed setup, delivery, and continuation failures. > - A repeatable check must verify real work and retain failed attempts. > - This pull request converts all 47 recorded steps into one fixed Product E2E journey. > - Maintainers can rerun the case and inspect independent delivery, cleanup, and accounting evidence. ## Linked Issues or Issue Description Builds on merged #18187, #18188, and #18189, and consumes the shared repairs from merged #18230 and the equivalent manual-policy declaration from #18222. Refs #18214 for the CI task wrapper. Refs #12503 and #14938 for related legacy adapter work. **Agent or provider** Google Antigravity native Runner with a saved managed Google subscription and the exact Low model. **Why this adapter is useful** A user must be able to add an agent, connect its account, and receive real task results across a follow-up. Picker visibility alone is insufficient. **How the agent is invoked** A fixed Playwright driver uses ordinary product controls. The agent runs through native ACP. Independent checks use public APIs, actual downloads, owned process observations, and native lifetime fences. ## What Changed - Register one explicit-only case: `antigravity-agent-journey.runner-antigravity.local.saved-subscription-two-turn`. - Map all 47 source steps and declare saved-account prerequisites, finite limits, and same-host macOS ARM64 scope. - Create an agent through the ordinary picker, connect the saved account, select Low, run Test, and wait for readiness. Save an instruction marker, deliver a file, and update it through an ordinary follow-up. - Require each run's visible completed file activity, exact downloaded bytes, committed Done result, same tagged conversation, distinct physical owner birth, released lease, and free native fences. Verify reload persistence. - Stop failed native runs that still own a retry. Replay an existing Stop with its durable request identity and wait for the matching audited acknowledgement. A terminal reservation without a native intent remains unconfirmed. - Keep private evidence in the existing result, report, dashboard, and accounting pipeline. Retain the paused QA agent and financial history while preserving the shared account and budget policies. - Journal only the ordinary wizard's future ID, target, name, intended harness and expected creator before forwarding its POST unchanged. Bind the response and interrupted recovery to exact identity reads; a pending 404 stays unconfirmed. - Serialize private resource snapshots through temporary-file fsync, atomic rename and directory fsync. Abort forwarding on storage failure and preserve legacy receipts. If later journal or diagnostic writes fail, retain the primary error, always close the browser, and attempt the ordinary failed report. - Add production-component browser controls and harden task-menu readiness, alias selection, scroll restoration, failure packaging, and one hermetic auth-test budget. - Wait for the existing GitHub recovery fixture to register its next deadline before asserting the original range; preserve its nested-transaction and zero-request checks. In the decision-expiry fixture, verify the exact saved expiry separately from the earlier global wake of another queue. ## Verification - Fresh registered acceptance passed on eval source `9060f3cd01b7c3445ecdf703d72e9cf30fe42b59` and merged serving product `61bd4ac6919c2309f766a25e62273b074cee3261`. It completed ordinary setup and two turns with native `.5` and `gemini-3.8-flash-low`. All 16 matchers, 14 checkpoints, and cleanup passed in **165,613 ms**. Actual downloads were **61 bytes** and **119 bytes**. Both turns passed their own run-bound browser activity checks and reload persistence. - Independent read-back confirms Done, a paused retained agent, the same connected saved default account, and no active owned run. Both accepted results have the same full tagged conversation and distinct primary process births. All 21 observed processes retired; both leases released and all three native fences were free after each turn. The selected `.5` checkpoints also showed equal agent/backend session IDs; this is an observed case requirement, not a generic ACP invariant. - Receipts report 339,273 input tokens, 7,224 output tokens, and 202,846 cached input tokens. Subscription prices are unavailable. Billing coverage remains incomplete, not free. - The normal report CLI passed. All 310 files from nine original attempts and two separate recoveries retained their hashes. The twelve current screenshots are byte-identical, and 194 local report links are contained and valid. The eight earlier reports were copied without regeneration. - Delivery source `1bf4fb04df04710b82844b3c9355767f46b5f68f` branches from `d3f2a60e795fc60d64c8b19d1eed4d48657d5492` and merges cleanly with current master `1d571de5f9f886d66e520800baec8fc2f67d0948`. All 41 prior `c8b332` authored file blobs remain identical; the 42nd path is the decision-expiry fixture contract correction. Creation ownership, the strict durable writer, and the ordinary successful workflow remain unchanged. Of 43 measured file blobs, 30 remain identical. The Antigravity oracle, artifact, billing and report gates and its suite-specific validation block remain unchanged. The actual retained agent matches its original creator; its original request `setupId` was not captured and is not reconstructed. - Later master changes include model-visible workspace guidance and rejected-terminal-report handling. Their bounded source assessment is separate: the first actual finish failed, then a same-turn replacement was accepted and committed. Later read-only results match both original native-result hashes, and the complete event catalogs have no `session.failed` event. Master #18228 also expands detection of explicit JSON file requests. The measured create/update-and-attach `.txt` task already required publication under both parsers; the publication validation gate itself is unchanged. Master #18240 changes remote workspace cache staging and adds an OpenCode index refresh. The selected local lane returns before those paths. Master #18213 adds optional numeric turn timing and trace boundaries. Its selected Antigravity model, text, IDs, result and retirement semantics remain unchanged in the bounded source review. Local diagnostic rows and awaits can change event ordinals and latency; the oracle checks relative semantic order. Collector coverage and latency improvement remain outside this proof. This does not claim that the whole current runtime is byte-identical to serving `61bd`, or relabel the measured result as a new run. - The adopted upstream cache controls passed 3/3 with pinned real Turbo. Forced work disables local and remote reads and writes; ordinary work reuses local results. The original genuine-pnpm/Turbo controls remain historical to `9060`'s earlier write-only policy. The duplicate cache patch is superseded by #18230. Its qualification-only pnpm addition is removed because the adopted upstream controls do not require it. - The E2E typecheck, map checks and 277-control replay are carried from the unchanged eval source paths. That replay passed, including the 183 Antigravity controls, catalog/connection checks and the separate product-journey validator. The carried creation controls include 91 config/recovery cases. The final launcher suite passed 19/19, including five real campaign finalization fault cases; the report suite passed 7/7. These final checks did not rerun the earlier 277-control group. The canonical production-component browser spec passed in 27.4 s under its unchanged 60 s limit before the replay. Four paused-composer cases and the product base's build/typecheck plus 376 focused regressions were verified earlier. - The shipped wizard and actual API client cover persistence before forwarding, lost response JSON, foreign/malformed requests, wrong response identity/creator and cleanup-error preservation. Real filesystem controls failed 5/5 before the writer repair and passed 5/5 afterward, preserving the old journal on partial-write, temporary-file sync and rename faults. Three persistent-sync campaign controls failed before the finalization repair and passed afterward. All five final campaign fault cases preserve the primary failure, cleanup failure, usage and failed report while attempting browser closure. The strict journal still blocks the next mutation. These are provider-free ownership controls; the Google task proof remains the original `9060` → `61bd` acceptance. - The decision restart check passed in the local 20-case fixture run. A current-source real-PostgreSQL rollback control reproduced the exact 90,000 ms earlier global wake: the old equality rejected it, while the exact durable expiry and new future-wake bound passed. The original 60 s open-state, exact-timestamp, continuation and quiet checks remain. The broader local run was **FAILED: 19 passed / 1 failed**, with a 15 s timeout and a 30 s cleanup timeout in an unchanged timestamp-pagination case. That case passed in canonical `c8b332` CI; the local timeout cause remains inconclusive. An extra local server typecheck failed against stale cached Runner declarations; it did not check this excluded test file. Both limits remain recorded for fresh canonical CI. - A broader local GitHub recovery group passed 21/22. Its unchanged pagination case observed an unexpected config request; the log does not establish the cause. That result remains retained, and fresh current-head CI is the final broader gate. - Exact delivery-head CI completed with 55 successes, two skips, and one optional neutral review. Required `ci / verify` and `ci / e2e`, build, typecheck, and Runner checks passed. Fresh Greptile is 5/5 with zero unresolved threads. Optional Paperclip is neutral 4/5; its carried recommendations are dispositioned against the public Stop contract and selected live identity evidence. Seven earlier converted attempts retain their failed grades and partial evidence. Historical Paid8 and its later read-only per-run UI observation remain separate from the fresh acceptance above. Unknown prices and the older partial startup accounting remain explicit. Full lineage and raw evidence remain private in the normal report bundle. ## Risks - This case requires an authorized saved personal default Google subscription and finite operator candidate admission. It does not test fresh OAuth or establish global qualification. - The physical observer supports a same-host loopback macOS ARM64 target. Cloud, Linux, and other models remain outside this case. - A known-cost stop cannot cap missing prices or in-flight subscription charges. Existing operator policies remain unchanged. - Raw account/native identities stay private. Missing retirement proof keeps resources retained. The selected cleanup mode does not test agent purge. ## Model Used OpenAI Codex (GPT-6). The host did not expose the exact model revision or context limit. The model used tools for code edits, tests, browser automation, and review. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (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> |
||
|
|
1d571de5f9 |
Add shared native turn attribution boundaries (#18213)
## Thinking Path > - Paperclip manages work performed by AI agents. > - Native execution crosses the plugin worker, Runner, sidecar, and durable event boundaries. > - Existing outer spans leave repeated preparation and admission work unattributed. > - Optimizations need a common baseline with accurate ownership and event meanings. > - This change extends the existing opt-in tracing contract with bounded timing receipts. > - It preserves execution policy and keeps provider internals opaque where the API provides no timing proof. ## Linked Issues or Issue Description **What existing behavior does this improve?** Attribution of native task preparation, retained/cold Runner handoff, and completion-to-text work. **Current behavior** Worker spans use a flat provider contract. Workspace calls lack a consistent dispatch envelope. Submitted-to-started timing is named as a provider queue even though it includes other work. The transport does not expose a shared breakdown of its waits. **Proposed improvement** Add invocation-scoped nesting, bounded numeric remote receipts, current-run transport timing, durable receipt intervals, and distinct completion/text milestones. Reuse the existing exporter. No latency optimization is included. Related public work: #17842 consolidates existing startup tracing tests; it does not add this runtime coverage. ## What Changed - Extend the optional SDK tracer with nested async scopes and completed timing receipts. Keep the host responsible for parent identity, capability checks, attributes, clocks, depth, and count limits. - Add dispatch and bounded host-read timings for environment and workspace providers. - Resolve transport parents on each call so retained sessions do not retain an earlier run's trace. - Split cold/resume/attach/prepare/registration/command/started-event waits. Add opt-in numeric ACPX Runner/sidecar status and prompt-start receipts. - Distinguish first completion request, validated tool receipt, final result commit, first nonempty text, and event persistence. Rename the submitted-to-started interval to match its meaning. - Link completed earlier remote lifecycles to their host-owned observer rather than placing them under a later polling request. Preserve sampling, timestamp limits and budgets. - Document the versioned coverage map, causal clock limits, and baseline acceptance requirements. ## Verification - Current head: GitHub CI is fully green. Standard Greptile and Apex are both 5/5, with no unresolved review threads. Full-suite validation was performed in CI; follow-up local validation was limited to affected packages and tests. - Review follow-up: early rejection, missing provider capability and startup-parent regressions were reproduced and fixed. The affected worker/SDK/timing set passes 128 tests; 28 timing/context tests, SDK typecheck and direct server TypeScript checking pass. The server typecheck wrapper reached an unrelated Runner rebuild and stopped because Cargo was absent from PATH; full Runner/image validation remains in CI. - CI failure accounting: the earlier Turbo cache/force conflict and Linux OpenCode shell assertion were reproduced and diagnosed. A direct proc probe ruled out permissions; a portable shell comparison identified Bash skipping BASH_ENV with stripped SHLVL and socket stdin. Upstream #18230 now supplies the CI and ignored-stdin fixture fixes; this PR adopts them without duplicate CI changes. The strict Linux OOM assertion passed before this source-equivalent merge. - Retry follow-up: the three insertion/replay/failure timing cases and server typecheck pass. The existing database regression now asserts a single marker across identical result replay; the current-head CI integration gate passes. - Upstream CI alignment: all three real-Turbo 2.11.10 integration cases pass. The repository policy gate rejected committing a generated lockfile; the final PR contains no lockfile edit and uses the maintained inline stale-lockfile recovery. - Linked-lifecycle follow-up: 44 focused host/export tests pass (three optional SDK-dependent cases skip); SDK and server typechecks pass. The API contract test verifies an explicit root context, host-owned observer link and unsampled suppression. - SDK typecheck and focused worker/invocation tests: 30 passed, including clock changes, bounded legacy IPC, and manual-span creation-scope parentage. - Focused reviewed host/native/transaction-boundary checks: 44 passed. The 86-test worker-manager suite passes after updating its exact assertions for the host-owned timing budget found by CI. Earlier preparation/first-text checks also passed. - Affected server and Runner TypeScript checks pass after building local workspace declarations. - Merge follow-up: the profile/candidate startup subset passes 94 tests, the four Grok source-identity checks pass, and Runner TypeScript checking passes. A subsequent execution-factory merge passes 21 focused timing/trace tests and server TypeScript checking. - Pinned Rust build and the ACPX Rust subset pass. The hostile receipt projection test passes. Source profile compatibility checks: 127 passed, one existing skip. Grok identity checks: four passed. - Broad transport/ACPX suite: 410 passed after building all fake provider binaries. Earlier attempts failed on missing Runner/fake-provider outputs; building the required fixtures resolved those failures. - The first CI run correctly rejected stale source attestations. After integrating current master, Grok advances 13→14 and Copilot 84→85; master’s historical fixtures and Pi 35 stay byte-identical. Provider dependencies, models and permission defaults are unchanged. Identity generation/checks now pass. - The added real-Postgres result lock regression could not initialize its local embedded cluster. The insertion/replay/failure unit regressions pass. The current-head CI integration gate passes. - Comprehensive repository checks and image builds are delegated to CI, as requested for this instrumentation pass. No deployment, model run, collector-ingestion proof, or latency improvement is claimed. ## Risks The new SDK methods are optional. Legacy span calls and endpoint-off behavior remain supported. The host accepts only closed timing names and bounded attributes. Remote durations are anchored at local receipt; transport/scheduling uncertainty remains explicit. Trace trees have count/depth limits. The first rollout must inspect actual collector exports before treating the baseline as accepted. Fresh live qualification for the new source identities remains a rollout requirement. Revert these commits to remove the new measurements; no schema migration is required. ## Model Used OpenAI Codex, GPT-6 family, with reasoning and local code/tool execution. The exact runtime 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 described the issue in-PR following the enhancement template - [x] I have not referenced internal/instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal issue 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] Standard Greptile and Apex are both 5/5, with no unresolved findings - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
2aa3ea47e3 |
Reduce restored workspace overhead and trace cache publication (#18240)
## Thinking Path > - Paperclip runs agents in isolated workspaces. > - A native sandbox turn must restore its workspace before the provider starts. > - Restored Git metadata can cause expensive work in the provider's first snapshot. > - Cache replay also hashes the same archives twice, and workspace helpers open sessions that do not need output. > - This pull request removes that repeated work and refreshes the restored index before OpenCode starts. > - It also adds cache-publication timings so the next measurement can separate quota checks, lock waiting, and archive IO. ## Linked Issues or Issue Description **What existing behavior does this improve?** Native sandbox workspace preparation and copyback. **Current behavior** Cache replay validates shared archives, copies them, and validates them again. Exit-status-only helpers use persistent sessions. A restored checkout can make OpenCode's first snapshot recheck much of the repository. Cache publication has an unexplained interval after archive verification. **Proposed behavior** Validate the private archive copy that staging will consume. Use the existing one-shot command path for helpers that only need an exit status. Refresh the Git index after workspace transfer for a new native OpenCode sandbox. Keep the refresh inside the awaited inbound barrier and use the existing command timeout. Add nested publication spans. **Reason and benefit** Two matched local component pairs reduced preparation plus provider time from 8.563/8.553 seconds to 7.313/7.511 seconds, including the refresh cost. Two alternating remote copyback pairs reduced the median from 9.110 to 7.943 seconds. These are component results. They do not establish an end-to-end hosted improvement. Related: #18181 and the earlier closed #18195. This implementation uses the existing fully awaited transfer boundary. It does not use an optional preparation deadline. ## What Changed - Materialize cache hits into caller-owned staging and validate those exact bytes once. Remove incomplete copies on failure. - Select the existing one-shot path for exit-status-only run and removal helpers. Output-reading helpers keep their existing behavior. - Refresh restored Git stat metadata before OpenCode starts. Enable this only for newly acquired native OpenCode host-current workspaces. Skip recovery and retained sandboxes. Keep dirty files unstaged, accept Git's dirty-worktree status, and propagate real command errors. - Trace cache capacity checks, eviction, the body after lock acquisition, archive copy, sync, and hashing. Keep the operator endpoint gate and bounded phase names. ## Verification - On the rebased branch: 202 focused tests pass: 152 workspace seed/cache/runtime tests, 27 managed command tests, and 23 native workspace/tracing tests. Adapter TypeScript build and server typecheck pass. - Tests cover corrupted copies, cache changes after private materialization, dirty working trees, quoted paths, recovery, the awaited refresh barrier, real command failure, and company-lock contention. - A real-filesystem probe through the server phase mapper verified parentage and endpoint-off behavior. A controlled lock wait stayed outside the locked-publication span. No external export was used. - A full local Core/Daytona replay on the pre-rebase implementation saved its synthetic reply. It retained the pinned large public workspace, all 209 skill files, positive Git context, and 66 tool schemas. Both model calls stayed on sandbox loopback. Index refresh took 0.644 seconds and the first provider snapshot took 0.499 seconds. The run took 162.004 seconds, including large laptop uploads; it is not a hosted acceptance result or a matched end-to-end comparison. The failed installer attempt remains recorded separately. Normal cleanup removed all owned sandboxes. - The current head passed 53 CI checks, with two optional skips. Greptile is 5/5 on the exact head, with no open review threads. No deployment or hosted latency claim is included. ## Risks - Index refresh adds one awaited command. It uses the existing timeout. A real Git failure stops preparation. - Cache hits need temporary disk space for a private copy. Existing corruption fallback and per-run recovery archives remain. - One-shot command transport must preserve exit status and timeout behavior across providers. The agent's native session and output-reading helpers are unchanged. - Local component gains are small relative to the remaining hosted latency. Batch the fixes with the diagnostic spans; measure the actual deployed path before claiming success. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, tool use, and code execution. The session does not expose the exact model SKU 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> |
||
|
|
6a67471644 |
Require publication for explicit JSON file outputs (#18228)
Extend the native file evidence rule to explicit JSON creation and publication requests, with conservative input and destination handling and a real PostgreSQL completion regression. Co-Authored-By: Paperclip <noreply@paperclip.ing>canary/v2026.1030.0-canary.1 |
||
|
|
d3f2a60e79 |
test(e2e): reuse core journeys across deployment targets (#18222)
## Thinking Path > - Paperclip manages agents and their work. > - Product E2E tests verify work through the browser and public APIs. > - The classic matrix already tests several common task stories. > - Its older stories depend on local fixture setup and workspace access. > - Deployment tests need the same story checks with a separate target adapter. > - This PR shares those checks and adds five explicit journey selections. > - A deployment pass still requires evidence from that deployment. ## Linked Issues or Issue Description **What existing behavior does this improve?** Product E2E journey reuse across managed instances and deployed Cloud instances. **Current behavior** The deployed-target catalog covers task creation, assignment, Ask, and fresh onboarding. Plan revision and Everyday stories run through the classic fixture driver. Several story steps assume a local workspace. **Proposed behavior** Add explicit Plan revision, artifact revision, protected-action approval and decline, Skill Studio, and Stop/redirect journeys. Share the main browser sequences and content checks with the classic driver. Let target adapters provide authentication, native agents, a reachable service fixture, and owned cleanup. **Reason and benefit** A local pass cannot verify the deployed application. Shared story code lets a deployed target exercise the same behavior without copying an entire test or starting a replacement server. **Breaking changes** No product API or default matrix selection changes. Passed deployment results must satisfy the declared story checks and work-run count. Unsupported target capabilities fail before a story runs. Related public work: #17262 and #18098. Upstream prerequisite: #18230. ## What Changed - Extract shared Plan, artifact download/oracle, protected service, Skill Studio, and Stop/redirect helpers. Keep classic callers on those helpers. - Add five explicit paid journey selections with owned-task observations and native company, agent, model, and environment checks. - Include classic prompts, delivery/decision code, and the decline grader in the source-definition hash. Keep classic transient-read retries and reject deployment binding failures immediately. Match cookie directory boundaries in sensitive fixture requests. - Require complete story checks and expected run receipts before retaining a passing result. Keep failed evidence and private downloads. - Add a secret-safe request method for deployment fixture credentials. Add the missing declaration for the existing manual evidence policy module so the E2E project can typecheck. - Document target responsibilities and promotion after a real deployment pass. This source catalog does not enroll candidates in a daily plan. ## Verification - E2E TypeScript check: passed, including the review follow-up. - Review follow-up: 30 tests passed across four files, covering transient Plan reads, immediate binding rejection, cookie-path scope, agent receipts, and artifact evidence. Stop now waits for a saved, still-active native turn before the browser click and retains its startup events. Counterexamples reject claimed-but-unstarted, already-completed, interrupted, and non-native work. Shared observation and API helpers also enter the definition fingerprint. Cancellation snapshots are captured before lease cleanup. A direct terminal-boundary assertion rejects native work after cancellation even if it is already in the first snapshot; five cleanup-window counterexamples are covered. The Stop-output regression first failed for both native `item.delta` and `item.completed`; the fixed check detects both while allowing accounting-only updates. A report-catalog test first failed because the sandbox denied the tsx child IPC pipe (`listen EPERM`); the unchanged test passed outside the sandbox. - Affected journey, catalog, API, service fixture, and delivery checks: 313 tests passed across 19 files. - Workspace build: passed after rebase. - Workspace typecheck: passed. The default repository run was attempted. Repeated embedded PostgreSQL startup failures prevented local database coverage; it was stopped without claiming a full pass. Linux CI must supply that coverage. - Broad E2E support run: 4,793 passed, 23 failed, 2 skipped. Failures include existing stale image/Pi assertions and process/startup timeouts under host load. The affected tests pass separately. This is not a claim that the broad suite is green. - Upstream CI prerequisites: this branch is rebased on the merged #18230 repair. The earlier conflicting Turbo flags no longer apply. The shell-hook fix is also supplied by that upstream change. Linux shell-hook investigation: 19 focused tests and adapter TypeScript passed. The exact staged-config sequence reproduced CI's 500 in a pinned Node 24 Linux container. Node's default stdin socket at shell level zero selects Bash remote-shell startup and reads `.bashrc` instead of `BASH_ENV`. Ignored stdin and a nested shell each produce 1000. The fixture now ignores stdin; the production hook and 1000 assertion are unchanged. See [Bash startup rules](https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files). - GitHub CI on the earlier head passed most suites but failed two browser tests (a fixture cleanup lock timeout and a fixture run staying queued) plus the shell-hook assertion. The lock-timeout case received one retry, which was cancelled by a later source push and does not establish recovery. These failures remain part of the verification record. - Real Cloud qualification: the private target adapter is reviewed and merged. These candidates must pass there before daily-plan promotion. Current source review: Greptile 5/5 and Paperclip Review 5/5 on `a9df1d6e8d880710fce39b87e689e07e1c8e6edc`, with zero unresolved review threads. The full [GitHub CI run](https://github.com/paperclipai/paperclip/actions/runs/40974946081) passed on that exact head, including both required aggregate checks. ## Risks Shared helper changes affect classic callers. The independent ZIP oracle and visible delivery requirements remain in place. Stop requires native acknowledgement, terminal event evidence, resource cleanup, and no later original-turn activity. The managed local target still lacks paid-agent fixtures and reports these journeys as unsupported. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, terminal use, and code execution. The exact serving model ID and context window are not exposed to this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (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> |
||
|
|
fe3e0f2d5f |
Preserve rejected native completion reports as failures (#18227)
Keep rejected declared completion reports on the existing permanent native failure path. Preserve rejection across restoration and order permanent failure ahead of terminal goal facts, goal results, and continuation while retaining the original provider terminal. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
1e984cc9ca |
fix(runner): guide missing deliverables to the task workspace (#18226)
Explain missing task-workspace deliverables and preserve safe remote file errors across output streams. Keep the existing file confinement and granted-location contracts. Co-Authored-By: Paperclip <noreply@paperclip.ing>canary/v2026.1030.0-canary.0 |
||
|
|
4de82bc12e |
test(server): give the description-edit admission poll the same retry budget as its siblings (#17487)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - One subsystem is the chat channel control plane. It admits inbound
GitHub mentions and then creates a chat conversation.
> - Admission is durable. A transient database error defers the wakeup
and retries it later.
> - The retry delay has a floor of 1000 ms (`1000 * 2 ** attemptCount`
in `server/src/services/chat-channels/inbound/wakeups.ts`).
> - One integration test waits 1000 ms for the conversation. Any
deferred retry therefore fails the test, although the product works.
> - This pull request gives that one wait the same 10 s budget that the
neighbouring tests already use.
> - The benefit is a stable `chat (2/3)` CI shard. No production code
changes.
## Linked Issues or Issue Description
No public GitHub issue exists for this test defect. This is a bug
report.
**What happened?**
The test "authorizes description edits as the editor, never inheriting
the original author's access" failed in CI at
`server/src/__tests__/chat-channels.integration.test.ts:5636`.
The assertion was `expected +0 to be 1`. It is an `expect.poll` call
without a timeout, so the budget is the 1000 ms default.
The server log from the same job shows that the application did not drop
the conversation. It shows a deferred admission instead:
```
WARN: accepted inbound chat wakeup will retry {"deliveryId":"..."}
caused by: PostgresError: could not obtain lock on row in relation "chat_endpoints"
```
`acceptInboundWakeup` sets `retryAt = now + Math.min(30_000, 1000 * 2 **
Math.min(attemptCount, 5))` on such errors. The floor is 1000 ms. One
deferred retry always exceeds the poll budget.
**Expected behavior**
The test waits long enough for one deferred retry. It then passes,
because the conversation is created.
**Steps to reproduce**
1. Check out `master`.
2. Run `cd server && ../node_modules/.bin/vitest run
src/__tests__/chat-channels.integration.test.ts -t "authorizes
description edits as the editor" --config vitest.config.ts`.
3. Add database contention on the `chat_endpoints` row during the second
`send()`, so the first admission attempt fails with `could not obtain
lock`.
4. The wakeup is deferred with a 1000 ms delay. The poll stops at 1000
ms and fails.
**Paperclip version or commit**
`master` at `991c47b`. The failure was observed on a pull request branch
that does not change the chat code.
**Deployment mode**
Local trusted, embedded Postgres test runner.
## What Changed
- Add `{ timeout: 10_000 }` to the `expect.poll` call at
`server/src/__tests__/chat-channels.integration.test.ts:5636`.
- This matches the three neighbouring tests that poll the same
conversation count (lines 5577, 5658, 5721).
## Verification
- Before the change, one deferred admission fails the assertion, because
the default budget is 1000 ms and the retry floor is 1000 ms.
- After the change, on `master` at `991c47b`:
```
cd server && ../node_modules/.bin/vitest run src/__tests__/chat-channels.integration.test.ts \
-t "authorizes description edits as the editor" --config vitest.config.ts
→ Test Files 1 passed (1); Tests 1 passed | 1421 skipped (1422)
```
- The complete file was not re-run locally. The targeted test covers the
changed assertion. All other lines of the test stay the same.
## Risks
- Low risk. The change touches test code only.
- A longer budget can hide a slow admission, but only up to 10 s. The
neighbouring tests already accept that budget for the same behaviour.
- A real loss of the conversation still fails the test.
## Model Used
- Provider: OpenCode. Model: `deepseek-v4.1-flash-free`. Context window:
200K. Modes: tool use, code execution, file access. No extended
thinking.
## 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
- [ ] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: ARTeMobAgents <11891309+ARTeMobAgents@users.noreply.github.com>
|
||
|
|
1843d27e09 |
chore(lockfile): refresh pnpm-lock.yaml (#18219)
## Thinking Path > - Paperclip uses a dependency lock for reproducible builds. > - Dependency changes on master need matching lock entries. > - Paid eval reports also pin a reviewed offline correction. > - Reports must install before paid model work starts. > - This automated PR keeps the lock and report proof together. ## Linked Issues or Issue Description **What happened?** Dependency manifests on master changed after the last committed lock refresh. **Expected behavior** Frozen installs must match those manifests. Eval reports must retain matching offline lock proof. **Steps to reproduce** Run a frozen install before and after this lock refresh. ## What Changed - Refresh the dependency lock from the manifests on master. - Include the matching offline report correction and hashes. ## Verification - Pinned pnpm resolution completed with lifecycle scripts disabled. - The report proof refresh accepted the reviewed committed baseline. - Required PR checks and reviews must pass before merge. ## Risks Dependency changes require review. Unknown report lock baselines remain blocked. This update changes no permissions or paid enable gates. ## Model Used None — generated by pnpm and the deterministic report-lock updater. ## Checklist - [x] Thinking path and problem description included - [x] Generated lock and matching report proof included - [ ] Required CI checks and reviews pass Co-authored-by: lockfile-bot <lockfile-bot@users.noreply.github.com> |
||
|
|
99ec767a42 |
Fix forced CI execution and align OpenCode shell fixture (#18230)
Use one explicit Turbo cache mode for forced CI execution and preserve cache trust boundaries. Match OpenCode’s ignored stdin in the relocated Linux shell-hook fixture while retaining strict OOM and parent-isolation assertions. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
16816d45e6 |
fix(runner): keep OpenCode thread/read within runnerd's frame limit (#18218)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - Paperclip Runner runs OpenCode agents through runnerd and the
OpenCode app-server proxy
(`packages/paperclip-runner/src/cli/opencode-app-server-proxy.ts`).
> - When runnerd restores an OpenCode session, it sends `thread/resume`
and then `thread/read`. It uses `thread/read` only to find an active
provider turn.
> - The proxy answered `thread/read` with the full retained OpenCode
message history (`GET /session/{id}/message`) in one JSON-RPC line.
> - runnerd rejects a provider stdout line that is larger than 4 MiB
(`CODEX_APP_SERVER_MAX_FRAME_BYTES`). A long OpenCode session therefore
can never resume. Each restore fails with `harness stdout frame exceeded
4194304 bytes`, and the run stops with `provider_frame_too_large`.
> - This pull request makes the proxy return turn metadata only, the
same as the Codex metadata-only read.
> - The benefit is that long OpenCode sessions resume again, and resume
no longer reads the full message history.
## Linked Issues or Issue Description
**What happened?**
A Paperclip Runner OpenCode task on staging tried to resume its session
in a new sandbox. The restored OpenCode state was approximately 41.5 MB.
The `run.attach` command failed with `failed to resume OpenCode
provider: failed to start opencode provider: harness stdout frame
exceeded 4194304 bytes`. The server recorded
`native_session_recovery_failed` with error code
`provider_frame_too_large`, and it stopped automatic replay. Each new
attempt has the same failure, because the message history only grows.
**Steps to reproduce**
1. Run an OpenCode task until its session holds more than 4 MiB of
message parts.
2. Let the run continue in a new runner process, so that runnerd must
send `thread/resume` and then `thread/read`.
3. The proxy writes the full message history in the `thread/read`
response. runnerd rejects the frame and the resume fails.
**Expected behavior**
The resume succeeds. The size of the session history does not change the
size of the `thread/read` response.
**Root cause**
`thread/read` in the OpenCode proxy added `transcript: await
session.read?.()`. No consumer reads this field. The Rust provider reads
only `thread.turns` (`latest_active_turn_id`). The Codex path already
avoids message hydration for the same check ("Never hydrate message
contents just to decide whether this thread has an active turn").
## What Changed
- `opencode-app-server-proxy.ts`: `thread/read` now returns `thread.id`,
`thread.cwd` and `thread.turns` only. It does not call `session.read()`.
- `test/fixtures/fake-opencode-server.mjs`: the fake OpenCode server can
now return a large retained message history. The test enables this with
a `fake-message-history-bytes` file in `XDG_DATA_HOME`. This follows the
existing file-switch pattern of the fixture. Without the file, the
response is `[]`, as before.
- `src/cli/opencode-proxy-thread-read.test.ts`: a new regression test.
It builds the real bundled proxy entrypoint, starts a session, stops the
proxy, gives the persisted session a 5 MiB history, then starts a new
proxy and sends `thread/resume` and `thread/read` (the runnerd restore
sequence). It asserts that all stdout frames stay below 4 MiB and that
`thread/read` still reports the thread id and turns.
## Verification
- Red before the fix: `npx vitest run
src/cli/opencode-proxy-thread-read.test.ts` failed with `expected
5243183 to be less than 4194304`. The 5,243,183-byte frame was the
`thread/read` response.
- Green after the fix: the same command passes.
- `npx vitest run src/cli/opencode-app-server-proxy.test.ts
src/cli/opencode-proxy-thread-read.test.ts`: 6 passed.
- `npx vitest run src/cli/opencode-proxy
src/backends/native-instruction-measurement.test.ts
src/drivers/opencode`: 158 passed, 1 failed. The failure
(`opencode-server-driver.test.ts` > "uses provider structure rather than
prose length to select a post-tool answer") also fails on the unchanged
base commit in this environment. This change does not touch that path.
- `tsc -p tsconfig.json --noEmit` for `packages/paperclip-runner`:
passed.
- Safety checks:
- Consumers: only the runnerd Rust provider (`read_thread`) calls
`thread/read` on this proxy. It reads `thread.turns`. No TypeScript or
Rust code reads `transcript`.
- Active-turn detection does not change. The `turns` logic is the same
code.
- Resume now does less work: one `GET /session/{id}/message` request
less.
- Not run locally: the Rust tests and a full runnerd plus real OpenCode
resume. This environment has no Rust toolchain. The Rust code does not
change. CI runs the Rust suites.
## Risks
- Low risk. The change removes one unused response field.
- If an external tool read `transcript` from the proxy's `thread/read`,
it does not get it now. I found no such consumer in this repository.
- Tasks that already failed with `provider_frame_too_large` continue
only after this proxy reaches the runner provider pack and the task runs
again.
## Model Used
- Provider: Anthropic. Model: Claude Opus 5.5 (`claude-opus-5-5`). Used
through Claude Code with tool use (shell, file edit, GitHub connector)
and standard reasoning.
## 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 (related: #16401 kept OpenCode turns alive through oversized
SSE events. It does not change `thread/read`.)
- [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 (none
required: no documented contract includes `transcript`)
- [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
- [ ] I will address all Greptile and reviewer comments before
requesting merge
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
canary/v2026.1029.0-canary.24
|
||
|
|
f5dcc505c0 |
perf(ci): select affected suites and cache task results (#18214)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Pull request CI checks the server, UI, packages, Runner, and release paths. > - An ordinary PR starts 48 jobs even when its diff affects only a small part of the repository. > - Repeated pushes also repeat successful tests with unchanged inputs. > - This PR selects affected suites before runner allocation and caches deterministic task results with Turbo. > - Required checks validate the plan. Unknown inputs and failed comparisons keep full verification. > - The benefit is fewer runner jobs and less repeated work, with full post-merge verification retained. ## Linked Issues or Issue Description **What existing behavior does this improve?** The GitHub Actions PR workflow repeats unrelated suites for each push. **Subsystem affected** Cross-cutting CI routing, test execution, and required-check aggregation. **Current behavior** An ordinary UI component change starts the complete 48-job PR workflow. Existing dependency and compiler caches do not reuse successful test results. **Proposed behavior** A trusted planner reads the tested merge diff and task inputs. A UI component change such as `ui/src/components/Sidebar.tsx` selects 18 jobs, including build and browser coverage. Successful general, serialized, and standalone Rust tasks can reuse unchanged results across pushes in the same PR. **Reason and benefit** Reduce unrelated jobs and repeated test execution. The 48-to-18 comparison measures planned job count. Remote wall-clock savings have not yet been measured. **Breaking changes** No application API changes. Required `verify` and `e2e` names remain stable. `verify` also checks serialized suites and the canary dry run. ## What Changed - Added explicit task inputs and a pinned Turbo version. An execution adapter calls existing package scripts without adding script aliases. - Added trusted diff planning and dynamic matrices with complete fallback matrices. - Added PR-scoped task result caches. External-state and revision-stamped checks remain uncached. - Added and created the `full-ci` override label, plus repository modes `enabled`, `shadow`, and `full`. Forced and shadow runs bypass result caches. - Added candidate-workflow qualification, planner and aggregate tests, and a real Turbo cache fixture. - Kept the repository-wide CLI guidance guard in the uncached typecheck lane so UI-only diffs retain this security check. - Documented rollout controls, input maintenance, and local inspection commands. ## Verification - Passed 537 focused CI policy, routing, matrix, cache, and shard tests, plus 146 existing release workflow tests. - Passed actionlint for all four changed or added workflows and `git diff --check`. - Passed `pnpm -r typecheck` and `pnpm build` on the implementation base. - Checked real repository task plans for existing general-test and native Rust commands. A real server partition passed, then restored from cache: Turbo task time was 20.022 seconds for execution and 151 ms for the cache hit, excluding wrapper/setup overhead. - The real Turbo fixture exercises the execution adapter and proves source, argument, toolchain-scope, and environment invalidation, result restoration, and retry of failed tasks. - Stopped the serial local `pnpm test:run` after over 30 minutes in favor of the complete parallel GitHub suite. A local parallel database-lane attempt had PostgreSQL startup errors and timeouts. The direct migration fixture passed, then all 273 database tests passed with one local worker. This recovery does not establish the exact cause of the earlier startup failures. The full GitHub PR suite and candidate qualification passed on commit `0bf07ae071c9fe7903edc604d44b5a175727fed0`. Greptile is 5/5 with no unresolved review threads. - All 40 CLI guidance safety tests passed with the exact uncached workflow command. - Verified that master rulesets require only `ci / verify` and `ci / e2e`; both names remain unchanged. - Trusted workflows load from master. The added GitHub-hosted qualification workflow exercises this candidate planner before merge. ## Risks - Changes to global inputs, including task definitions and execution helpers, force execution and disable cache restore/save for the full PR diff. Missing a cross-package filesystem read could omit a suite. Inputs include known server reads of UI files and shared tests of UI assets. Unknown paths, malformed or truncated diffs, and definition download failures select all suites. - Task result reuse requires complete inputs. Keys include Git source files, scripts, resolved dependencies, environment, toolchain, checkout path, and unclassified source files. Generated build artifacts are excluded from input hashes. Registry smoke, browser, and revision-stamped tasks remain uncached. - Maintainers must update task inputs when suites start reading new paths. `shadow` reports selection while running all work. `full` and `full-ci` disable selection and result reuse. - The implementation becomes active after merge. Full post-merge verification remains unchanged. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, repository inspection, tool use, and code execution. The session does not expose a verifiable exact runtime 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> |
||
|
|
61bd4ac691 |
feat(agents): set up Antigravity with saved Google subscriptions (#18189)
## Thinking Path > - Paperclip manages agents and their work. > - Users choose providers and managed accounts while adding agents. > - Antigravity was missing from the ordinary additional-agent picker and its saved Google path did not complete native readiness. > - A user needs a successful Test, an enabled task action, and a stable account binding. > - This pull request connects the ordinary setup flow to the native candidate. > - It also preserves retired credential refreshes across database failures and server restarts. ## Linked Issues or Issue Description Built on merged #18188 and #18187. Refs: #12503, #14938 for related legacy CLI proposals. **Agent or provider** Google Antigravity ACP 1.4.3. **Why this adapter is useful** Users need to set up an Antigravity agent and run real work through their managed Google subscription. **How the agent is invoked** Native Paperclip Runner uses the pinned Antigravity ACP runtime. Exact operator admission remains required; the local candidate result does not enable general release. ## What Changed - Show Google Antigravity in the ordinary adapter grid and preserve the draft choice when setup resumes. - Reuse the same user’s saved personal default Google subscription and discover the exact low model through the native account. - Run a prompt-free native Test and wait for authoritative readiness before enabling task assignment. - Carry the managed account through native runs and recover retired refreshes through the existing encrypted, fsynced journal with exact generation checks. - Retain the latest rotated credential through verification, storage, and partial home-removal failures. Retry the exact account’s retained cleanup before another provider use. - Reconcile cleanup before taking the credential mutation lock, fence owners arriving during lock acquisition, and support nested lock holders without a join cycle. - Bound sign-in retirement outside database transactions and preserve claims for the existing cleanup owner; one pending sign-in does not block unrelated accounts. - Cover Gemini and Pi API-key recovery, keep API-key bulk manual-model editing usable, and keep adapter discovery available after candidate expiry. - Skip taskless native timer work before run or credential admission. Preserve current master monitor and deadline scheduling. ## Verification - The registered local saved-Google-subscription journey passed all 16 matchers in 196,520 ms using eval source `12aba` against actual serving source `4a37ee7c`. Both turns stayed in one conversation, produced exact downloaded files of 61 and 119 bytes after reload, and used distinct native primary processes. All observed owners retired, leases released, and credential fences settled. Independent readback confirmed Done work, no active owned runs, a connected saved account, and the retained agent paused for inspection. - The measured runtime is production-equivalent to pre-restack `65ef31dc` except its test-only transport fixture correction. Current-master head `ff7c9249` preserves all 99 product paths: 98 exact blobs and only eight inherited plugin-panel lines in `agents.ts`. Its native binary was rebuilt for inherited Codex-only diagnostic changes; the changed Rust behavior is outside Antigravity's ACPX execution path. Shared native/UI changes have focused regression coverage. The recorded live result is not represented as a measured replay of `ff7c9249`. - Full workspace build and typecheck passed on `ff7c9249`. All 376 focused tests in 14 files passed, covering Google credential/retirement controls and the inherited native-tool, redaction, route, and UI recovery changes. Token gates, maps, and diff checks passed. The required-close fixture was separately demonstrated red, then passed all 317 selected provider-wiring cases. - [Current-head CI](https://github.com/paperclipai/paperclip/actions/runs/40959387972) is green: 55 successful checks, two skipped workflow checks, and an optional neutral review check. Required `ci / verify` and `ci / e2e` passed. Greptile and Paperclip Review both report 5/5 on exact `ff7c9249`, with zero unresolved review threads. - This qualifies the selected operator-authorized local saved-subscription candidate. The original exploratory journey remains historical evidence; the repeatable fixed-driver eval is in the next PR. ## Risks - Google refresh recovery must preserve the exact grant, account, and credential generation. An uncertain native owner or failed encrypted handoff retains the private home and blocks cleanup. - A successful local saved-subscription candidate does not qualify fresh OAuth, API keys, Cloud, Linux, other models, or general release. - Timer filtering changes only taskless native Runner admissions. Existing task-bound monitors and legacy adapters retain their owners. ## Model Used OpenAI Codex (GPT-6). The host did not expose the exact model revision or context limit. The model used tools for code edits, tests, and review. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (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> |
||
|
|
d7bcf3912f |
fix(ui): single underline on markdown document card labels (#18215)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - Comments and task bodies render markdown, and a saved plan or
document shows as a compact document card
> - The document card is a link inside the markdown body, so it gets the
general markdown link underline
> - The card label also has its own underline, so the label shows two
lines
> - This pull request removes the inherited underline from document
cards only
> - The benefit is that the card label shows one clean underline
## Linked Issues or Issue Description
No public issue exists. This is a small visual bug.
**What happened?**
A document card (for example the "plan" card) in a comment shows a
double underline under its label.
**Expected behavior**
The card label shows a single underline.
**Steps to reproduce**
1. Open a task that has a plan document.
2. Look at a comment or body that links the plan as a document card.
3. See two underlines under the card label.
**Paperclip version or commit**
`master` at
|
||
|
|
54cc522e86 |
feat(runner): add gated native Antigravity ACP execution (#18188)
## Thinking Path > - Paperclip manages agents and their work. > - Native Runner must bind each provider turn to the selected task, account, model, and instructions. > - Antigravity needs native ACP admission and physical process ownership across continuation. > - A saved conversation must not reuse an old process owner or silently switch its effective model. > - This pull request adds the native candidate behind exact operator admission. > - The default release gate remains closed while qualification is pending. ## Linked Issues or Issue Description Builds on merged #18187. Product account setup and the candidate producer are in dependent #18189. The repeatable browser journey is in #18190. Refs: #12503, #14938; those proposals use legacy CLI adapters. **Agent or provider** Google Antigravity ACP 1.4.3. **Why this adapter is useful** Users need to set up an Antigravity agent and run real work through their managed Google subscription. **How the agent is invoked** Native Paperclip Runner uses the pinned Antigravity ACP runtime. Exact operator admission is required while qualification remains pending. ## What Changed - Add native Antigravity ACP model and instruction admission, selected-account homes, and fenced refresh ownership. - Carry exact candidate authority from the control plane through Runner, Rust, the sidecar, and each current run. Clamp daemon lifetime to the absolute permission expiry, including replacement owners. - Preserve a rotated OAuth refresh token before later identity verification can fail, including failed or cancelled startup admission. Make private lease-close retries safe. - Bound native probe retirement and retry the exact original owner; do not delete credential homes before physical proof. - Preserve Gemini API-key recovery when shared Google subscription capability is added. - Resume the same tagged native conversation with fresh per-turn process ownership and physical native retirement. - Include native manifests in isolated Rust image stages, release cache keys, and dev rebuild detection. The workflow changes only extend existing cache input lists. - Keep current master provider behavior and append Grok 13, Pi 35, and Copilot 84 input identities. Preserve prior identities, including saved Copilot 82 and 83 runs. ## Verification - Runner TypeScript main checks, profile generators, Rust formatting, and offline workspace checks pass. The native backend integration target passes 28 tests. - The complete transport and cleanup group passes 387 tests without unhandled rejections. These checks use local scripted children and actual process and port ownership. - Saved-profile decoding, native-execution parsing, installation, and selected-credential controls pass 208 focused tests. All 109 pre-existing profile identity files remain byte-for-byte unchanged. Copilot, Grok, and shared TypeScript/Rust generation checks pass. - The final recovery fixture passes all seven cases. After the master rebase, the combined recovery and owned-Node-runtime group passes all 10 cases. Each expiry case sets one 45-second absolute grant before startup. It includes the deliberate six-second cold delay, four existing eight-second command budgets, and active-turn headroom. The test proves an active turn before expiry and then checks the daemon, owned process group, child processes, and all three native port fences. The 60-second test deadline does not renew provider authority. - The consolidated model-discovery and pending-release group passes 22 tests. Google credential compatibility and auth recovery pass 25 tests, including existing Gemini API-key recovery. The full product settings test group remains intact in #18189. - Earlier failures remain in their original CI runs and local records. They exposed the Copilot 82 decoder gap, an expired five-second fixture bootstrap ticket, and a fixture grant consumed before activation on loaded CI. Each repair has a separate result. Production ticket limits and admission behavior are unchanged by the final test commits. - An unrelated decision-expiry check failed in [the earlier CI run](https://github.com/paperclipai/paperclip/actions/runs/40941986698/job/123688668997). Its owning code is unchanged from the base. The unchanged suite passes 20 tests on isolated PostgreSQL. A controlled database rollback reproduces the earlier wake: clean startup schedules the 120-second decision expiry, while rollback reconciliation leaves a 30-second continuation-coalescing wake. The decision stays open, with no wake delivery or error. The fresh final-head server shard passes; the failed result is preserved. - Final native commit `ec6bc7e4d77f5ae0cc4946dbba6c662e95a87f5b` passed `ci / verify` and `ci / e2e`. Fresh Greptile and Paperclip reviews both score 5/5, with no open findings. Antigravity retains the recorded native `.5` closure and exact low-model profile. This PR does not claim global or cross-platform qualification. ## Risks - The new transport carries private managed credentials. Exact ownership, account generation, model, instructions, and native retirement are fail-closed. - Only local macOS ARM64 has a verified complete Antigravity runtime. Default Antigravity task execution remains disabled without current trusted operator admission. The Google server sign-in lane and production candidate producer ship in #18189; this native slice does not expose the subscription catalog choice. - Shared launch inputs change provider identities. New identities are append-only; existing recorded identities remain available. ## Model Used OpenAI Codex (GPT-6). The host did not expose the exact model revision or context limit. The model used tools for code edits, tests, and review. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (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> |