mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-21 16:27:18 +02:00
7c58ea07b2095366d6bf7451f3146ea2df85ba17
470
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
ac9459bae3 |
feat: configure company agent observability (#16874)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Companies use several agent harnesses and execution environments. > - Operators need one place to select where native agent logs and traces go. > - An inference proxy would add a dependency to the agent request path. > - This pull request supplies native OpenTelemetry settings to managed Codex and Claude Code processes. > - Company secrets protect destination credentials. Export failure does not change the task result. ## Linked Issues or Issue Description **Subsystem affected** Company settings, shared contracts, database, server, adapters, and runner. **Problem or motivation** An operator cannot configure a company destination for native agent logs and traces. Manual harness configuration is hard to apply across local and remote execution. **Proposed solution** Add one company destination: Braintrust or a custom OTLP HTTP/protobuf endpoint. Apply a transient snapshot when execution preparation starts. Keep credentials out of API reads, task environment manifests, recovery files, and command arguments. Replace a warm process when its export settings change and preserve its conversation. **Alternatives considered** Multiple destinations can use a user-operated collector for fan-out. This change does not add a collector, an inference proxy, or transcript scraping. **Roadmap alignment** This extends company settings, secret management, and support for multiple harnesses. The maintainer requested this implementation. Searches for observability and Braintrust found no duplicate company destination feature. Related infrastructure tracing work in #16236 has a separate content-free contract. ## What Changed - Add strict schemas, revision checks, encrypted secret storage, activity records, and board-only settings routes. - Add explicit synthetic logs and traces tests with a bounded HTTP request and sanitized results. - Supply native Codex configuration and Claude Code environment values through local and remote launch paths. - Preserve Codex login refresh through the existing managed credential link. Retain unsaved drafts across background reads. Require complete custom header re-entry when the endpoint origin changes. - Separate process export compatibility from conversation identity. Isolate generated Codex configuration and preserve resumable sessions, including remote home refresh after export changes. - Advance the immutable Pi/Copilot source attestations for shared environment and sidecar code changes. Keep their provider payloads unchanged and retain prior identities for decoding. - Redact destination credentials throughout launch diagnostics and HTTP logs. - Add the production settings form, Storybook states and journey, documentation, and feature/access map entries. ## Verification - Real managed local Codex 0.160.0 and Claude Code 2.1.286 tasks exported to Braintrust. API readback and the Braintrust UI showed the test records. A real remote Daytona Codex task exported through the legacy `exec` path. - Live tests exercised content capture off, export disabled, warm conversation reuse, and a destination that accepted connections but never replied. Agent work succeeded and export requests stopped at the configured three-second timeout. The UI connection test returned “Test payload accepted”; the saved API key stayed masked after reload. - All current-head CI test lanes, typechecks, packaging/build checks, and required aggregates passed on `71e994b2be9c8fb6d6e938a4ad7cf4c95fdafe31` ([CI run](https://github.com/paperclipai/paperclip/actions/runs/39319194318)). Greptile completed on that exact commit at 5/5, with zero unresolved review threads. The additional optional Paperclip Review check remains queued waiting for its assigned agent. - Local workspace typecheck and build passed. Focused verification included 239 combined runner tests, 789 API/native-session tests, 107 Codex home/ACP/sandbox-site tests, 204 feature/privacy tests, and the affected Rust suites. Migration, token, map, Storybook catalog, and Storybook build checks passed during acceptance. These checks ran at the relevant implementation or merge boundary; the current-head CI is the complete final gate. - Managed AI credential projections now receive enabled and disabled company export settings; genuine caller-owned Codex homes remain untouched. Two regressions reproduced the skip before the repair. All 276 engine/lifecycle tests and adapter-utils typecheck pass afterward. The launched TOML retains provider/MCP settings, credential continuity, and redaction. - Settings saves, removal, and the real company-deletion owner acquire secret mutation ownership before database locks. PostgreSQL NOWAIT probes cover all three paths; concurrent save/rotation/removal/deletion requests settle correctly. The affected suites passed 137 tests, followed by all 32 service/connection cases after expanded deletion coverage. Server and Codex adapter typechecks pass. - Codex source profiles use the effective CLI argument list. A spawned fixture CLI reproduced both ignored-argument failures; all three precedence/fallback cases now pass. - Real tar staging reproduced remote conversation loss in both API-key and subscription modes before the repair. Both now pass: changing managed settings preserves sessions, archives, native indexes, and refreshed subscription credentials. A corrupt upload preserves the prior config and conversation. - Preserved failure evidence: initial CI caught stale Pi/Copilot source attestations, a missing test-harness helper, and packaging fixture/probe mismatches; those were corrected and covered by focused checks. Superseded heads had intermittent attachment-composer timeouts despite successful uploads; [the original trace and screenshot remain available](https://github.com/paperclipai/paperclip/actions/runs/39309701089/artifacts/12215109203). The same attachment case passed on the final head: [25/25 tests in shard 3](https://github.com/paperclipai/paperclip/actions/runs/39319194318/job/118288637051). - A connection-fault fixture also exposed a stale pooled socket after its hang case; closing fixture responses isolated scenarios and the full affected suite passed. - The broad local test run was not clean: database resource failures, timeouts, an older cached module graph, and a stale optional-resource manifest assumption were recorded. Focused checks passed after the documented fixes. This does not establish a clean full local pass. - Native remote Codex, remote Claude, and the full ACPX Codex bridge remain unqualified. The direct Codex resume test does not establish full bridge acceptance. ## Risks - Native exporters perform network requests from each execution environment. A server connection test does not prove remote reachability. - Prompts, assistant responses, and tool content are enabled by default when supported. Native caps and harness-specific controls still apply. - Caller-owned Codex homes are unsupported for automatic configuration and remain untouched. - Native harnesses and their tool processes can inspect export credentials. The settings form and documentation advise using ingestion-scoped credentials. Retained headers remain bound to their saved scheme, host, and port; changing origin requires fresh values or removal. - Migration 0357 adds a company-scoped row and secret reference. It is safe to reapply. Secret removal and company deletion use the existing secret lifecycle. - Slow or unavailable destinations must not block task settlement. Export settings take effect at the next execution preparation boundary. ## Model Used OpenAI Codex, GPT-6, with reasoning, tool use, code execution, and browser verification. The exact serving model ID and context window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
8193abb936 |
feat(claude): default qualified macOS and Linux targets to Paperclip Runner (#15997)
## Thinking Path > - Paperclip must run the selected agent on its selected host. > - Claude needs verified packages for each supported target. > - A Mac controller must select the correct Linux provider pack. > - New defaults must follow package and execution evidence. > - This PR adds Claude platform packaging and target-specific pack selection. > - Existing Codex Linux ARM64 behavior remains intact. ## Linked Issues or Issue Description Refs #15683. This PR depends on #15993 and #15994. Related scope: #15422 and #15224. ## What Changed - Reuse the merged four-target daemon producer/consumer matrix. Add target-owned Linux provider packs and carry their immutable identities through release assembly and vendoring. - Reuse master’s landed pinned Claude SDK ARM64 executable admission and retain package-integrity, architecture and no-follow admission. - Select target-specific remote packs so Mac controllers can use Linux hosts without a development pack override. - Preserve read-only runtime context on SSH startup and resume without accepting unverified old content. - Check ordinary installed Claude readiness without injected package authority. Retain Codex and Linux x64 consumer checks. - Extend Claude automatic target selection for the remaining qualified package targets. Retain unsupported-platform and external-override behavior. - Qualify managed Daytona snapshot names through provider IDs during Claude Connect. Pin native acquisition to the measured ID. Preserve a revocation marker after failed probes or target edits, and block native acquisition until requalification instead of falling back to a mutable name. Preserve immutable-image proof, company and account boundaries, and Legacy acquisition. ## Verification - Reconciled with master `9179d8dcc3e908c217fde4f63c9d08ccf8132eeb` through the prerequisite stack, retaining the merged startup fix and latest Codex Linux ARM64 behavior. - [Four-target exact-source package qualification](https://github.com/paperclipai/paperclip/actions/runs/39267321383) passed on source `04e0202ca81387b17cbe7fd094a8338648356fe9`: all four native builds, public-package assembly, Linux x64 verification and clean installed consumers on Apple Silicon, Intel Mac and Linux ARM64. The later master reconciliation adds shared OpenRouter attribution and changes runtime source. This historical result keeps its original source identity; [later qualification](https://github.com/paperclipai/paperclip/actions/runs/39281100929) passed at `dca62c7aeb4b45f0dd91a8e18d386a16a2658ef8`. It predates the subsequent TypeScript startup fix. - Fresh local product acceptance on integrated source `b2c9fe43f9cd3bc5dd9d22552da0148845ba71a4` completed a useful file and follow-up through native Claude/Opus 5.5, High effort and the API-key connection. Both actual browser downloads were independently checked; the revision preserves the original body and session continuity. Total task estimates: $0.518432800. Ordinary web and API creation saved defaults with the native experiment disabled. - Local focused verification passed 993 startup/session tests, 243 UI tests, 12 workflow security tests, direct server/UI TypeScript checks, and token/palette gates before the last review changes. Initial DB-backed snapshot pin/revocation coverage passed 18 cases; the final serial route suites pass 122 credential/permission and 232 snapshot/environment cases after correcting a test hook timeout. Current-head cloud suites pass. - Preserved the failed pre-provider local fixture and its full pending reservation. The successful fixture has no unpriced or pending usage. Historical failed Cloud journeys, accounting holds, source identities and subscription limitations remain in the dated plan. - All Docker/Rust release production was performed in cloud CI. No local Docker image was built. An inadvertently invoked local Rust prerequisite was stopped. - Current-head cloud CI is green. All three stack PRs have fresh Greptile 5/5 reviews and zero unresolved review threads. Required typecheck, test and build gates ran in cloud CI; Docker work stayed remote. Earlier failed checks remain in their original runs. - The final master merge preserves task-loading, permission, skill-retention and OpenRouter changes. Pi uses a fresh combined profile 27, preserving both historical profile-24 declarations; Copilot remains profile 22. Focused protocol checks passed 155 cases (one skipped), the updated Pi attestation check passed 18 (one skipped), and 91 evaluation/catalog checks passed. - Latest-application manual continuation passed in 37.942 seconds on `695e5c005a85bddc8711d3fcddcaf6b7e1fb64d0`, with High effort, native Opus 5.5, Anthropic API attribution, the same resumed Claude session, an independently checked 635-byte file and persisted Done status. It uses the earlier verified Mac daemon; the preceding-source package qualification passed at `dca62c7aeb4b45f0dd91a8e18d386a16a2658ef8`. That package run predates the small TypeScript startup fix and is not relabeled as qualification for it. - Upgrade limitation: changed compiled sidecar identity rejected old durable launch state and recovery hit session-open bounds before eventually resuming. That attempt was operator-cancelled and retained; the successful manual continuation does not qualify seamless upgrades. - Local latency profile, Opus 5.5/High unchanged: three alternating real-ACP loopback samples per variant reduce median provider-ready time from 5.081s to 4.034s. The matched real API task startup improves from 5.533s to 4.348s, but total reply time changes from 17.933s to 20.221s because agent work varies. This establishes a startup saving of about one second, not a consistent total-reply speedup. A real candidate follow-up passed in 20.146s and resumed the same saved session. The loopback fixture makes no external model requests; failed initial probes remain retained. - The startup change passes 107 focused runtime/effort/lease tests, 53 profile checks (one skipped), TypeScript checking and the TypeScript-only runtime build. Native hire fixture checks pass 70 tests; their first local run retained a socket-hangup failure and stale OpenCode expectation, both accounted for before the passing rerun. Broader required checks run in cloud CI. ## Risks - **Experience needs improvement:** successful connection setup still shows “Connection needs attention” because runtime checks are deferred. Cold provider-pack upload took 122–126 seconds per run while the task mainly showed “Thinking.” The tested Core-only preview excludes private Cloud UI plugins; this is not full Cloud distribution or subscription qualification. Desktop dark theme was tested; mobile and comprehensive accessibility were not. The portable report validates, but gallery interaction could not be inspected because host preview was queued. - The optional supply-chain scan returned neutral/inconclusive because GitHub Actions package coverage and infrastructure parsing are unavailable. It is not counted as a successful supply-chain qualification. Exact package, daemon and image integrity checks passed. - A stale, missing or wrong-architecture pack must fail admission. It must not change runner or target silently. - Provider-pack source changes invalidate affected earlier execution results. Existing unknown-cost and cleanup holds remain intact. - Live subscription execution remains unverified under the API-key qualification direction. Built-in authentication flows are retained. ARM64 cloud-image production is deferred. Merge and production deployment remain separate. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, repository tools, code execution and browser testing. The exact serving model ID and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [ ] Focused local tests and final cloud verification 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> |
||
|
|
95672307f4 |
feat(runner): carry acknowledged Claude effort through native resume (#15994)
## Thinking Path > - Paperclip manages AI agents and their work. > - The native runner must carry each supported agent setting. > - Claude effort must reach its ACP session before a prompt and after resume. > - Installed Claude setup must find the owning server package without a qualification override. > - This PR adds those shared contracts and preserves historical readers. > - The Claude default change can then use the same runner path. ## Linked Issues or Issue Description Refs #15683. This prerequisite follows the actual Codex squash `adb69e8f09852c772d9901ae270e5b2d66e39c77`. Consumers: #15993 and #15997. Related scope: #15422, #13978 and #15224. ## What Changed - Add native-input v9 for Claude effort. Preserve v1–v8 readers, including v7 explicit home modes, v8 Muse, Dot and Grok Bot. - Preserve prepared task input and constraints through the newer contracts, including completion-only continuation without wrapping compact model input again. - Carry effort through daemon/sidecar admission; require provider acknowledgment before prompting and after resume. - Find installed server package authority through the verified canonical layout. Retain package-integrity, digest, architecture and no-follow checks. - Return Claude startup cancellation promptly while retaining unfinished settings writes and the lifetime lease through cleanup. Preserve merged Codex close/cleanup behavior. - Retain both independently authored historical Pi profile-24 declarations. Combined master/Claude source attestations use Pi profile 27; pending Copilot remains profile 22. This does not expand either provider's qualification boundary. - Avoid a spare verified executable snapshot when Claude effort control reuses its initialized provider. Preserve cold-control snapshot renewal and acknowledged effort. ## Verification - Reconciled with master `9179d8dcc3e908c217fde4f63c9d08ccf8132eeb`, retaining its task-loading, progress, skill-retention, permission and OpenRouter changes. - Final focused protocol/provider checks passed 155 tests (one skipped), the updated Pi attestation check passed 18 (one skipped), and 91 evaluation/catalog checks passed. Generated TypeScript/Rust profile checks and Rust formatting pass. The integrated consumer's TypeScript-only runtime build also passes. - Earlier branch checks passed 369 protocol tests (one skipped), 72 catalog checks and TypeScript checks/build; their source identities remain historical. No Rust compilation or Docker build is needed locally for this proof. - Current-head cloud CI is green. All three stack PRs have fresh Greptile 5/5 reviews and zero unresolved review threads. Required typecheck, test and build gates ran in cloud CI; Docker work stayed remote. Earlier failed checks remain in their original runs. - [Earlier four-target package qualification](https://github.com/paperclipai/paperclip/actions/runs/39267321383) passed on source `04e0202ca81387b17cbe7fd094a8338648356fe9`; it is not relabeled as proof for the final merge. Existing failures and unknown-cost holds remain preserved. - Current-head cloud CI is green. All three stack PRs have fresh Greptile 5/5 reviews and zero unresolved review threads. Required typecheck, test and build gates ran in cloud CI; Docker work stayed remote. Earlier failed checks remain in their original runs. - Latest-application manual continuation passed in 37.942 seconds on `695e5c005a85bddc8711d3fcddcaf6b7e1fb64d0`, with High effort, native Opus 5.5, Anthropic API attribution, the same resumed Claude session, an independently checked 635-byte file and persisted Done status. It uses the earlier verified Mac daemon; the preceding-source package qualification passed at `dca62c7aeb4b45f0dd91a8e18d386a16a2658ef8`. That package run predates the small TypeScript startup fix and is not relabeled as qualification for it. - Upgrade limitation: changed compiled sidecar identity rejected old durable launch state and recovery hit session-open bounds before eventually resuming. That attempt was operator-cancelled and retained; the successful manual continuation does not qualify seamless upgrades. - Local latency profile, Opus 5.5/High unchanged: three alternating real-ACP loopback samples per variant reduce median provider-ready time from 5.081s to 4.034s. The matched real API task startup improves from 5.533s to 4.348s, but total reply time changes from 17.933s to 20.221s because agent work varies. This establishes a startup saving of about one second, not a consistent total-reply speedup. A real candidate follow-up passed in 20.146s and resumed the same saved session. The loopback fixture makes no external model requests; failed initial probes remain retained. - The startup change passes 107 focused runtime/effort/lease tests, 53 profile checks (one skipped), TypeScript checking and the TypeScript-only runtime build. Native hire fixture checks pass 70 tests; their first local run retained a socket-hangup failure and stale OpenCode expectation, both accounted for before the passing rerun. Broader required checks run in cloud CI. ## Risks - Explicit Claude effort needs a daemon and sidecar that support input v9. Historical readers stay available; downstream builders and permission-pin transport checks must also use v9. - Source-bound profile changes may require reopening older Pi/Copilot sessions. Copilot remains pending and executable package closures remain unchanged. - This prerequisite changes shared runtime behavior; Claude default selection remains in #15993/#15997. No database migration or Codex default change is introduced. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, repository tools, code execution and browser testing. The exact serving model ID and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
3e5a9f5afe |
perf(ui): load recent tasks with bounded summaries (#16851)
Replace passive recent-task detail reads with bounded, authorized summaries. Keep account isolation, stored history, task actions, and live recovery behavior. Overlap access checks with shell settings and avoid duplicate session and health reads on the first healthy socket opening. Retain domain reconciliation. Add focused coverage and local performance evidence. Isolate the existing cache capacity test from entry expiry on slow CI runners. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
23b2ceb0d1 |
feat(connections): add unified Google Workspace connector (#15545)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Connected Apps supply governed tools to those agents. > - Google services currently require separate connections or one broad request. > - Users need one account and control over which services it can access. > - A picker must change the OAuth request, not just the screen. > - This pull request binds selected services to consent and tool access. > - The benefit is simpler setup without enabling unselected tools. ## Linked Issues or Issue Description **Subsystem affected** Connections catalog, OAuth grants, and the MCP tool gateway. **Current behavior** Google setup uses separate service profiles. A combined request alone cannot express the user's choice before Google consent. Accumulated Google grants can be broader than a new request. **Proposed behavior** Offer one Workspace connection. Let users choose Gmail, Drive (including Docs, Sheets, and Slides), and Calendar. Start all three with read and write access. Let users disable groups or choose read-only access. Do not offer Chat, Contacts/directory, or cross-service Search in new setup. Bind selected scopes to durable OAuth state. Cap effective tool access to both the saved request and provider-reported consent. **Reason and benefit** Users can choose services without managing several accounts. Existing company, identity, agent, and action-policy controls remain in force. **Breaking changes** No database migration. Existing service connections and grants remain supported. New Workspace requests require the companion broker change in https://github.com/paperclipai/paperclip-cloud/pull/823. Old brokers reject narrowed requests safely. Related work: #14740 reduced Google scopes; #14774 introduced the earlier catalog hold. #15412 proposes a separate Gmail REST implementation. This maintainer-requested change extends the existing Connections and governed tool gateway paths. It does not replace them. ## What Changed - Add one Workspace catalog entry and a namespaced action catalog. Retain legacy definitions and saved accounts. - Use the approved production service picker in Apps and task-hosted setup. Keep dropdowns between names and toggles. Block empty selection. - Derive exact scopes from a closed registry. Default selection requests nine scopes. New requests exclude Chat, Contacts/directory, and Search scopes. - Bind selected scopes through managed and customer-owned OAuth state, callback, claim redemption, and refresh. - Cap accumulated Google grants to the saved selection. Recheck grant-specific permission at discovery, listing, and dispatch, including cached actions. - Restore the current subject's saved request on reconnect. Block on grant-load failure. Preserve draft selection on cancel and retry. Do not create an account on picker cancellation. - Preserve healthy services during partial outages, without combining grants across identities. Keep writes from being automatically replayed. - Preserve the original 21-scope legacy Workspace envelope contract as individual profiles evolve. - Add production-component Storybook stories, request validators, consent regression tests, and rollout guidance. Integrate the stories with the current feature catalog while preserving their IDs. ## Verification - Integrated branch merges current master and has no merge conflicts. - Full workspace build passed on the integrated checkout. - Token gates passed. Storybook catalog structure check passed: 283 files and 2,750 stories. - Final affected app suites: 914 passed. This includes 502 database-backed service/gateway tests and 412 UI/shared/validator/broker-handoff/governance tests. The production picker tests cover defaults, identity-specific reconnect, and failed-load recovery. - Full workspace typecheck passed after adding required current-master Storybook annotations. The final UI build also passed. - The full repository suite is still running and includes the two pre-fix retry assertions. Both were updated for the current gateway's explicit-retry contract and pass in the clean 502-test database run. No complete final-head full-suite pass is claimed. - The initial local database startup failure came from missing native-library symlinks in the fresh dependency install. The package's postinstall repair fixed it; the clean database-backed run has no skipped tests. - Broker focused suite: 47 passed, including real signed session → callback → claim redemption and wrong-scope rejection. Full broker suite before the final test-only follow-up: 3,562 passed, 103 skipped. - Real integrated-app walkthrough: Connectors → Workspace → customer-owned app → service picker. Verified all three defaults, empty-selection blocking, cancel/reopen with the selected read-only access preserved, preserved form values, and zero saved connections after cancel. Credentials were synthetic; no Google grant was made. - Current-head CI and Greptile review remain pending. Previous-head results are not treated as current. ## Risks Ship the companion broker before app instances send narrowed requests. Enable the intended Workspace client/profile separately on the target broker. This pull request does not deploy a tenant app, start a fleet rollout, alter Google Console, or upgrade the pinned reviewer stack. The three-group picker is not proof of live provider access. Before production, verify a real selected-service grant, reconnect, refresh, allowed reads/writes, and denied unselected actions on the isolated staging reviewer app. Google verification and preview enrollment remain separate requirements. Legacy service profiles stay compatible. New grant metadata keeps provider scope evidence separate from requested scope evidence. Missing or unsupported evidence fails closed. No scope union across user or organization grants is allowed. ## Model Used OpenAI Codex, GPT-5-based coding agent, with repository editing, code execution, and browser tools. The exact serving model ID and context-window size were not exposed. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal issue ID - [ ] I have run all final-head 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 risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
9179d8dcc3 |
fix: credit Paperclip for managed OpenRouter requests (#16850)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - AI connections choose credentials and routes independently of the agent harness. > - OpenRouter assigns app credit from the final request headers. > - Harness defaults can assign Paperclip work to the underlying harness. > - This pull request applies one public Paperclip identity to managed OpenRouter requests. > - The benefit is consistent app credit across supported harnesses and internal model calls. ## Linked Issues or Issue Description **What existing behavior does this improve?** App attribution for existing OpenRouter connections and explicit provider configurations. **Current behavior** Requests can omit attribution or carry the harness identity. Paperclip does not receive consistent credit in OpenRouter rankings. **Proposed behavior** Use `https://paperclip.ing`, the title `Paperclip`, and the coding categories `cloud-agent,programming-app` for managed requests to OpenRouter. Keep credentials, routing, and unrelated providers intact. **Reason and benefit** The provider URL identifies the app across personal and shared API keys. A search of public issues and pull requests found no duplicate attribution work. This improves existing AI connections and does not add a separate roadmap feature. ## What Changed - Add a shared attribution policy and a parity-checked copy for the standalone Runner. - Apply it to managed Codex, Claude, OpenCode, and Hermes connections, plus native Pi and explicit legacy provider configs. - Preserve attribution across Codex config filtering, Claude environment filtering, OpenCode proxy requests, and model-level overrides. - Attribute direct fast-response and decision-model requests, including custom connections to the OpenRouter endpoint. - Add positive and negative regression tests and provider attribution requirements to the connector playbook. - Advance native Pi to profile 24, preserving historical identities and binding the attribution source in its declaration and release checks. ## Verification - Final head `6df282d2a58c2698e41127443903d6fc85b4b72f`: all CI/status checks passed or were intentionally skipped; Greptile is **5/5**, with zero unresolved review threads. [Final CI run](https://github.com/paperclipai/paperclip/actions/runs/39274938069). - Focused server/shared/config suites: 132 tests passed before the final edge-case additions. Expanded adapter suites pass 48 tests; the final OpenCode merge passes 15 tests; global/EU/US endpoint and policy-parity suites pass 26 tests. - Focused Runner suites: 85 tests passed, including model overrides and recovery/config boundaries. Profile installation/environment/config tests subsequently passed 72 tests (one optional distribution test skipped); historical decoding passed 11 tests and updated recovery coverage passed 27 tests. The Rust profile admission test and all five native Pi launch/recovery tests passed. - All 114 managed AI connection tests pass together. They include custom-header preservation for legacy and native Claude runs, both OpenRouter and other gateways, inherited headers, and unresolved secret references. - Actual requests from installed Codex 0.160.0, Claude Code 2.1.245, OpenCode 1.18.34, Pi 0.74.0 and 1.0.0, and the managed Hermes runtime carried all four Paperclip headers. A local endpoint used dummy credentials and returned an intentional 401 after capture. Codex and Claude retry requests retained attribution. This proves outgoing header precedence; it is not a successful model-inference test. The first Claude capture had an argument-separation error and sent no request; correcting the command produced the captured requests. - A live request through `fastResponseModel` completed with `attribution verified`. OpenRouter recorded generation `gen-1792420273-Ez1GUTCc7YuZ1FJMCGob` under app ID `3118063`, at a cost of $0.00000375. The public app record maps that ID to `https://paperclip.ing/`. - Full `pnpm -r typecheck` and `pnpm build` passed, including a repeat after the review fixes. The final server build stamp records commit `6df282d2a58c2698e41127443903d6fc85b4b72f`. `pnpm check:token-gates` passed. - CI first caught the stale Pi source attestation; it is now a new immutable profile. Greptile caught custom-header loss, now fixed and covered by the complete managed-connection suite. The next CI run caught the missing Docker allowlist entry for profile 24; the allowlist and release smoke pins are now synchronized. Local Docker verification cannot run because its daemon socket is absent; The exact Docker context check passed in CI on the final head. - The initial local `pnpm test:run` did **not** pass. It ran across source/build edits, reported chat/tool-access collection failures, three workspace-runtime failures, two new managed-header failures, one Dot Runner readiness failure, and two native-session-resume failures, and was interrupted after the final-head CI server coverage passed. Its secrets suite also reported 91 cases skipped. The isolated tool-access suite passed all 428 tests, and the complete managed-connection suite passed all 114 tests. These retries establish recovery, not the cause of the original local failures; no claim of a successful full local run is made. Final acceptance uses immutable final-head CI plus the focused local and live checks above. - Final-head CI encountered one unchanged UI assertion in `FileViewerSheet.copy.test.tsx` (missing “Copied link” feedback after clipboard completion). That shard passed on the earlier head with identical UI code, and all six clipboard tests passed locally. A timing race around the asynchronous React update is suspected but not conclusively established. The single CI retry passed, with no product/test code changed for it. The earlier failure remains part of this verification record. ## Risks - Native Pi profile 24 requires a fresh provider session when encountering a profile 23 identity; recovery tests cover that boundary. - Harness upgrades can change header precedence. The playbook requires actual request capture when changing provider paths. - Externally managed agents, unmanaged harness settings, and gateways that replace headers need separate qualification. This change does not intercept arbitrary model calls made by task scripts. - The existing OpenRouter entry for the Paperclip URL still displays an old title, “PrettyFly Opus Testing,” and no categories on the final public-page recheck. The live request received credit under that URL's app ID. Public title propagation and leaderboard placement remain controlled by OpenRouter. - Global, EU, and US OpenRouter hosts are recognized explicitly; other subdomains are not treated as OpenRouter. No database migration, credential ownership change, or Paperclip telemetry event is involved. Attribution contains public product constants only. ## Model Used OpenAI GPT-6 through Codex, with reasoning, repository editing, shell execution, web research, and live API verification. The exact deployment identifier and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass — the focused suites listed above; the unsuccessful full local attempt is explicitly recorded, with full final-head coverage supplied by CI - [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> |
||
|
|
a7504784e5 |
perf(chat): avoid snapshot reads in native progress polls (#16845)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Chat connectors publish safe progress from native runs. > - A recurring query joins each run to its conversation through JSON context. > - Large snapshots make repeated JSON reads expensive. > - Issue-scoped runs already have a typed issue binding. > - This pull request uses that binding and retains the legacy JSON fallback. ## Linked Issues or Issue Description **What existing behavior does this improve?** The native chat-progress candidate query in `enqueueSafeNativeChatProgress`. **Subsystem affected** `server/` database queries and chat publication. **Current behavior** The conversation join extracts `issueId` from each run's JSON snapshot. A local plan probes the run repeatedly and reads a large snapshot for each probe. **Proposed behavior** Use the run's typed `issue_id` when present. Read the JSON key when that column is null. Keep the existing company, endpoint, event, publication, cursor, and cadence conditions. **Reason and benefit** Avoid repeated snapshot reads for scoped runs. Related: #15802 changed delivery queue scheduling; it left native progress projection on its existing cadence. ## What Changed - Change only the native-progress conversation join. Leave the separate milestone query, which already uses its expression index, unchanged. - Add a disposable PostgreSQL benchmark that captures the real service SQL and compares complete rows on one shared fixture. It includes a legacy null binding, unrelated tenants, 2,400 historical decoys, and 144 KiB of random bytes per snapshot (about 192 KiB after base64 encoding). - Compare cardinality across independent fixtures. Their generated conversation and event IDs are not deterministic. - Add PostgreSQL regressions for a typed issue binding without the JSON key and for the legacy NULL-column fallback. ## Verification - Full-size paired local measurement: native baseline 57.67 ms median, treatment 19.35 ms median, **2.98× faster**. Both return the same 41 complete rows. Five timed samples follow warmups, with baseline and treatment alternated. The unchanged milestone query is a control. - An independent full-size run also passed complete row equality and measured 65.22 → 24.08 ms (2.71×). - The small 1 KiB control passed the same 41-row equality check and was neutral: 15.20 → 15.45 ms median. The improvement targets large snapshots, not small payloads. A repeat of the final JavaScript entry point also passed equality and measured 2.97× while the full test suite was running; its wider timing spread is not the primary performance result. - Four PostgreSQL cases pass: typed issue scope without a legacy JSON key, NULL-column JSON fallback, native-progress cadence, and paused-endpoint no-replay behavior. The remaining tests in that file were excluded by the name filter. - Reproduce with `node --import ./cli/node_modules/tsx/dist/loader.mjs scripts/benchmark-chat-native-progress.mjs --phase=baseline` before applying the query change. Run the same command with `--phase=treatment` after applying it. The tool stores SQL, parameters, plans, all samples, and equality evidence under `.scratch/`. - Full workspace typecheck and final server typecheck passed locally. Four focused PostgreSQL cases passed. The duplicate unsharded local full-suite run was stopped after the same commit passed all CI test shards; the full local tests/build sequence was not completed. CI Build and the aggregate verification gate passed on that commit. - Current-head CI is green at `82c9ef9` (55 successful checks, two valid skips). An unchanged runtime-supervision test failed in the first attempt; its isolated local reproduction passed, and one failed-job rerun passed on the same commit. The local reproduction runs on macOS and does not exercise the Linux process-identity branch. - Greptile reviewed `82c9ef9` at 5/5 with no unresolved threads. ## Risks - The typed issue binding takes precedence when present; older rows retain JSON fallback. Company and publication ownership checks remain in the query. - Measurements use local embedded PostgreSQL 18 with synthetic data. The hosted motivation used PostgreSQL 17. Absolute timings and plans can differ on other compute and data distributions. - The milestone benchmark returns an empty candidate set and is a performance control; the nonempty native comparison is the correctness and performance target. - No schema migration or provider network request is added. This PR does not deploy a query change to a live database. ## Model Used OpenAI GPT-6 through Codex, with reasoning, repository inspection, tool use, and code execution. The exact serving model ID and context-window size are not exposed. Z-AI GLM 5.3 Prime through OpenRouter (`openrouter/z-ai/glm-5.3-prime`) assisted the initial query treatment and benchmark. Codex repaired the comparison, narrowed the production change, and ran the full-size proof. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
98ca6ff7c5 |
perf: reuse verified provider files during sandbox startup (#16493)
Build provider-pack transport layers once, reuse verified image files in private directories, and upload only missing layers. Preserve archive integrity checks and directory fallback on unsupported hosts. Verified with 44 focused tests, all 48 main CI jobs, cloud Docker Runner checks, and Greptile 5/5 on the merged head. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
9077748894 |
Remove the Pipelines experiment and preserve its data (#16834)
## Thinking Path > - Paperclip manages AI agents and their work. > - Pipelines was an unused experiment with its own UI, API, CLI, and automation. > - Keeping it leaves unsupported product surfaces and extra task-detail queries. > - Removing the experiment must preserve data that users already saved. > - This pull request removes the feature and keeps its database schema and migration history. > - Cases and Routines remain available as separate features. ## Linked Issues or Issue Description **What existing behavior does this improve?** Remove the unused Pipelines experiment across the application. **Current behavior** The experiment includes pipeline boards, stage settings, case automation, review queues, learnings, permissions, and CLI commands. Task detail also queries pipeline links. **Proposed behavior** Remove all these product surfaces and their implementation. Preserve existing tables, records, and documents. Ignore the retired boolean in older managed configurations so upgrades still start. **Breaking changes** Pipeline URLs, API endpoints, CLI commands, and `pipelines:write` are removed. Task detail no longer includes the old `linkedCases` field. The independent Cases API remains available. No database migration or cleanup is included. Related feature work: #7907, #9110, #10905, #11375, #13004, #14671, #16133. Related issues: #9663, #10310, #10312. This removal supersedes the feature; it does not implement those pending enhancements or delete their saved data. ## What Changed - Remove Pipeline UI pages, navigation, gates, clients, query keys, helpers, and unused design tokens. - Remove Pipeline REST routes, services, automation dispatch, task-detail queries, and OpenAPI discovery. - Remove the CLI commands, shared contracts, experimental flag, catalog entry, and permission defaults. - Remove feature-specific tests, tutorials, smoke scripts, maps, and Storybook examples. - Preserve database schema, migration history, and the reserved document key used by old records. - Keep Cases routes independent and cover obsolete stored and managed settings. ## Verification - Passed: `pnpm build` and `pnpm -r typecheck`. - Passed: targeted settings, managed configuration, sidebar, settings UI, routing, and feature-catalog tests. A first sidebar run caught a shared Workspaces icon import; the import was restored and the sidebar rerun passed. - Passed: 40 tests covering Cases routes, OpenAPI discovery, retained Pipeline table constraints, and schema snapshot drift. - Passed: token gates, map validation, generated API metadata check, Storybook catalog validation, and 28 map/catalog tests. - Passed: isolated local browser verification of navigation and Experimental settings with Pipelines absent; Cases and Routines still open normally. Live GET/POST requests to retired Pipeline endpoints return 404, and the retired setting is absent. CLI help has no Pipeline commands. - Passed: 22 access-service and agent-default-grant tests after restoring unrelated permission assertions flagged in review. - Local full run: `pnpm test:run` reported one failure in the unchanged workspace-runtime port-allocation test. That test passed in an isolated rerun. The long local run was stopped after full CI passed; it is not reported as a complete local pass. - Passed: all 56 checks on `def9181f3a4491d95fca1d38e9739f5b821aae3e` (2 conditional checks skipped), including build, typecheck, test shards, and browser suites. Eleven interrupted CI jobs reported “The operation was canceled”; their one-time retry passed. [CI run](https://github.com/paperclipai/paperclip/actions/runs/39255211006). - Greptile: 5/5 on the final commit, with the only review finding fixed and resolved. - Sandbox socket restrictions affected the first build/API test attempts. The same commands ran with local sockets available. ## Risks - Existing Pipeline clients must stop using the removed endpoints and commands. - Existing data remains in the database and backups, but the removed UI no longer displays it. - Historical boolean `enablePipelines` values are ignored. They cannot restore the feature. - Cases and Routines must retain their separate behavior. Targeted route tests cover this boundary. ## Model Used OpenAI Codex, GPT-6, with repository inspection, editing, shell execution, and browser verification. The exact deployed model ID and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
896f3c7f3b |
Add personal Muse operator setup and composer controls (#16450)
Add Muse invitation, connection readiness and scoped operator controls.
Keep connection state tied to the current company, person, agent and binding. Surface failed reads and invalidate stale cleanup observations; require current authority and exact readback. Preserve Dot/Grok setup, source-trust limits and existing design tokens.
Carry actual merged backend
|
||
|
|
e6dcc6b095 |
Connect personal Muse through secure native execution and Vault OAuth (#16448)
Add company-scoped Muse native control, OAuth, wake receiver and recovery. Recheck current authority after waits and before effects or receipt replay. Preserve task-read scope, assignment expiry, independent holds, nonblocking reassignment and truthful cleanup provenance. Retain source trust on progress comments and verify current Muse V8 authority through real signed-JWT HTTP requests. Preserve the upstream trimmed ordinary authentication lookup. Refs #16448. Preserve captured canonical queue recovery and concurrent environment preparation while retaining the scoped Muse V8 exclusion. Normal migration 0354 and existing Muse SQL remain unchanged. Fresh current-head Greptile review is 5/5 with the project-write finding addressed. Required CI and independent technical review gate the merge; maintainer override is reserved for formal approval rules. Recheck current Muse project-write authority after all receipt/task/run/admission waits, before creation or replay. Real PostgreSQL regressions reproduce four late effects/replays on the old route; the repaired three-file treatment passes 354 cases with no skips, and the scoped server typecheck passes. Ordinary/Dot behavior is preserved. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
e30550ef39 |
refactor: remove code comments added by recent PRs (#16681)
CONTRIBUTING.md says PRs add no code comments, but #16485, #16586, #16621 and #16672 added some. This removes the 215 comment-only lines git blame on master attributes to those merge commits, across 12 code files, plus one blank line the removal left doubled. Rewritten (not added) comments in scripts/assert-cloud-image-sentry.mjs and comments in .github workflows are left alone. No code changes. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
27ab902d3d |
perf(docker): start the server from a precompiled runtime bundle (#16672)
The production image started the server through the tsx loader, which resolved about 3,100 modules and transpiled about 1,200 workspace TypeScript files on every boot (7.6-20 s before listen on a live instance). A build:runtime step now bundles server/dist/index.js with esbuild, compiling in the workspace packages, and the image starts node server/dist-runtime/index.mjs. Server dependencies stay bare so runtime resolution (including the cloud image's optional peers) is unchanged; each module keeps its original import.meta location; dynamic imports stay split; the entry presents the original dist/index.js as argv[1]. The avatar worker loads through tsx's API when the main thread has no loader, tini runs as a subreaper (-s), and PR CI boots the bundle with scripts/server-boot-smoke.sh. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
2cc7992369 |
Share the external Runner lifecycle and add strict Muse contracts (#16444)
Add the external Runner foundation with distinct Dot/Grok V6, canonical home-mode V7 and Muse V8 contracts. Keep generated schemas and profiles synchronized. Bound default question-answer command IDs in a disjoint namespace while preserving existing IDs and durable replay. Preserve canonical migration history and add normally generated, replay-safe Muse schema milestones with literal preview-history fixtures. Refs #16444. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
4de6335c3b |
perf(server): trim saved run JSON from agent authentication (#16577)
## Thinking Path > - Paperclip coordinates AI agents that work for companies. > - Agent JWT authentication checks each request against its saved run. > - Saved runs can contain large prompts and result payloads. > - The first run lookup needs only identity fields, cancellation state, and the conversation flag. > - Reading all saved JSON transfers data that this lookup does not use. > - This PR selects the required JSON fields in PostgreSQL and preserves the existing authorization decisions. ## Linked Issues or Issue Description **What existing behavior does this improve?** The initial saved-run lookup in agent JWT authentication. **Subsystem affected** Server authentication and database queries. **Current behavior** The lookup transfers the full context and result JSON on each request. It uses only the cancellation state and conversation flag from those values. **Proposed behavior** Select the required JSON fields in PostgreSQL. Keep the run, company, and agent predicates. Read current state on every request. **Reason and benefit** A synthetic lookup with a 96 KiB prompt and 4 KiB result returns 102,520 JSON bytes before this change and 134 bytes after it. This reduces data transferred by this query. **Breaking changes** None intended. Identity fields, write revocation, read access, and cancellation response codes retain their current behavior. Related: #9280 addresses authentication round-trip counts. This PR only reduces the data returned by the existing initial run lookup. ## What Changed - Extract the initial run lookup and select only the JSON fields that authentication consumes. - Add real PostgreSQL tests for legacy JSON shapes, fresh cancellation state, payload size, and run/company/agent scope. - Add a reproducible benchmark that loads the original query from an explicit baseline commit. - Document the lookup and benchmark. ## Verification - Baseline: `06689c1b3410000bcd65ff40cb469e600209c4db`. - `pnpm -r typecheck`: passed. - `pnpm build`: passed. - Final server typecheck: passed. - Final-head GitHub checks: all green at `2be1c38e6bf51616b69993cf84cee1eef9657517`. Apex: 5/5, zero unresolved threads, conflict-free. - `pnpm check:module-boundaries`: passed. The standalone synthetic benchmark now uses the existing root benchmark directory and resolves Drizzle through the server workspace. - Focused HTTP middleware and database tests: 29 passed on real Homebrew PostgreSQL 16.14. The SQL test compares 270 combinations of status, cancellation JSON, and conversation JSON. It also checks fresh state and company/agent/run scope. - Broad native verification: 873 passed across the HTTP middleware, SQL projection, run diagnostics, and native executor suites. - The default local full command completed its general server lane with 12,090 passed and 8,885 skipped tests. It could not finish the root workflow: the host could not start the bundled PostgreSQL; a diagnostics assertion matched a directory name; and Git fixtures retained the host default branch. These failures remain in the verification record. All 68 failed files now pass on replay with disposable Homebrew PostgreSQL, an isolated checkout, and command-scoped Git defaults. The 68-file replay passed 2,588 tests and left two email skill-resolution failures. Moving the checkout outside an unrelated ancestor skills directory resolved those last failures: all 44 tests in that file passed. Product code and test assertions were unchanged for these host adjustments. Benchmark command: ```sh pnpm --filter @paperclipai/server exec tsx ../scripts/benchmark-agent-authentication.ts --baseline-ref=06689c1b3410000bcd65ff40cb469e600209c4db ``` The final benchmark ran at treatment commit `2be1c38e6bf51616b69993cf84cee1eef9657517` with a clean worktree. The local run used PostgreSQL 16.14 and the maintained test constructor seam to start disposable Homebrew clusters. The bundled PostgreSQL binary could not start on this host. Both versions use the same schema and predicates. Each case has two warmup rounds and ten measured rounds with alternating order. Random content prevents unrealistic compression. Complete authentication decisions match. | Context / result | Before JSON bytes | After JSON bytes | Before median | After median | | --- | ---: | ---: | ---: | ---: | | 1 KiB / 4 KiB | 5,240 | 134 | 0.157 ms | 0.157 ms | | 96 KiB / 4 KiB | 102,520 | 134 | 0.331 ms | 0.140 ms | These are local query round trips, including result transfer and decoding. The small control has no material latency gain. The large case improves by about 2.4x. Both plans read the same single row. The primary result is reduced response size. This does not measure HTTP latency, server CPU savings, or fleet-wide cost savings. Full samples and plans are retained with the verification evidence. ## Risks - JSON types must retain their meaning. The real database tests compare the consumed authorization contract with the original projection, including SQL null, JSON null, scalars, arrays, objects, string booleans, and cancellation states. - The change covers the first JWT run lookup. Later run identity capture keeps its existing full-run reads and transaction locks. Those reads remain a separate cost. - The change adds no schema migration or authorization cache. ## Model Used OpenAI GPT-6 through Codex, with reasoning, code editing, and shell tools. This session did not expose a more specific serving model ID or its 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> |
||
|
|
ce0eff7d1f |
perf: reduce fresh workspace clone and sandbox staging waits (#16487)
## Thinking Path > - Paperclip manages AI agents and their work. > - Each run needs a private workspace and safe persistence. > - Fresh isolated repository sources download upstream Git history again. > - Sandbox staging also verifies an optional seed cache before it uploads the workspace. > - That verification holds a company lock during a full extraction and hash scan. > - This pull request reuses pristine Git objects through an authenticated remote clone. > - It also overlaps seed verification with upload and moves verification outside the publication lock. > - The benefit is less repeated transfer and less serial preparation work, with the same task isolation and recovery contract. ## Linked Issues or Issue Description **What existing behavior does this improve?** Fresh task-private repository preparation and inbound sandbox workspace staging. **Current behavior** Each isolated remote source clones the full upstream history. Optional seed verification then extracts and hashes another full tree before upload. One workspace's verification can hold the company cache lock while other workspaces wait. **Proposed behavior** Use a company and credential scoped cache of pristine upstream objects for GitHub HTTPS sources. Each task still clones from the current remote. It disconnects from the cache before publication. Run seed verification alongside upload. Hold the company lock only for final capacity checks and publication. **Reason and benefit** These operations lie on the workspace preparation path. Removing repeated Git pack transfer and serial verification can reduce startup time. Local measurements below cover these boundaries. They do not establish hosted agent latency. Related: #16425, #16454, #16398, #16461, #16468, #16473. The cache inspection and durable folder proposal in #13376 covers separate product work. ## What Changed - Add a pristine upstream Git object cache for fresh isolated GitHub HTTPS sources. Key it by company, repository and current credential fingerprint. Do not store credentials. - Keep online clone authorization and current remote refs. Use `--reference-if-able --dissociate` so task objects remain independent. A reference failure retries once online without the cache and resolves credentials again. - Cap cache storage at 64 entries and 4 GiB per company, with 2 GiB per entry. Skip contended publication. Bound priming by a cooperative five-second budget and a 4,096-entry scan allowance. Keep the existing free-space reserve. - Overlap optional seed verification and required workspace upload. Settle both before returning or deleting temporary files. Recheck quotas and company directory identity under the publication lock. - Keep the independent fresh upstream reproducibility proof, task commits, dirty source copies, ignored files, nested repositories and durable recovery behavior. - Suppress optional Git server-info generation during dissociation so generated storage passes the existing safe-expiration checks. This uses [the supported Git setting](https://git-scm.com/docs/git-config/2.43.0#Documentation/git-config.txt-repackupdateServerInfo). - Add bounded timing phases, regression coverage and two repeatable local benchmarks. No first-party Telemetry or dependency changes. ## Verification - `pnpm -r typecheck`: passed. - `pnpm build`: passed. - Affected adapter suites: 240 tests passed. Native workspace persistence/history and tracing: 33 tests passed. Server checkout/isolation/tracing batch: 53 tests passed. Final object-cache authority, path and capacity suite: 12 tests passed. These batches overlap. - Cache and expiration/restoration lifecycle batch: 34 tests passed. A direct generated-storage check covers cached clones. - Real HTTP Git fixture: a matching cache does not bypass revoked remote access. Other fixtures cover current refs/tags, hidden cached commits, independent objects after cache removal, corruption fallback, credential/company scope, quota limits and publication contention. - Initial restricted runs hit SQLite write and Unix socket permission failures. The adapter batch passed with disposable writable instance state and socket access. The first typecheck rejected the test use of `Promise.withResolvers`; typed deferred gates now use the supported library contract. - Repository benchmark on final head `9047368bf3b7fa2061e00d698b8b51cf4ae1da32`: five alternating samples, real local `file://` Git transport, synthetic 32 MiB history, no injected latency. Median 1143.8 ms to 240.5 ms; ranges 1085.7–1486.6 ms and 188.0–254.8 ms. Received Git pack bytes fell from 33,569,788 to zero. Initial cache priming took 1208.4 ms and is reported separately. - Sandbox benchmark, five alternating samples per mode on 10,000 files with real packing, extraction and verification: with a controlled 3-second transfer delay, median 9.450 s to 7.620 s (ranges 9.280–12.115 s and 7.296–7.983 s). With no injected delay, median 6.808 s to 6.450 s (ranges 6.255–7.029 s and 5.709–6.902 s). The no-delay ranges overlap; local copying competes with verification for disk. Both modes verify final tree contents, ignored-file exclusion and Git HEAD. These are synthetic local fixtures, not hosted agent runs. - Reproduce with `pnpm --filter @paperclipai/server exec tsx ../scripts/benchmark-repository-object-cache.ts` and `pnpm --filter @paperclipai/server exec tsx ../scripts/benchmark-workspace-staging.ts --baseline-ref=307eb16c0c --transfer-delay-ms=3000`. - Prior head `af766bc820` received Greptile 5/5 with no findings. Its E2E shard 7 failed in `plan-task-fixture` cleanup: company deletion raced an `activity_log` foreign key. That fixture has no provider run or Git workspace. The failure is retained here; final-head CI must pass. The corrected corruption fixture now forces a pack and verifies a real damaged archive. Current head `9047368bf3b7fa2061e00d698b8b51cf4ae1da32` has Greptile 5/5 with no review threads or findings. Final head has 55 passing checks and two optional Storybook skips. [The first workspace-shard attempt](https://github.com/paperclipai/paperclip/actions/runs/38802441857/job/116655485350) passed all 1,778 cases, then reported a late `EPIPE` from unchanged `server-utils.ts` while the ACP reuse test was active. That case mocks workspace preparation and passed locally in isolation. [Its single retry on the same commit](https://github.com/paperclipai/paperclip/actions/runs/38802441857/job/116659728034) passed, as did the dependent verification gate. The earlier E2E cleanup fixture passed on this final head. Both initial failures remain recorded here. A full local suite was not duplicated; the affected boundaries were run locally and the complete suite runs in CI. ## Risks - First cache population adds local copying. Cold clones, credential rotation, capacity exhaustion and a corrupt cache retain the online clone path. No eviction is added. Cached data is bounded, but many companies can each consume their allowance. - Individual filesystem calls and cleanup can exceed the cooperative priming budget. Failed reference clones make one additional online attempt. - Parallel verification and upload compete for disk and CPU. The local no-delay benchmark shows a smaller gain than a slow-transfer case. Verification still checks contents before cache publication, and required upload failures remain failures. - Local fixtures do not prove hosted throughput or the 15–30-second end-to-end target. The fresh checkout still writes its working tree, and model startup, copyback and other preparation costs remain. ## Model Used OpenAI Codex, GPT-6 family. The exact serving model ID and context window are not exposed in this session. Used reasoning, source editing, shell tools and test execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes: #` / `Refs: #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change and contains no internal task identifiers - [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> |
||
|
|
fa9f3f8a08 |
feat(runner): support preconfigured user homes for Codex and ACPX (#16486)
## Thinking Path > - Paperclip manages AI agents and their work. > - Runner launches the selected provider and keeps durable session state. > - Runner currently prepares private provider homes for each session. > - Operators can already have working login, skills, and MCP configuration on the execution machine. > - This PR adds an explicit mode that uses that existing setup. > - Runner keeps its task bridge and session ownership while leaving the user's configuration in place. ## Linked Issues or Issue Description **Problem or motivation:** Rebuilding a provider home is unnecessary when the execution account is already configured. **Proposed solution:** Add `homeMode: "preconfigured"` to Runner adapter config and runnerd transport options. Keep `"isolated"` as the default. Initially support native Codex and ACPX Claude. **Alternatives considered:** Continue copying user configuration into a private home, or add an approval workflow. Both add work outside this feature's scope. **Roadmap alignment:** This extends the existing cross-provider Runner. It does not add another runtime. Related work: #14056 covers managed Codex credentials. #14474 covers command environment delivery. This mode uses user-owned credentials and retains the existing launch boundaries. ## What Changed - Add a closed v7 launch contract for the selected home mode. Existing contracts retain their behavior. - Keep homeMode under operator control. Reject task overrides and agent-authenticated changes, including removal through replacements, adapter changes, or rollback. Ignore stored task values and exclude it from automatic hire inheritance. - Skip managed AI login, assigned-skill materialization, and external MCP setup in preconfigured mode. Preserve the Runner task/completion bridge. - Keep protocol state and provider lifetime fences scoped to the Runner session. Different sessions can share a home. - Fail preconfigured ACPX planning/read-only launches before provider admission until a read-only user-home launch is qualified. Use isolated mode or native Codex for planning. - Reject ACPX approval requests. Keep native Codex on `never`. Local permission rules and hooks remain effective. Initially require the default Runner ACPX `approve-all` setting; other Runner policies are unqualified in this mode and fail before launch. - Keep the internal ACPX bridge in a stable session namespace, preserving an existing user MCP server named `paperclip`. - Reject preconfigured ACPX Codex before launch until a session permission profile can enforce Runner-state denial. Remove the unprotected full-access mode switch; use native Codex or isolated mode for that model family. - Bump Pi to profile 23 because its attestation covers shared Runner source changed here. Preserve profile 22 for historical recovery, and update Docker/package verification inputs. - Fence recovery on mode and home bindings. Fail missing provider-history recovery without starting a replacement session. Exclude the external Codex home from backups and credential cleanup. - Discover remote HOME on the execution machine. Do not project controller HOME or XDG paths onto it. - Separate task instructions from Codex ACP isolation and update the generated provider digest. - Keep remote configured-environment manifests consistent when dropping controller paths. Preserve exact Claude model IDs through per-launch environment settings, without editing the user home or patching the provider. ## Verification - Targeted local checks cover native contracts and launch allowlists, user-config preservation, provider admission, permissions, session recovery, remote environment projection, heartbeat preparation, and operator-only configuration. Runner, shared, and server TypeScript checks and the Rust binary build pass; generated ACPX profiles are current. - Following the latest master integration, all 757 server configuration/executor tests and 115 Runner admission/recovery tests passed. Additional review-fix checks passed: 103 planning contract/host tests, 78 provider-backend tests, 95 route/preparation/inheritance tests, 43 task-validator tests, and 43 workspace-policy tests. Counts describe separate runs and can overlap. - The real pinned Claude ACP/SDK regression reproduces exact-model aliasing without the fix (`claude-sonnet-5-5` becomes `sonnet`) and passes with the fix. All 89 adapter tests pass. User settings remain byte-for-byte unchanged. - Localhost-only Claude SDK probes with synthetic credentials verify the private bridge runs, local `ask` reaches the existing reject callback, local `deny` blocks without a callback, and a user MCP server named `paperclip` remains available. No user model allowlist is required. - Review regressions cover fail-closed provider admission, saved-mode recovery before routing, controller-home path removal without configured-environment manifest drift, pre-launch rejection of unqualified read-only ACPX launches, and denial of task/agent changes to the operator-owned home mode. - Before rebase, `d4d4ee2aebe4cb88c4f4d9ef8e22fed4b36b87be` received standard Greptile 5/5 with no unresolved threads. Prior Apex findings are fixed and covered by regressions. No manual Greptile retrigger is requested for this rebase, per reviewer direction. - The prior PR head and master hit the same GitHub runner encoding crash in workspace-b on three PR attempts, including diagnostic logging ([prior PR CI](https://github.com/paperclipai/paperclip/actions/runs/38818474563/job/116714538405), [prior master CI](https://github.com/paperclipai/paperclip/actions/runs/38819528748/job/116712423193)). Rebased onto `origin/master` at `c3ffa3f0dd` to pull in its bridge-test index correction. The rebased head `edd153db410bea063b645e0000aa68649f287b00` passes all CI checks ([CI run](https://github.com/paperclipai/paperclip/actions/runs/38824676914)), including workspace-b. Greptile's automatic standard review is 5/5 on this exact head, with no unresolved threads; no manual review was requested. - Local workspace-b investigation passed 911 shared tests and 3,868 tests across the remaining 15 workspace projects. The catalog run separately hit an existing ignored `.agents/skills/design-guide/SKILL.md` description-budget violation in this checkout; that file is untracked, outside the PR, and left untouched. Repeating shared tests with CI reporting enabled also passed. - Rebase verification: the final Git tree exactly matches the previously reviewed branch combined with current master. All 192 Runner admission/contract tests, 61 server preparation/provider tests, and 68 bridge tests pass, as do Runner/server TypeScript and generated-profile checks. The real Claude adapter fixture hit an `ENOTEMPTY` cleanup race on its initial run; all 89 adapter tests passed on retry. - Apex on rebased head `edd153db` returned 2/5: ACPX Codex selected full access without enforcing Runner-state denial, and agent configuration replacement could remove the operator mode. Both are fixed in `26e14dbbf`. Preconfigured ACPX Codex is temporarily unqualified; re-enabling it requires session permission enforcement on thread/turn operations and a real filesystem-denial probe. The config guard covers effective replacements, adapter changes, and rollback while allowing ordinary agent merges and operator removal. All 190 focused Runner tests, 103 server tests, both typechecks, and generated-profile checks pass. Standard review and CI passed before the next Apex request. - CI on `26e14dbbf` passed 1,967 Runner-shard tests but hit the previously observed `ENOTEMPTY` fixture cleanup race after successful Claude model admission. `eb83284fb` adds bounded filesystem retries to that fixture's teardown; all 87 adapter tests pass. Assertions and production cleanup behavior are unchanged. Head `eb83284fb42ee19a15d9a93b106c1bbb07e1695e` passes all 59 CI checks ([CI run](https://github.com/paperclipai/paperclip/actions/runs/38829500857)) and standard Greptile at 5/5 with no unresolved threads. Apex also completed at **5/5** on that exact head ([Apex result](https://github.com/paperclipai/paperclip/pull/16486#issuecomment-6201559527)). All review threads are resolved, the branch has no merge conflicts, and the PR remains unmerged. - No live paid-provider or remote-machine smoke was performed. The lockfile remains unchanged under the repository's refresh-bot policy; local dependency installation resolved the changed patch hash. ## Risks This explicit opt-in grants Codex tools access to the execution home (read-only in planning), including credentials. Native Codex separately denies Runner-owned protocol state. ACPX Claude retains its existing provider trust boundary, and the isolated default is unchanged. Providers may refresh credentials and update their own metadata. User configuration can block tools or the completion reporter. Existing blocked results and failure diagnostics remain the recovery path. Edit the local settings and retry; no new approval workflow is added. External provider history remains on the execution machine and is not backed up by Runner. Remote HOME discovery requires `getent` and fails explicitly when unavailable. Other harnesses need separate qualification. The Codex ACP bundle digest changes. Existing sessions tied to the old bundle may need a fresh session. No database migration is required. ## Model Used OpenAI Codex, GPT-6, with reasoning and code execution. The exact runtime model ID was not exposed. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have described the issue in-PR following the feature issue template - [x] I have not referenced internal/instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal ticket id - [x] I have run targeted 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 risks above --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
0b62c736a0 |
feat(connections): add generic Daytona API and Toolbox access (#16483)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Apps connections give agents controlled access to external services. > - Daytona provides sandbox, file, command, Git, and account APIs. > - Operators need to assign this access without exposing a server credential. > - A small task-specific tool list cannot serve general Daytona work. > - This pull request adds the published HTTP actions through the existing connection gateway. > - Operators keep control of identity, agent access, and each action. ## Linked Issues or Issue Description **Problem or motivation** Paperclip has a Daytona sandbox provider for its own execution infrastructure. It lacks a normal Apps connection for agents to manage an operator's Daytona account. Reusing the server's provider credential would bypass normal connection ownership and action permissions. **Proposed solution** Add a Daytona connection with personal or shared vault credentials. Generate its action catalog from the official platform and Toolbox API specifications. Use the existing run-bound gateway, grants, action policies, approvals, revocation, and audit paths. Sandbox IDs come from Daytona; tools need no Paperclip task or lease ID. **Alternatives considered** A four-action diagnostic subset cannot support general provider work. Launching the provider CLI would expose host filesystem behavior. Native OAuth is not included because a supported third-party registration path was not verified. The native method uses an organization API key. Existing Composio setup is a separate possible OAuth route and is not qualified by this change. **Roadmap alignment** This extends the existing Apps and Connections provider coverage in `ROADMAP.md`. It uses that system's credential and permission model. GitHub searches found no existing Daytona Apps connector PR or issue. ## What Changed - Add the Daytona catalog entry, provider source override, official theme logos, permission review, and setup documentation. - Generate 274 HTTP actions: 169 platform and 105 Toolbox operations. Record two WebSocket upgrades separately; do not advertise them as HTTP tools. Record source URLs and hashes. - Add provider-focused execution for sandboxes, snapshots, volumes, files, Git, commands, computer use, and account resources. Provider authority still limits which endpoints accept an organization key. - Validate action arguments. Resolve Toolbox targets through the fixed platform API. Check sandbox identity and organization before using an approved Daytona proxy. Keep normal guarded network requests and vault resolution. - Transfer file bytes without reading or writing host files. Share one caller deadline across prerequisite reads, dispatch, and response reading. Bound requests and responses. Do not automatically retry writes with unknown outcomes. Redact the selected credential from results and errors. - Classify credential access, access changes, interactive input, command execution, file permissions, and deletion (including TTL and auto-delete) as destructive actions. Keep new and changed actions under catalog review. - Upgrade saved catalogs and retire the earlier diagnostic names. Hide retired actions from the UI and agent discovery even when provider refresh fails. Preserve existing action choices and historical records. Reject stale same-name contracts during agent discovery and dispatch before a board refresh. - Add database-backed gateway and catalog-upgrade regressions, schema generator tests, a browser setup check, and both capability map updates. ## Verification - Passed on the review-fix head: 57 focused Vitest cases (18 Daytona database/client cases, five HTTP boundary cases, and 34 shared catalog cases), four generator tests, `pnpm -r typecheck`, and `pnpm build`. The five HTTP cases use a real local server through the pinned production transport. The normal browser setup check and 17 generator/artwork cases passed on the initial PR head; those UI and artwork paths are unchanged. - Passed on this branch: brand asset validation, token gates, map structure checks, and `git diff --check`. All latest-head GitHub checks pass on `ea979ccb3a64dc9508807823540f935c4316ea35`. Apex is 5/5, with all five findings addressed and zero unresolved threads. The branch has no merge conflicts. - The initial catalog-generation command could not find the external research corpus. The supported `--definitions-only` mode regenerated the definitions successfully. Unrelated generated drift was excluded. - An earlier full local Vitest attempt on the preview branch failed when bundled PostgreSQL could not start on macOS. After replay onto current master, all three unchanged event-sequencing cases pass with bundled PostgreSQL; the earlier startup cause remains uncertain. - The first full-suite command on this branch used my external test database override. Chat fixtures require a current migrated schema and failed because `agents.lifecycle_state` was absent in that disposable database. A focused comparison reproduces failure with the override and passes with normal setup. That attempt was stopped, and the full suite restarted without the override. Focused Daytona cases use their own migrated PostgreSQL 16 databases. - The clean local full-suite attempt recorded embedded PostgreSQL startup failures in two unchanged native-runtime cases and two failures in unchanged Git fixtures. It was stopped after these failures were isolated; no full local suite pass is claimed. The 15 matching native-runtime cases pass separately. The Git cases fail with the local `init.defaultBranch=main` setting and pass with `GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=init.defaultBranch GIT_CONFIG_VALUE_0=master` limited to the test command. No global Git setting was changed. Full Linux CI is green. - Fixtures use real database persistence and run-bound gateway sessions with provider responses replaced by fixtures. They cover personal/shared vault ownership, reads and writes, file bytes, Off policies, revocation, organization mismatch, untrusted proxy rejection, output bounds, saved catalog upgrades, failed refresh, and permission preservation. - The first Apex review found five valid issues: multipart transport compatibility, destructive classification, caller deadlines, audit filters, and stale saved contracts. All five were fixed with regressions before the second review. A typecheck then found the nullable saved schema hash; admission now accepts that stored type and rejects null as stale. - The browser check covers setup controls without submitting a provider key. No real Daytona account, provider write, native OAuth flow, or agent model run is qualified. Live provider read/write proof remains pending a test account. ## Risks - Daytona keys have broad Toolbox authority, including keys with no selected resource scopes. Only assign this connection to trusted agents and review its action permissions. - Remote writes or commands can continue after a timeout. Calls do not automatically retry an uncertain outcome. - The bridge targets Daytona Cloud. Proxy hosts are restricted; an unrecognized future regional host fails closed. - Files and responses have an 8 MiB bound. Each action has one caller deadline, capped at 30 seconds across all provider requests and response reading. Interactive WebSocket sessions are not exposed as HTTP actions. - The generated JSON snapshot exceeds 1,000 lines because it holds the provider input contracts. Generator logic and execution code remain in separate small modules. Updates require explicit regeneration and catalog review. - No database migration or lockfile change is required. ## Model Used OpenAI Codex, GPT-6. The runtime identifies the model family but does not expose the exact backend model ID or context window. Used reasoning, repository inspection, code editing, shell tools, database verification, and browser tests. ## 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> |
||
|
|
676d3ec8d4 |
perf(ci): reuse package downloads and overlap runtime checks (#16474)
## Thinking Path > - Paperclip contributors wait for CI before delivering changes. > - Build still finishes last after #16460. > - CI already downloads the public npm graph while the build runs. > - Bundled-package preparation ignores that cache and downloads the same archives again. > - Reuse the existing cache and overlap independent runtime checks while preserving fresh installs, integrity, offline lifecycle and admission verification. > - Measure staging and the full workflow separately. ## Linked Issues or Issue Description Refs #16460 and #16434. This is a focused follow-up to merged #16460, now based directly on master. **Current behavior:** The Build workflow warms `PAPERCLIP_PUBLIC_INSTALL_NPM_CACHE`, but `startBundledInstalls` inherits the host's default npm cache. Server staging took 31.17 seconds in the latest passing run, before packing and the clean consumer install. **Proposed behavior:** Pass the verifier environment, including the explicitly configured warm cache, to the three existing staging children. Without an explicit shared cache, keep the usual producer npm configuration. **Alternatives considered:** Copying an installed dependency tree would bypass normal fresh installation. Adding jobs would add setup cost. This change reuses only npm's integrity-checked download cache. It does not remove coverage or change product behavior and does not overlap a roadmap feature. Open PR title search found no equivalent cache wiring change. ## What Changed - Initialize the existing consumer cache before package staging and expose it to producer npm only when explicitly configured. - Pass that environment to the existing bundled-install children. - Extend the child orchestration check to verify cache propagation and document the cache boundary. - Start Pi setup after the offline lifecycle, in its own download sandbox, while Codex and Grok probes run in separate offline sandboxes. Join successful Pi setup before lock verification and Pi admission. Name and clean up only the verifier-owned setup container. ## Verification - 33 focused public-install, closure and child-orchestration tests pass on Node 24.21.0. - A real server dependency staging experiment used `prepare-bundled-package.mjs`, its actual manifests, provider overrides and release patches. Built application payloads were omitted from this dependency-only measurement. - Cold cache: **16.139s**. After the actual CI warm-up script: **6.980s**. A fully warm producer cache took **6.127s**. These are local sequential measurements, not a CI wall-clock claim; filesystem warmth and registry timing vary. - All **28,329 files/links**, including both lockfiles, were byte-identical between the cold output and the actual-workflow-warm output. - The warm-up itself took 49.631s; CI already runs it during Rust restore/build. This change adds no warm-up operation. - First follow-up run [passed all 48 jobs](https://github.com/paperclipai/paperclip/actions/runs/38791277425), and Greptile gave the cache-only head 5/5. Server staging fell **31.172s → 17.565s** and total staging **70.169s → 54.869s**. But complete CI was **8m20s**, slower than the parent's 8m04s; longer Codex/Pi probe times outweighed that saving. This is not a full-run speed improvement claim. - The next revision overlaps the independent probes instead of serializing Pi setup behind them. All 46 focused sandbox, staging, closure and process-supervision tests pass, including failed background children, parent exit and cancellation. Pre-retarget head `590873a44` passes all 48 jobs and Greptile 5/5 with no review findings. After #16460 merged, head `fe4f8d38e` incorporates master and retargets this PR directly to master. Its diff remains only four optimization/documentation/test files; 46 focused checks pass again. Fresh full CI and review are pending. The unchanged parent conflict-resolution run passed all 48 jobs in 8m04s: https://github.com/paperclipai/paperclip/actions/runs/38789785045. Final paired runs against the same updated master, both on `m7i-flex.xlarge`: | Measurement | Parent #16460 | This PR | | --- | ---: | ---: | | Bundled server staging | 22.220s | 14.202s | | All package staging | 61.277s | 48.304s | | Clean consumer install | 67.617s | 73.490s | | Pi setup remaining wait | 25.428s (serial setup) | 20.719s | | Build job | 385s | 368s | | Build start after workflow creation | 23s | 136s | | Entire workflow, including admission and aggregates | 452s (7m32s) | 552s (9m12s) | [Parent run](https://github.com/paperclipai/paperclip/actions/runs/38792983313), [final run](https://github.com/paperclipai/paperclip/actions/runs/38792986392). Build execution improved by **17s (4.4%)** in this pair. The total workflow did **not** improve: it waited 113 seconds longer to start Build, and other lanes/aggregates also contribute. The overlapping setup ran for 25.667s while Codex/Grok took 4.946s, leaving 20.719s to wait. Actual installed Codex, Grok and Pi checks all passed with zero provider calls. These are individual samples with filesystem/network/CPU variance, not a claimed steady-state average. The earlier slower cache-only run is retained above. No tests were removed and no jobs were added. ## Risks Shared-cache contention can reduce the benefit if warm-up is still running. npm handles concurrent content-addressed cache writers and checks integrity; misses still download normally. Two runtime containers can now overlap and contend for host resources; the full CI run measures that tradeoff. They retain separate network policies and per-container bounds. Pi writes only its provider assets and a private receipt; the other probes inspect Codex/Grok. No installed tree, lock, test result or build output is reused. The consumer still starts empty and performs the full lifecycle and runtime checks. Normal unconfigured producer cache behavior is preserved. ## Model Used OpenAI GPT-6 through Codex, with repository inspection, execution and GitHub tools. The serving model suffix and context capacity 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 linked existing issues or described the issue in this PR - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no private ticket identifier - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation - [x] I have considered and documented the risks - [ ] All Paperclip CI gates are green (prior head passed; rerunning after master merge) - [ ] Greptile is 5/5 with no open P2s, recommendations or follow-ups (prior head 5/5; current head pending) - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
307eb16c0c |
perf(ci): avoid duplicate extraction in public install checks (#16460)
## Thinking Path > - Paperclip manages AI agents for work. > - Contributors wait for CI before they can deliver changes. > - After #16434, Build is the longest CI job. > - Its clean public npm install spends about 90 seconds installing packed artifacts. > - npm extracts local archives to read metadata before it installs them. > - Serve metadata from those same packed artifacts, then let normal npm verify and install their bytes once. > - Preserve the offline lifecycle and runtime checks, and measure the complete workflow. ## Linked Issues or Issue Description Refs #16434 and #16429. **Current behavior:** The Linux Build check installs every staged package by local tarball path. npm's file fetcher extracts an archive to obtain its manifest. Installation then extracts it again. In the last green run, Build took 408 seconds; consumer installation took 89.7 seconds. The full workflow took 8m06s. **Proposed behavior:** Read manifests directly from the packed archives. Serve those manifests and their SHA-512-bound tarballs from a temporary registry on container loopback. Use normal npm installation into the empty consumer. Other packages still resolve from the public npm registry. **Alternatives:** More parallel jobs would add setup and transfer work. Skipping the install or runtime probes would remove useful coverage. This change removes duplicate extraction instead. It does not add a product feature or duplicate a roadmap item. ## What Changed - Build a registry catalog from the actual tarball manifests and archive hashes. - Run the short-lived registry and npm in the existing unprivileged download container. No host port is exposed. - Preserve public dependency tarball URLs, archive integrity checks, disabled initial lifecycle scripts, the offline rebuild, lock checks and all Codex, Grok and Pi probes. - Close the registry before offline verification. Keep native ARM and Mac install qualification unchanged. - Add real npm parity and failure tests. Record metadata preparation time in the existing timing receipt. - Fix an existing policy false positive: the filename `docker-compose-secrets.test.mjs` is not a workflow credential. Inspect GitHub expressions and retain rejection of Honeycomb keys, dot/bracket secret reads and `toJSON(secrets)`. ## Verification - 31 focused install-contract checks pass on Node 24.21.0. All 16 targeted CI profile-policy tests also pass. - Real npm file and registry installs produce identical installed files, bundled dependencies, optional dependencies and executable links. Both defer lifecycle execution; offline rebuild works after the registry closes and preserves the lock. - npm rejects an archive whose gzip header changes while its extracted payload remains valid. The CLI propagates the failure. - The permanent real-npm parity test now includes non-catalog `is-number@7.0.0`. Both paths install it from its official npmjs tarball, and the test asserts the lock URL. Fetches have a 10-second bound and no retries. This addresses the first Greptile finding. A separate live probe also confirmed public provenance. - The first local run hit the host sandbox's loopback `EPERM`; the same checks passed with local listener access. An initial corrupted-gzip negative fixture hit decompression failure before integrity verification; the final fixture preserves valid gzip and specifically proves integrity rejection. An old command-shape assertion was updated for the new entry point without removing its ordering checks. - The [first CI run](https://github.com/paperclipai/paperclip/actions/runs/38778371043) passed all test lanes and Build, but the existing credential-guard false positive failed policy and both aggregates. Its 7m25s full duration is **not** counted as a passing performance sample. The guard repair and public-download regression are on the new head. - The real Linux install passed all 18 packed packages, the lifecycle sentinel, offline rebuild, unchanged lock, official Codex payload/lease checks, Grok missing/present checks and Pi admission. The receipt confirms `artifactTransport: loopback-registry`. No provider calls ran. - Compared with the previous green run, consumer install fell **89.72s → 66.29s** (26.1%), including 1.87s to prepare metadata. Build fell **408s → 374s**. Both Build hosts were `m7i-flex.xlarge`; these are separate runs, so registry/cache and upstream changes remain confounders. - The base advanced since the previous 8m06s run, including runtime and test changes. Treat that duration as historical context, not an identical-source control. - Pre-conflict head `d8f9de1c` [passes all 48 workflow jobs](https://github.com/paperclipai/paperclip/actions/runs/38779549190), including both required branch-protection checks. Greptile is **5/5** on this head; its review thread is resolved. The non-required Superagent Security Scan is still running. | Measurement | Previous green run | Final green run | Observed change | | --- | ---: | ---: | ---: | | Full CI, workflow creation through final aggregate | 8m06s | **7m35s** | **31s shorter (6.4%)** | | Build job execution | 408s | **389s** | **19s shorter** | | Clean consumer install, including catalog preparation | 89.72s | **69.69s** | **20.03s less (22.3%)** | The final catalog preparation took 1.87s and is included in the install figure. Both Build hosts were `m7i-flex.xlarge`. Build began 42 seconds after workflow creation instead of 53 seconds in the historical run, so faster queue/setup admission explains part of the 31-second total. Upstream code also advanced; these measurements are not a controlled causal estimate of the complete gain. The two candidate install measurements (66.29s and 69.69s) support the narrower reduction in install work. No tests or runtime probes were removed. - Conflict-resolution head `ea8287b81` [passes all 48 workflow jobs](https://github.com/paperclipai/paperclip/actions/runs/38789785045), including both required gates. Greptile re-reviewed this exact head at 5/5, with the sole earlier thread resolved. The conflict was the independent filename-policy fix; the stronger expression guard is retained. This run took **8m04s** overall, Build 423s, consumer installation 80.56s and bundled-server staging 31.17s. This confirms meaningful run variance: the earlier 7m35s is a sample, not a guaranteed new wall-clock duration. - A second independent master update touched the same credential test. Final head `1c740b73e` resolves that conflict while retaining the same stronger guard. [All 48 jobs pass](https://github.com/paperclipai/paperclip/actions/runs/38792983313); Greptile re-reviewed this exact head at 5/5. This run took **7m32s** overall, Build **385s**, consumer install **67.62s**. Auto-merge is enabled but GitHub requires code-owner approval. ## Risks The initial install now uses registry package specs instead of file specs. The parity test checks the resulting installed bytes. Full CI must still exercise real bundled provider graphs and all offline probes. The temporary consumer lock contains loopback artifact URLs; it is not exported or reused for another installation. Native release consumers retain their existing artifact install path. Queue, host and cache variance limit attribution from separate workflow runs. ## Model Used OpenAI GPT-6 through Codex, with repository inspection, execution and GitHub tools. The serving model suffix and context capacity 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 linked existing issues or described the issue in this PR - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no private ticket identifier - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation - [x] I have considered and documented the risks - [x] All Paperclip CI gates are green (48 jobs and both required gates on conflict-resolution head) - [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> |
||
|
|
341cfbcea8 |
fix(docker): remap the node user without walking the app home (#16475)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The container image sets the node user's home to the app home, `/paperclip`, which is the data volume in container deployments > - When `USER_UID`/`USER_GID` differ from the image, the entrypoint runs `usermod -u` and `usermod -g` before the app starts > - `usermod` also re-owns every file under the user's home, so every boot walks the whole data volume first > - On a large volume this delayed each boot by about six minutes, and platforms that stop the old container before starting the new one serve errors for that whole time > - This pull request runs the remap while the home points at a path that does not exist, then restores it > - The benefit is that a UID/GID remap takes milliseconds, and deploys no longer wait for a full volume walk ## Linked Issues or Issue Description Related: #15992 (skips the full-tree ownership probe on routine boots) and #10530 (ownership before the privilege drop). This removes the remaining per-boot full-tree walk. **What happened?** A deployment sets `USER_UID=1001`/`USER_GID=1001` on an image built with the default 1000. Every boot logs `Updating node UID to 1001`, and the next log line (`Updating node GID to 1001`) appeared six minutes later. During that time the app was not running. The volume holds many agent worktrees and dependency trees. No file had the old owner, so the walk changed nothing. **Expected behavior** Remapping the node account should not depend on the size of the data volume. Ownership repair belongs to the existing tiered ownership probe, which records a marker and skips the full walk on routine boots. **Steps to reproduce** 1. Build the image with the default `USER_UID=1000`. 2. Run it as root with `USER_UID=1001`, `USER_GID=1001` and a large app home. 3. Every boot spends the time of a full home walk in `usermod -o -u` before the app starts. Measured in the runtime image (Debian trixie) with 200,000 files under a user's home: `usermod -u` took 1,204 ms and re-owned every file. With the home moved away first, the three `usermod` calls took 124 ms and changed no file. ## What Changed - `scripts/docker-entrypoint.sh`: when a UID or GID remap is needed, read the node user's home with `getent passwd node` and point it at `/nonexistent/paperclip-uid-remap`. Then run the same UID and GID commands as before, and restore the home. Without a passwd entry, the remap runs as before. The ownership probe and repair logic are unchanged. After a real ID change, the home directory has the old owner, so the shallow probe detects the mismatch on the same boot and repairs the tree once. - `server/src/__tests__/docker-entrypoint.test.ts`: stubs `getent` and adds tests for the call order (UID+GID remap, GID-only remap), for repair after the remap, and for the fallback without a passwd entry. ## Verification - `pnpm exec vitest run src/__tests__/docker-entrypoint.test.ts` (in `server/`): 22 passed. - `sh -n scripts/docker-entrypoint.sh`: passed. - Manual check in the runtime image with a throwaway user and 200,000 files (numbers above). The UID changed, file owners were not touched, and the passwd home was restored. ## Risks - `usermod -d` without `-m` only edits the passwd entry. The home is restored right after the ID change. If the entrypoint fails between the two calls, `set -e` stops the container before the privilege drop, and the next boot sets the home again, so a partial state does not persist past a restart. - Ownership after a real remap now depends on the existing probe instead of `usermod`. The probe's tests already cover the remap, fresh-mount, deep-mismatch and marker cases. ## Model Used - Claude Opus 5.5 (`claude-opus-5-5`), 1M context, through Claude Code with tool use (shell, file edits, test runs, live measurement in a running container). ## 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: Paperclip <noreply@paperclip.ing> |
||
|
|
68a09dcb5f |
perf(ci): shorten the test execution critical path (#16434)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Contributors wait for the full PR workflow before they can deliver fixes. > - Server shards still execute independent files in series, and a single Runner file serializes two long real-clock waits. > - Faster work outside the critical path does not prove a faster workflow. > - Overlap independent files while preserving isolation, test cases and real production deadlines. > - Compare complete baseline and candidate workflows, separating queue delay from execution cost. ## Linked Issues or Issue Description Refs #16429. Related duration refresh: #12577. **What existing behavior does this improve?** The elapsed time from PR CI creation to the last required check. **Current behavior** General server shards use one worker. One Runner transport file takes about 333 seconds on Linux, including over 100 seconds in two real-clock regressions. These are the longest verification lanes after #16429. **Proposed behavior** Run independent general-server files in at most two isolated forks. Move the two intact Runner deadline regressions into a separate file to overlap their waits in the existing pool. Run two chat partitions per existing job, each with its own temporary home and embedded PostgreSQL. Preserve serial execution within files and every assertion and timing boundary. ## What Changed - Qualify both serial and parallel forks with real worker processes, isolated homes/configuration, timers, globals and environment. - Require both parallel workers to arrive before either exits. - Use two isolated forks for sharded general-server tests; retain one worker with an explicit shared test database. Other test groups keep their existing concurrency. - Extract the lease-expiry and Pi cold-admission regressions verbatim into a separate Runner test file; retain real waits and process/lease assertions. - Split each sharded chat job into two independent invocations; preserve serial shared-database execution. Await both children before failing the parent. Prove disjoint coverage and failure propagation. - Update the paired Linux benchmark to compare a complete general-server shard with identical case inventories. - Document concurrency and deadline-test placement. No production behavior, workflow topology or runner count changes. - Allow 15 seconds for snapshot integration cases that cold-start multiple real TypeScript workers. On the repeat, one-worker cases took 2.5–3 seconds, so queued or sequential starts could exceed the default five seconds. Preserve all cleanup, queue-release and filesystem assertions; these cases do not enforce a production latency deadline. ## Verification All 48 jobs passed on scheduling head `5d718e18` in [attempt 1](https://github.com/paperclipai/paperclip/actions/runs/38763885288/attempts/1). The [bounded repeat](https://github.com/paperclipai/paperclip/actions/runs/38763885288/attempts/2) failed two existing snapshot-worker tests at their default five-second timeout. Its shorter duration is **not** counted as a successful performance sample. The latest head `3c894462` adds a targeted test-budget repair and [passes all 48 CI jobs](https://github.com/paperclipai/paperclip/actions/runs/38768433532) in **8m06s** (workflow creation to final required workflow job). This is **70 seconds / 12.6% shorter** than the 9m16s intermediate run, but the earlier 9m23s result remains part of the evidence: a stable average improvement is not established. Both branch-protection checks (`ci / verify` and `ci / e2e`) pass. The non-required Superagent Security Scan is still running; external PR scans are separate from this workflow duration. | Measurement | Before | After | What it establishes | | --- | ---: | ---: | --- | | General-server shard, paired on one Linux host | 430.94s | 292.99s | 32.0% faster; identical 1,047 case inventory | | Chat job 1 | 460s | 211s | Same full chat inventory spread across isolated partitions | | Chat job 2 | 408s | 274s | Serial cases within each child, separate PostgreSQL instances | | Chat job 3 | 408s | 216s | Total chat runner time fell from 1,276s to 701s | | Full PR workflow, first chat candidate | 9m16s | 9m23s | Not an end-to-end win in this pair: unchanged Build rose from 365s to 465s | | Full PR workflow, final repaired head | 9m16s | 8m06s | All 48 jobs pass; 70 seconds faster observed, not a controlled causal estimate | - Latest [paired benchmark](https://github.com/paperclipai/paperclip/actions/runs/38763885223) passes. Earlier paired server measurements were 33.3% and 37.4% faster. Unchanged fixture timing noise is not attributed to this PR. - All **1,337 chat case identities and outcomes match exactly** across [before-chat](https://github.com/paperclipai/paperclip/actions/runs/38760937988) and [after-chat](https://github.com/paperclipai/paperclip/actions/runs/38763885288/attempts/1), without duplicates or removals. Whole-suite records rose from 44,563 to 44,574: three new launcher checks and eight upstream warm-owner tests. Remaining name differences were generated fixture IDs/timestamps/PIDs, not removed tests. - The final run used `m7i-flex.xlarge` for Build (408s), with all chat jobs completing in 238s / 318s / 280s. It used the same actual merge base `afe5b341` as the first chat candidate. Optional profiling was disabled after the bounded measurement experiment; the full 48-job correctness workflow still ran. - The fleet used `m7i.xlarge` for the earlier Build and `m6a.xlarge` for the first chat candidate Build. Several unchanged compile/install/probe phases slowed together. This does not prove hardware alone caused the difference, and full-run attribution must account for runner/cache variance and the upstream base change. - Original full baseline: [all 48 jobs passed](https://github.com/paperclipai/paperclip/actions/runs/38753547876/attempts/2), 12m07s, including a server job that queued over five minutes. It is not a clean basis for attributing the whole elapsed-time reduction to this PR. An interrupted baseline and two misrouted candidate attempts were excluded and preserved; routing/trust rules were not weakened. - Local: 32 sharding/launcher checks pass, including disjoint coverage, shared-database fallback and a failed child that waits for its sibling. Real paired chat partitions passed 416 cases in 217.63s on independent embedded databases. - Both extracted Runner deadline regressions pass unchanged with real waits. An initial local attempt rejected a Node executable under the controller home; the identical binary in an owned non-home path passed without weakening that guard. - Real worker-isolation proof, actionlint and diff checks pass. Latest-head Greptile is **5/5**, with no review threads or actionable findings. - The eight snapshot-worker cases pass locally with a private `PAPERCLIP_HOME`. The first direct local invocation failed to open the default-home lock database under the sandbox; no production guard was changed. ## Risks Parallel files and paired chat databases may expose shared-state assumptions or increase peak memory. Cases stay serial within each invocation, and explicit shared databases keep the serial path. Complete server coverage and the full 48-job CI workflow pass. Check external required PR scans before merge; the full-workflow measurements are observational and do not establish a steady 12.6% speedup. Queueing, cache state and runner variance must be distinguished from execution improvements. ## Model Used OpenAI GPT-6 through Codex, with repository inspection, code execution and GitHub tools. The exact serving model suffix and context capacity 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 (48 jobs; both required branch-protection checks pass; non-required external security scan pending) - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
95692b7785 |
fix(docker): forward tool action signing secret in Compose (#15202)
## Thinking Path > - Paperclip can run through Docker Compose. > - Approval-gated tools need an independent signing secret. > - The guide sets that secret before starting Compose. > - Neither Compose file passes it into the container. > - This pull request forwards the operator's configured secret. > - Documented setup can issue signed tool-action approvals. ## Linked Issues or Issue Description Fixes: #15064 ## What Changed - Forward PAPERCLIP_TOOL_ACTION_SIGNING_SECRET in both shipped Compose environments. - Document persistent deployment secrets and reuse on restart. - Explain that it is independent from the session secret. - Keep an empty default so deployments without approval-gated tools retain their existing startup behavior. ## Verification - Docker Compose config before the fix drops a supplied synthetic secret in both files. - After the fix, both preserve the supplied value. - Both also resolve successfully when the optional signing secret is absent. - Used --env-file /dev/null and synthetic values. No containers were started. - `node --test scripts/docker-compose-secrets.test.mjs`: 2 passed. - The Docker context CI lane runs this integration test. - git diff --check passes. ## Risks The value is visible to the container as intended. Operators must protect it as a secret. This does not change admission rules or require a new startup value for existing deployments. ## Model Used OpenAI Codex, based on GPT-6, assisted with source review, implementation and local test execution. The exact deployment model ID and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass (targeted local checks and full remote CI pass) - [x] I have added or updated tests where applicable (Hermes regression / real Compose interpolation checks) - [x] I have updated relevant documentation to reflect my changes (Hermes has no configuration changes; Compose documentation is updated) - [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 |
||
|
|
7ec6fd0972 |
perf(ci): remove repeated test setup and fixture work (#16429)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - CI must check changes without making contributors wait for repeated setup. > - A complete CI profile showed 158 serialized Vitest launches and repeated dependency installs. > - A large fixture also transferred 40,000 files to prove two different size boundaries. > - This PR removes repeated controller, install, build, transfer, and wait work. > - It keeps isolated test processes and all useful regression boundaries. > - Paired command benchmarks check speed and test inventories before we claim a benefit. ## Linked Issues or Issue Description Refs #16423 for the complete CI profiling data path. No duplicate optimization PR was found. **Current behavior** Each serialized file starts a new Vitest controller. Each CI lane restores the pnpm store and installs dependencies. Large Git scanning and staging share one 40,000-file fixture. A readiness regression waits over a minute for the default database idle deadline. **Proposed behavior** Use one controller per serialized shard, with a fresh fork for each file. Restore exact installed dependencies and certified shared/SDK build outputs when inputs match. Keep the normal install and build paths on a miss. Separate the 32 MiB Git scan proof from staging above command argument limits. Cross a real database idle deadline with a one-second fixture setting. **Reason and benefit** The paired Linux CI benchmark reduced the complete 566-case serialized shard from 303.43s to 246.96s (18.6%). The Git/database fixture command fell from 156.54s to 33.78s (78.4%). Exact dependency/build restoration reduced setup from 56s to 19s (66.1%). These are measured command/setup times. They do not establish a controlled reduction in the full workflow's queue-to-completion time. **Breaking changes** None to application behavior. Tests still run in full. Test results are not cached. Cache misses preserve the existing lockfile resolution fallback. ## What Changed - Batch serialized files into one isolated, single-worker Vitest invocation per shard. Give each worker its own home, config and instance ID. - Add a real two-order isolation check for processes, environment, globals, timers and filesystem state. - Add exact dependency keys for all manifests, lockfile, workspace settings, patches, installer, runtime, platform, libc, pnpm, store and checkout path. Cache only installed package directories, not source fixtures. - Add a separate content key for the shared/SDK dependency graph. Retain the existing source/output fingerprint verifier and rebuild path. Only an exact canonical master push can populate normal caches. Stale lockfile fallback runs cannot publish entries. - Keep four real Git filename lanes above 32 MiB. Use a separate 4,000-file staging/deletion case above 2 MiB. Check every staged file, unusual names, cleanup and bounded commands. - Configure a real one-second PostgreSQL idle timeout in the readiness fixture. Assert that the backend connection changes and that another connection can write the parent row. - Add an opt-in, unprivileged Linux benchmark under `profile-ci`. It compares the tested merge tree with its actual first parent on one runner. It also removes installed outputs and qualifies a real cache restore using temporary PR-scoped entries. ## Verification - Local Node 24.19.0: unchanged serialized shard 255.69s; candidate 231.44s; all 566 cases pass in both. - Local fixture command: unchanged 189.13s; candidate 43.39s. Candidate scan 18.58s, staging 13.41s, database case 2.80s. All three candidate cases pass. - Negative control: moving readiness back inside the real parent-lock transaction fails the shortened regression at the parent-write assertion. The production source was restored and is absent from the diff. - Worker isolation check passes in both file orders. - 565 CI policy, partition and workflow regression checks pass with local HTTP/IPC access enabled. The first sandboxed attempt was denied listen access; it was not a code failure. - `actionlint` passes for the three changed workflows. - [All 48 main CI jobs passed](https://github.com/paperclipai/paperclip/actions/runs/38745643045) on head `5bec2edb2b194e74352ca697f3fd1d0ac03ce967`, including full typecheck, tests, build, browser E2E and release checks. All 158 serialized files and 3,250 cases passed through 9 controller invocations. Full typecheck/test/build were verified in CI; they were not all repeated locally. - [Paired Linux benchmark passed](https://github.com/paperclipai/paperclip/actions/runs/38745643127) on Node 24.21.0. Its baseline is `57fa6b358de62922cfa9a67766b2a227c434fcdf`; its candidate merge tree is `f68f1b32966090f11647502e31852130c20237cf`. The artifact contains results, exact case inventories, setup times and raw logs. Serialized case identities match exactly. All three fixture contracts execute in both variants. | Measured work | Baseline | Candidate | Reduction | |---|---:|---:|---:| | Complete serialized shard, 566 cases | 303.43s | 246.96s | 18.6% | | Git/database fixture command | 156.54s | 33.78s | 78.4% | | Dependency/build setup, cold vs exact hit | 56s | 19s | 66.1% | - [Honeycomb profile export succeeded on its second attempt](https://github.com/paperclipai/paperclip/actions/runs/38747237615/attempts/2). The first attempt failed on GitHub HTTP 503 while downloading an artifact, before export. Only the export was retried; tests were not repeated. The temporary PR-scoped qualification caches were removed after validation, reclaiming 3.34 GB. Timing artifacts remain available. - Greptile is 5/5 on the current head, with no unresolved review threads. Its P1 checkout-prefix finding was fixed in `5bec2edb2`; the corrected reporter paths and paired comparison passed. Earlier runs were superseded while this was fixed. A copy-batching experiment did not speed up the Git fixture and was replaced by the two-boundary fixture split. ## Risks - A persistent controller retains transform state longer. The local shard's maximum RSS rose from about 1.52 GB to 1.99 GB. Full CI must confirm all shards fit the runner budget. - Materialized caches are larger than metadata caches. The Linux benchmark measured real archive transfer and validation after removing installed outputs. Its hit took 19s versus 56s cold. Normal PR lanes cannot publish cache entries. Exact misses run installation. Canonical cache warming requires a frozen-lockfile install; the existing stale-lockfile fallback remains uncached. - The PR uses the trusted reusable workflow from master. The paired benchmark directly exercises the candidate dependency action; normal workflow adoption still requires this PR to merge. This PR does not change the trust references. The completed main workflow took 11m02 including queue time. No controlled full-workflow latency improvement is claimed before this workflow adopts the cache change. - Only deterministic dependency/build outputs are reused. Broad dependency-based test omission and caching successful test results are deliberately excluded from this change. - The real Runner lease minimum and cold-admission waits remain. They protect protocol boundaries and were not shortened by weakening production limits. ## Model Used OpenAI GPT-6 through Codex, with reasoning, shell execution and code tools. The runtime does not expose a more specific deployment ID or context-window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [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> |
||
|
|
7420af26fc |
fix(ci): finish large Honeycomb profile exports (#16423)
## Thinking Path > - Paperclip uses pull request CI to check changes before merge. > - The merged CI profiler records a selected full PR suite in Honeycomb. > - A real 48-job profile exposed an export failure after Honeycomb accepted only part of the trace. > - The same run exposed three fixture subprocesses that looked like incomplete test launches, one direct reporter without a launcher marker, and one overlong test name. > - The exporter needs to handle temporary ingest rejection without sending accepted spans again. > - This pull request fixes those cases and documents the trace display limit. > - The benefit is a complete, checkable CI waterfall with test-file timings. ## Linked Issues or Issue Description **What happened?** The first live `profile-ci` run on #16423 completed all 48 jobs, but the post-run exporter stopped when Honeycomb rejected part of a batch. The initial trace had no root span. Its coverage flag also reported four unfinished invocations and one invalid timing record. **Expected behavior** The exporter should pace large uploads, retry only temporarily rejected events, and publish the root after every child is accepted. Completed reporters should count as complete. Long test names should not erase test timing. **Steps to reproduce** 1. Add `profile-ci` to a CI CODEOWNER PR with the merged profiler. 2. Run the full PR suite, as in [run 38732093469](https://github.com/paperclipai/paperclip/actions/runs/38732093469). 3. Inspect the separate [failed exporter run](https://github.com/paperclipai/paperclip/actions/runs/38733393370) and the trace coverage fields. **Paperclip version or commit** `12612b06eb4332844ac4c8770a1fb6c6b7eccbc9` (PR run head, based on merged #16378). ## What Changed - Pace Honeycomb uploads and retry only transiently rejected events from each batch. - Preserve overlong test timings with bounded names and count complete reporter pairs without a launcher record. - Keep nested Vitest fixture runs from inheriting CI profiling and creating false coverage gaps. - Clarify ordinary CI access, large-trace display limits, and export behavior in the operator guide. ## Verification - [Full PR suite](https://github.com/paperclipai/paperclip/actions/runs/38732093469/attempts/1): 48 of 48 jobs succeeded; 10m 29s wall time. The selected jobs used the AWS public PR fleet. The protected exporter used a separate GitHub-hosted runner. - [Clean Honeycomb file waterfall](https://ui.honeycomb.io/paperclip/environments/test/datasets/paperclip-ci/trace?trace_id=01ed0c541b0442e613a030ffb6dc8d9b&trace_start_ts=1792065955&trace_end_ts=1792066584): 48 jobs, 822 steps, 2,622 file spans, and `ci.profile_complete=true`. It was reconstructed from that run's 45 timing artifacts after identifying three nested fixture records. The full trace also recorded 44,497 tests; Honeycomb's chart omits some deep test spans because it displays at most 32,000 spans per trace. - The original exporter stopped after a partially accepted batch. A local replay of that batch succeeded. I used the authorized local test-environment key to complete the original upload and create the file-level view. No key was added to this branch or PR. - `node --test .github/scripts/tests/ci-profile.test.mjs scripts/ci-profile/reporters.test.mjs`: 18 passed. - `pnpm exec vitest run server/src/__tests__/vitest-chat-shards.test.ts`: 1 passed. - `git diff --check`: passed. - The local `pnpm -r typecheck` and profiled fixture rerun could not start: the package-manager shim could not verify the `pnpm@9.15.4` registry signature because its fetches failed. `pnpm test:run` and `pnpm build` were not run locally; hosted CI is pending. - The updated exporter has not yet run from protected `master`; this PR remains draft until CI and review finish. ## Risks - A 48,000-span export now takes about three extra minutes due to pacing. Retry limits still fail a persistently rejected batch and keep the root unpublished. - Honeycomb may retain duplicates from an already partial export. The clean file-level evidence trace uses a separate trace ID. - The API key stays only in the protected `ci-profiling` environment. PR jobs write timing artifacts but never receive it. > 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 — see `CONTRIBUTING.md`. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, code execution, GitHub API, and browser inspection. The runtime does not expose the exact serving model ID or context window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes: #` / `Refs: #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
6acec4266e |
feat(ci): profile full CODEOWNER PR suites in Honeycomb (#16378)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Its PR workflow runs dozens of parallel build and test jobs. > - Individual job durations do not show the elapsed cost of the whole suite. > - Maintainers need one shared timeline to find slow work and repeated setup. > - This pull request adds full-suite profiles for selected CI CODEOWNER PRs. > - Honeycomb shows each job, step, test file, and supported test on that timeline. > - The benefit is evidence for changes that reduce total CI time. ## Linked Issues or Issue Description **What existing behavior does this improve?** The main PR workflow has about 48 jobs. Maintainers need to compare their overlapping work and find which jobs delay completion. **Current behavior** GitHub shows job and step durations separately. Test files and tests are not joined to a full workflow trace. **Proposed behavior** A CI CODEOWNER adds `profile-ci` to a PR. The tested code stays on that PR branch. All main PR lanes run, including lanes normally skipped for stack position or release notes. A trusted post-run exporter sends one wall-clock trace to Honeycomb. **Reason and benefit** The trace supports decisions about which CI work to speed up or remove. Ordinary PRs do not export traces. The roadmap and related-PR search found no duplicate CI profiling work. ## What Changed - Add label selection and a full-suite override. Verify the PR author, original actor, and rerun actors against the trusted `.github/**` CODEOWNERS rule. - Record Vitest, Playwright, and Node test file/test timings in local artifacts. Keep ordinary reporter behavior and failing exit codes. - Add a trusted `workflow_run` exporter. Use actual GitHub timestamps for all jobs, setup, steps, waiting, and teardown. Mark missing test data and partial reruns. - Keep the ingest key out of PR jobs. Store it only in the `ci-profiling` environment, restricted to `master`. The exporter reads bounded JSON and never executes artifact code. - Record expected test invocations outside reporters so a missing invocation cannot appear complete. Preserve `node --test` on older PR checkouts. Flush large shard inventories before exit. - Add security, timing, routing, and real-reporter checks. Document operation and activation. Protect the exporter with CODEOWNERS. ## Verification - 509 focused workflow/reporter/shard checks passed. They include outside authors, outside rerun actors, bots, stale revisions, malicious ZIP paths, incomplete reports, and partial ingestion failures. - Final revision `3bf5d9017d` adds multi-file qualification and fixes short-file step parenting and duplicate Node file-wrapper events. Greptile reviewed this exact revision at 5/5 with no unresolved threads. [Main PR CI run](https://github.com/paperclipai/paperclip/actions/runs/38728040302): the initial attempt had 54 successful checks, 3 intentional skips, and one serialized-shard failure from an unchanged workspace-authorization test exceeding its 15-second timeout. The single failed-shard retry passed: the final result is 55 successful checks and 3 intentional skips. The same timeout reproduces locally with profiling disabled; both assertions pass with a diagnostic 60-second timeout override (about 23 seconds total). No source or CI timeout was changed. - A dry run against real GitHub attempt 2 of run `38677445871` produced exactly 3 executed jobs, 40 spans, and 510 seconds, excluding 45 carried-over jobs. The partial trace remains explicitly incomplete; this validation did not upload data. - `actionlint` passed for all four changed workflows. `git diff --check` passed. - Full Node 24 `pnpm -r typecheck` and `pnpm build` passed. The local full `pnpm test:run` was stopped after it reported a setup-token timeout and a distribution-plugin-catalog fixture failure. The 30 setup-token tests passed on focused rerun. The plugin fixture fails at `rmSync` of a directory symlink on this macOS/Node 24.11.0 host; the same failure reproduces with the unchanged base Vitest configuration and unchanged test/service files (10 other tests pass). The local full test suite is therefore not claimed green. - A real root-config Vitest probe passed 13 tests with profiling both off and on. Multi-file Vitest, Playwright, and Node probes each verify two distinct filename rows and four correctly parented tests, including repeated test names across files. Separate passing probes exercise the full exporter hierarchy `workflow → job → step → filename → tests`. Intentional failing probes preserve failing exit status. - Verified all 48 measured jobs in latest-head run `38728040302` used AWS: one `paperclip-ci-routing-x64` gate and 47 `paperclip-public-pr-x64` jobs. Profiling preserves AWS authorization and its GitHub-hosted fallback. The separate privileged exporter runs on `ubuntu-latest` outside the measured suite. - [Live Honeycomb baseline](https://ui.honeycomb.io/paperclip/environments/test/datasets/paperclip-ci/trace/oaPMzw8zGwG): 48 jobs, 731 spans, 479 seconds. It matches [GitHub run 38671274294](https://github.com/paperclipai/paperclip/actions/runs/38671274294). This historical trace has job/step data only; it is not proof of the future label-triggered test-reporting journey. - Verified the dedicated Honeycomb key is ingest-only with dataset creation disabled. Verified the GitHub environment allows only the `master` branch. No repository-level secret of that name exists. Both credential values were scanned absent from source and branch history. After merge, add `profile-ci` to a CI CODEOWNER PR, wait for the entire PR run and exporter, then follow the run-summary link. Collapse job children to compare parallel lanes; expand a job to inspect its steps and tests. ## Risks - Activation requires merging the trusted workflow definitions to `master`. This PR continues using the current trusted reusable workflows until then. - Selected runs produce many spans and artifacts. Oversized artifacts fail export instead of truncating data. Missing or cancelled reporters are marked incomplete. - GitHub timings have second precision. Node test times use reporter receipt time. Rust retains job/step timing but lacks per-test wall timestamps. - CI CODEOWNERS are individual users in the explicit `.github/**` rule. Unsupported team rules and identity lookup failures disable profiling. - An interrupted upload can leave partial data. Retrying uses the same span IDs, but the Events API does not promise deduplication. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, code execution, repository tools, and browser verification. The runtime does not expose the exact serving model ID or context-window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [ ] 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> |
||
|
|
1897080a6d |
test(scripts): retire duplicate provisioning fallback launch (#16110)
Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
5c65525219 |
test(scripts): consolidate stable shard selection cases (#16109)
Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
445feaa7aa |
fix(server): index retained workspace task authorization (#16334)
## Thinking Path > - Paperclip manages AI agents and their work. > - Before an agent starts, repository admission checks access to retained workspace files. > - Admission holds a company provenance lock while it checks each source and reader. > - The retained-task query cast the indexed task ID to text. PostgreSQL could evaluate privacy across company history before it matched one source ID. > - Repeated slow checks kept the lock for hours and blocked other agent launches. > - This change looks up the canonical source UUID through the existing primary key before it checks privacy. > - The query does less work and keeps the same access decisions. ## Linked Issues or Issue Description **What happened?** Nine runs appeared active but had no provider process or log file. Read-only database inspection found a transaction holding the company repository-provenance lock for more than ten hours. Eight other transactions waited for that lock. The owner repeatedly ran workspace authorization queries. The company had about 13,400 tasks and 8,500 workspaces. **Expected behavior** A retained-source check should find the referenced task before it evaluates that task's privacy. Unrelated task history should not multiply the privacy work for every source and reader. **Steps to reproduce** 1. Run the new `workspace-authorization-query.test.ts` against authorization code from `5c7a025032`. 2. The real PostgreSQL fixture has 1,200 unrelated tasks and one retained source. The regression fails with 2,402 recursive privacy traversals, above the bound of 100. The other five access tests pass. 3. Apply this change and run the same test. All six tests pass. Related: Refs #16330 adds workspace timing evidence. This PR fixes a measured SQL plan. It does not change those tracing boundaries. ## What Changed - Compare the UUID task column with a guarded canonical UUID from the retained-source JSON key. - Reuse `canonicalExecutionUuid`. Invalid and noncanonical keys still match nothing and cannot cause a UUID parse error. - Add real PostgreSQL coverage for query work, missing and foreign sources, malformed and uppercase IDs, both agent and sponsor grants, and grant revocation. - Add a reproducible baseline comparison and document its scope in `doc/DATABASE.md`. ## Verification - Red: the unchanged query fails the new work-bound regression. Five access cases pass. - Green: 101 tests pass across the new query suite, workspace binding, and the production privacy review suite. - Full `pnpm -r typecheck` and `pnpm build`: pass. Dependencies use the repository's pinned pnpm 9.15.4. - All current-head CI checks pass, including the full server, chat, workspace, serialized, Runner, and eight E2E test lanes. Build, typecheck, canary, and security checks pass. Head: `ad907f6e14c2d773fa8c20692e5ccc10215c9297`. - Greptile: 5/5 on that head, with no actionable findings or unresolved review threads. The branch is mergeable. - The local full `pnpm test:run` was started, then stopped after a concurrent disposable-database check hit the macOS shared-memory limit. This is not counted as a local full-suite pass. The benchmark passed when rerun alone; the complete suite passed in CI. - `git diff --check`: pass. The branch has no lockfile or workflow changes. Synthetic SQL comparison on PostgreSQL 18.1, with 13,429 tasks and one retained source: | Query | Median | Five measured samples | Recursive privacy traversals | | --- | --- | --- | --- | | Baseline `5c7a025032` | 42.57 ms | 42.57, 47.71, 44.51, 41.29, 41.44 ms | 26,860 | | Fixed | 2.37 ms | 2.76, 2.35, 2.37, 2.11, 3.33 ms | 4 | Both versions return identical complete rows. The benchmark alternates variants after two warmup rounds. It loads the baseline authorization module with current dependencies; the UUID helper is unchanged. The measured gain is about 18x for this SQL fixture. The final committed benchmark also passed a second isolated run: 55.44 ms baseline and 3.26 ms fixed, with identical complete rows (about 17x). Two read-only queries on the affected database also returned identical complete rows. One changed from 129 ms to 7 ms; a workspace with 49 retained sources changed from 576 ms to 11 ms. These are single paired measurements, not endpoint or startup benchmarks. Reproduce: ```sh pnpm exec vitest run server/src/__tests__/workspace-authorization-query.test.ts server/src/__tests__/task-workspace-binding.test.ts server/src/__tests__/privacy-production-review.test.ts pnpm --filter @paperclipai/server exec tsx ../scripts/benchmark-workspace-authorization.ts --baseline-ref=5c7a025032 pnpm -r typecheck pnpm test:run pnpm build ``` ## Risks - A direct UUID cast could broaden or break access for malformed keys. The existing canonical guard and regression cases preserve the former text-match behavior. - Planner choices can differ across PostgreSQL versions and data sets. The regression bounds real privacy work rather than elapsed time or one exact plan shape. - Admission still checks every retained source and reader under its existing lock. This removes a measured query cost; it does not claim a bound for the full admission process. - No schema migration, permission change, lock removal, or live deployment is included. Recovery of the affected runs remains unverified until rollout. ## Model Used OpenAI GPT-6 through Codex, with tool use and code execution. The exact served model variant and context-window size are not exposed to this task. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#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> |
||
|
|
b226336762 |
ci: skip full CI for release-notes-only pull requests (#16207)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Each beta release ends with a pull request that adds one release notes file under `releases/` > - PR CI runs the full build, test, and e2e matrix for that pull request > - No build, test, or e2e lane reads `releases/v*.md` or `releases/beta/v*.md` > - The full matrix takes about 30 minutes, and lost runners or flaky e2e specs can make it run again > - This pull request lets the existing CI scope gate skip the heavy lanes when a pull request changes only release notes > - The benefit is that release notes pull requests get a green result in minutes, and code pull requests keep full CI ## Linked Issues or Issue Description **Issue type** CI efficiency enhancement. **Where is the issue?** The `Select stacked PR CI scope` step in `.github/workflows/ci-routing.yml`. This step sets the `full_ci` output for PR CI. **What's wrong?** The step sets `full_ci=false` only for middle pull requests in a stack. A pull request that changes only one release notes markdown file runs the full matrix. For example, #16053 changed one file in `releases/beta/`. Its CI ran two times: on the first run, 8 shards lost their runners, and on the second run, one Playwright spec flaked and needed a rerun. **Suggested fix** Read the pull request diff from the GitHub compare API in the scope step. When every changed path is release notes, set `full_ci=false`. The callers already support this value. I found no open pull request or issue for this change. ## What Changed - `ci-routing.yml`: the scope step (renamed to `Select PR CI scope`) also sets `full_ci=false` when every path in the diff matches `releases/v*.md` or `releases/beta/v*.md`. - The step reads the diff from `compare/<event base SHA>...<event head SHA>`. The SHAs come from the event, so a later push cannot change the decision for this run. - For a renamed file, the step checks the old path and the new path. - The step keeps full CI when the event is not `pull_request`, a SHA is malformed, the API call fails, the diff is empty, or the file list has 300 entries. The compare API can truncate a list at 300 entries. - The step does not change the stacked pull request rules. It checks the paths only when the stack rules select full CI. - `ci-routing.test.mjs`: the GitHub stub now returns `files` for compare calls. 17 new cases cover release notes paths, mixed diffs, renames, non-markdown files, nested folders, empty and truncated lists, API failure, non-PR events, malformed SHAs, and stack interaction. - `e2e-shard.test.mjs`: the test now uses the new step name. - `doc/DEVELOPING.md`: added a short description of the CI scope rules. ## Verification - `node --test .github/scripts/tests/ci-routing.test.mjs scripts/__tests__/e2e-shard.test.mjs`: 73 pass, 0 fail. - `node --test '.github/scripts/tests/*.test.mjs'`: all pass. - I ran the jq filter on real compare API responses. #16053 (one file in `releases/beta/`) returns `true`. #16082 (10 files) returns `false`. - After merge: open a pull request that changes only a `releases/beta/v*.md` file. The `Select trusted runner` job shows the notice `release notes only; full_ci=false`. The heavy lanes show as skipped. The `policy`, `verify`, and `e2e` checks pass. Note: `pr.yml` calls `pr-trusted.yml@master`, and that workflow calls `ci-routing.yml@master`. This pull request does not change its own CI run. The change applies after merge. ## Risks - Low risk. The skip uses the existing `full_ci=false` path. The `verify` and `e2e` aggregate checks already accept that value, and the `policy` job always runs. - A future job that reads release notes files would not run for notes-only pull requests. Today, only the release workflows read these files, and those workflows do not run on pull requests. - The step now uses `GH_TOKEN` to call one more read-only API endpoint. The workflow still does not check out or run pull request code, and its permissions do not change. ## Model Used - Claude Opus 5.5 (`claude-opus-5-5`), Anthropic. Agentic coding with tool use (shell, file edits, 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 - [ ] 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: devinfoley <139239+devinfoley@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
ad0bd26bb7 |
perf(heartbeat): avoid Git inspection for stored workspace reads (#16306)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Heartbeat selects and restores a saved execution workspace before dispatch. > - These reads used the workspace detail reader, which also scans Git and resolves delivery state. > - Configuration reads do not use those live display fields. Each extra process can delay other controller work. > - This pull request adds a stored-record reader and uses it in configuration, environment selection, and finalization. > - It also derives ancestry from the existing ahead/behind result and skips delivery HEAD reads for unfinished tasks. > - The benefit is fewer Git processes while live execution and cleanup guards remain in place. ## Linked Issues or Issue Description Related: #16282, #16302, #13619. Those changes reduce background or display scan demand. This change removes live display inspection from execution configuration reads. **What existing behavior does this improve?** Heartbeat workspace configuration reads and workspace close-readiness checks. **Current behavior** Reading saved workspace configuration also loads runtime health, Git status, ancestry, and delivery state. Close readiness walks history twice to determine ancestry. **Proposed behavior** Execution reads stored configuration through a company-checked method. Live branch validation and destructive cleanup still inspect current Git state. Close readiness uses its ahead/behind result to determine ancestry. **Reason and benefit** A synthetic benchmark of the actual service returned identical stored fields for 20 workspaces. Detail reads launched 60 Git commands and took 689 ms. Stored reads launched zero Git commands and took 8 ms. This was a local macOS measurement, not an end-to-end cloud latency claim. **Breaking changes** None to public APIs or saved data. Workspace detail responses keep their live fields. ## What Changed - Add `getStoredById(companyId, id)` and use it in three heartbeat reads. - Preserve the access-denied error for a foreign-company workspace. - Remove the extra `merge-base` process and the unused HEAD read for unfinished tasks. - Add recovery, company-boundary, ancestry, and cleanup regressions. - Add a repeatable database/Git benchmark and document the read boundary. ## Verification - The new environment-selection regression failed before the fix with `Live Git inspection is unavailable` and passes after it. All eight environment-selection tests pass. - On the final rebased commit, workspace service, environment selection, and branch finalization: 89 tests passed. Branch-containment, runtime-execution, and display-cache suites also passed during development. - `pnpm -r typecheck`: passed. - `pnpm build`: passed. - `pnpm test:run`: started locally, then stopped after all full-suite CI test shards passed on the final commit. The complete local run was not finished; CI provides the full-suite result. - Final commit `9a13ef0481b7bf6a60b2b7ac13f35f78a14e232c`: 55 successful checks and 2 expected skips. Greptile: 5/5, no actionable findings. - `pnpm --filter @paperclipai/server exec tsx ../scripts/benchmark-workspace-record-reads.ts`: identical stored fields, 60 to zero Git commands, 689 ms to 8 ms for 20 reads. ## Risks - Execution callers must use saved fields only. Detail readers and live branch and cleanup guards remain separate. - A failed ancestry comparison stays unknown. Automatic cleanup still rejects unknown delivery state and rechecks Git before deletion. - This patch has not been deployed. It does not prove the full slow-run latency is resolved. ## Model Used OpenAI Codex, GPT-6. The exact model identifier and context window are not exposed in this session. Used reasoning, repository inspection, code editing, and local command execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
bd64eb27b0 |
perf(recovery): use indexed execution identity lookups (#16291)
## Thinking Path > - Paperclip manages AI agents and their execution. > - Recovery must keep old execution ownership visible before new work starts. > - Ownership reads filter large run contexts through a combined text expression. > - Recovery and status delivery also cast indexed UUID columns to text. > - These reads can scan history before finding the requested execution. > - This pull request preserves identity and ownership rules while using existing indexes. > - The benefit is less database work during recovery and task polling. ## Linked Issues or Issue Description Refs #14406. Related community report: #15275. This is an independent implementation. It does not use that pull request's code or commits. It covers the reported execution joins and the additional ownership query hotspot. **What happened?** Accumulated staging query statistics showed 11,782 ownership reads at 51 ms each. A paired recovery-action read averaged 22 ms. Both queried large run JSON. Text casts also prevented indexed UUID lookups in recovery and status delivery. **What did you expect to happen?** Recovery must find the same execution evidence through existing indexes. Malformed identifiers must match nothing without a cast error. Native issue bindings must retain precedence. Missing termination evidence must continue to block new work. **Steps to reproduce** Run the disposable benchmark below. It loads the original service modules from the baseline revision. It compares their exact ownership, blocker action and status-delivery SQL with the current modules on 1,400 synthetic runs, 350 historical recovery actions and 192 KiB contexts. ## What Changed - Convert saved text to UUID only after checking its canonical lowercase form. - Keep indexed run and task UUID columns unchanged in execution joins. - Split native and legacy issue predicates so existing indexes can filter ownership candidates. - Preserve company scope, native precedence, process and lease holds, recovery eligibility and delivery receipts. - Add real PostgreSQL identity and ownership regressions, a reproducible benchmark and database documentation. ## Verification - Local service SQL benchmark: ownership 78.30 ms to 1.14 ms, with the same two complete rows. Blocker action read 76.94 ms to 22.55 ms, with the same complete row. These are synthetic SQL timings, excluding process probes, provider calls and HTTP. - Status delivery returned the same 100 rows. Timing was neutral on the small-task fixture: 7.85 ms before and 8.30 ms after. No speedup is claimed for that case. - 231 local tests passed across six server suites. They cover malformed identifiers, canonical spelling, company scope, native precedence, retained processes, workspace restore, native replacement, conversations and delivery. - `pnpm -r typecheck` and `pnpm build` passed. - `git diff --check` passed. - All current-head CI and security checks passed, including the full general and serialized suites, browser shards, Runner verification and build. Greptile reviewed the exact commit at 5/5 with no actionable findings. - The older full local sweep in the companion worktree was stopped after final-commit complete CI passed. It is not claimed as a completed local pass. The 231 focused tests above passed locally on this branch. ```sh pnpm --filter @paperclipai/server exec vitest run src/services/conversation-continuation.test.ts src/services/legacy-execution-recovery.test.ts src/__tests__/legacy-workspace-restore-recovery.test.ts src/__tests__/chat-completion-delivery.test.ts src/__tests__/agent-conversations.test.ts src/services/native-runtime/native-safe-replacement.test.ts pnpm --filter @paperclipai/server exec tsx ../scripts/benchmark-recovery-queries.ts --baseline-ref=1e731520bb ``` ## Risks - PostgreSQL accepts more UUID spellings than the old text joins. The explicit guard preserves the old lowercase spelling requirement. - Query plans depend on the data distribution. Small task sets can show neutral status-delivery timing. The benchmark is not a production latency claim. - Recovery ownership checks remain conservative. Process, lease, workspace and no-replay rules are unchanged. - No migration, new index, cache, cleanup change or lock removal is included. ## Model Used OpenAI GPT-6 through Codex, with reasoning, repository inspection, shell tools and local code execution. The runtime does not expose a more specific backend model ID or context-window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
ebeac833a6 |
perf(runs): bound history and reduce repeated context reads (#16286)
## Thinking Path > - Paperclip helps operators manage AI agents and inspect their work. > - Run history supplies recent execution records to the board and API clients. > - The list repeats eight reads of a large stored JSON context. > - A caller can also omit the limit and read the complete history. > - This pull request expands context fields once and bounds every list read. > - The benefit is lower database cost and bounded redaction work. ## Linked Issues or Issue Description Refs #958. Related community reports: #13962 and #10631. This is an independent implementation. It does not use their commits or code. It covers the history bounds reported in both. Process memory monitoring from #10631 is outside this change. **What happened?** The run-history query repeatedly extracts fields from large context JSON. Requests without a limit also load every historical run before authorization and redaction. Accumulated staging query statistics showed 271 ms for summary history and another 58 ms for its redaction lookup. **What did you expect to happen?** Normal reads must use a bounded recent history. Context projection must preserve the existing values and privacy behavior with less repeated database work. **Steps to reproduce** Run the disposable benchmark below against the baseline revision. It creates 1,400 synthetic runs with 192 KiB contexts. It compares the exact service SQL and every returned column for both summary and full history. ## What Changed - Expand context fields with one lateral record projection. Preserve non-object legacy contexts and the first-class issue binding. - Enforce a 200-row default and a 1,000-row maximum in the route and service. - Apply the default in the shared UI client, including both agent detail implementations. - Preserve response arrays, authorization, result projection and secret redaction. - Fetch older linked runs by ID in both agent pages. Check company and agent scope, navigation races and visible retry errors. - Update OpenAPI, data-path documentation and capability maps. - Add real PostgreSQL and HTTP regressions plus a reproducible benchmark. ## Verification - Local benchmark: summary history 37.72 ms to 19.34 ms; full history 37.84 ms to 19.01 ms. All 200 complete positional rows match in each comparison. These are synthetic local SQL timings, excluding HTTP and redaction. - History, route, privacy and redaction suites: 160 server tests passed across six files. Twenty-two UI API, selection, run-panel and log-visibility tests passed. Both agent-page variants render an older linked run with an empty history page on desktop and mobile. - `pnpm -r typecheck` and `pnpm build` passed. - Map validation and `git diff --check` passed. - All current-head CI and security checks passed, including the full general and serialized suites, browser shards, Runner verification and build. Greptile reviewed the exact commit at 5/5 with no remaining findings. - The full local sweep began before the final compatibility fixes. It was stopped after the final commits passed complete CI. The focused local suites listed above passed on the final code. Before interruption, the broader local sweep passed 31,743 tests across the general server, UI and several package groups, with no reported failures. The full local command is not claimed as a completed pass. ```sh pnpm --filter @paperclipai/server exec vitest run src/services/heartbeat/run-state.test.ts src/__tests__/heartbeat-list.test.ts src/__tests__/agent-live-run-routes.test.ts src/__tests__/run-secret-redaction.test.ts src/__tests__/heartbeat-run-privacy-routes.test.ts pnpm --filter @paperclipai/ui exec vitest run src/api/heartbeats.test.ts pnpm --filter @paperclipai/server exec tsx ../scripts/benchmark-run-history.ts --baseline-ref=1e731520bb ``` ## Risks - Clients that relied on an unbounded array now receive 200 rows by default. Explicit limits allow up to 1,000. This change does not add pagination. - Legacy context conversion must stay identical. Real database regressions cover null, array, scalar, nested values and native issue precedence. - No schema migration or persistent cache is introduced. Redaction and access checks remain active. ## Model Used OpenAI GPT-6 through Codex, with reasoning, repository inspection, shell tools and local code execution. The runtime does not expose a more specific backend model ID or context-window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
e9b6c4d44c |
perf: remove history scans from task and chat queries (#16278)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Task reads and external chat notices must remain responsive as run history grows. > - The chat notice sweep casts indexed UUID columns to text. > - Run redaction and task provenance filter large JSON contexts with expressions that lack matching indexes. > - These queries scan history and read large stored contexts on common requests. > - This pull request adapts two existing fixes to current master and adds the missing provenance index. > - The benefit is less database work with the same query results and access rules. ## Linked Issues or Issue Description Refs #15927. This change adapts that chat sweep fix to the extracted inbound notice module and retains the contributor credit. Refs #12499. This change adds that missing nested-context index through a current, concurrent migration. It retains the contributor credit. This combined change replaces those older layouts for the measured query paths. It also covers task creation provenance, which those pull requests do not address. **What happened?** The chat notice sweep scans wakeup history. Issue redaction scans run contexts because only one branch of its JSON condition has an index. The task creation-source filter also scans contexts because its native and legacy ID expression lacks an index. **Expected behavior** The queries use indexed lookups and return the same rows. Company access, task origin precedence, secret redaction, and chat notice ordering remain the same. **Steps to reproduce** Run `pnpm --filter @paperclipai/server exec tsx ../scripts/benchmark-slow-queries.ts --baseline-ref=f8af817f8d`. The benchmark creates disposable PostgreSQL data and compares the old query with the current query on the same fixture. ## What Changed - Compare chat UUID columns directly with safely parsed payload IDs. Reject malformed and noncanonical IDs without a cast failure. - Add the nested `paperclipIssue.id` run-context index and the exact native/legacy task-provenance expression index. - Build both indexes concurrently. Register the migration for top-level execution and invalid-index retry repair. - Extend chat payload and migration regression coverage. - Add a repeatable synthetic SQL benchmark and document its scope and command. - Keep the five newest schema snapshots. ## Verification - Focused local checks: 76 selected tests passed in five files. These cover FIFO notices, malformed IDs, conversation state, redaction, provenance, and company boundaries. - Disposable PostgreSQL 18.1 fixture: 335 tasks, 1,400 runs, 13,000 wakeups, 377 actions, and 192 KiB synthetic contexts. - Five warm samples per query, after two warmups. Every returned SQL column matched before and after, compared as positional tuples so duplicate unnamed projections are retained. | Query | Before, median | After, median | Improvement | | --- | ---: | ---: | ---: | | Chat notice candidates | 26.21 ms | 6.43 ms | 4.1× | | Task creation-source list | 159.69 ms | 6.51 ms | 24.5× | | Issue redaction contexts | 131.88 ms | 0.34 ms | 389.1× | The run-history context projection returned the same 200 rows and kept the same index plan and buffer counts. Its timings were noisy (37.30 ms before and 56.78 ms after in the last run; 34.25 ms and 34.14 ms in the previous run). No improvement is claimed for this control. Its repeated JSON projection remains a separate optimization opportunity. The populated plans use the wakeup primary key, the provenance expression index, and a BitmapOr over both redaction indexes. These are local SQL measurements. They do not prove an equivalent change in hosted API latency. - `pnpm -r typecheck` and `pnpm build` passed locally. - The full local `pnpm test:run` was started and then interrupted (exit 130) when the Mac reached its PostgreSQL shared-memory limit. It did not complete and is not reported as passed. The final SQL benchmark passed after its disposable database resources were released. The full general and serialized test suites passed in CI. - All CI checks for final head `193acca6abaa992acad12f4b631bd31dd3234641` passed, including full Vitest coverage, E2E checks, typecheck, build, migration order, and lifecycle boundaries. - Greptile reviewed that exact head at 5/5 with no actionable comments. ## Risks - Both indexes add storage and write cost. Initial builds read stored run contexts and can take time on large histories. - Concurrent index builds avoid holding a write-blocking table lock for the whole build. The existing migration retry path removes invalid partial indexes before retrying. - The chat parser accepts only canonical lowercase UUID text. This preserves the prior text comparison, including rejection of uppercase and malformed values. - Staging has not been migrated or deployed. Local PostgreSQL and synthetic data do not reproduce hosted load or network latency. ## Model Used - OpenAI Codex, based on GPT-6. The exact serving model ID and context window were not exposed in this session. Used reasoning, repository tools, browser inspection, and local code execution. The adapted fixes retain their original contributor credits. ## 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> |
||
|
|
b7f41ee51d |
perf(ci): warm the public-install npm cache during pnpm build (#16204)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Each pull request runs the Trusted PR CI. The `ci / Build` lane is the longest check, or close to the longest, in each green run. > - On 2026-10-13, `ci / Build` took 415-446s in runs 38426120144, 38432086560 and 38423713537. Of that, the public-install verifier took 226-241s. > - In the verifier, the consumer `npm install` took 119-129s. It downloads the full public registry graph into an empty npm cache. > - Source manifests set that graph. Thus CI can download it before `pnpm build` makes any tarball. > - This pull request fills the npm cache in the background while the Rust restore, Evalbook and `pnpm build` run. Then the verifier reads that cache. > - The benefit is a shorter `ci / Build` lane. The verifier keeps all its checks. ## Linked Issues or Issue Description Refs #15213, #15849, #15868, #15888 (earlier changes that made this verifier faster). **Enhancement description** The `ci / Build` lane runs the public-install verifier after `pnpm build`. The verifier starts with an empty npm cache. Its consumer install then downloads the full public registry graph: 119-129s of a 226-241s step. **Proposed change** Download the same registry graph into an npm cache in the background, during the earlier part of the lane. Give that cache to the verifier. **Why it helps** The download moves off the critical path of the lane. A local test of the same 628-package install took 51s with a cold cache and 21s with a warm cache. ## What Changed - Add `scripts/public-install-closure.mjs`. It holds the one definition of the public package closure: `@paperclipai/server`, `paperclipai`, and each public workspace package that they reach through `workspace:` specs. It also gives the registry dependencies of that closure. - Add `scripts/warm-public-install-npm-cache.mjs`. It installs those registry dependencies into a temporary consumer, with scripts disabled, to fill `PAPERCLIP_PUBLIC_INSTALL_NPM_CACHE`. Then it removes the temporary consumer. - `scripts/verify-grok-npm-install.mjs` now gets its closure from the shared module. When `PAPERCLIP_PUBLIC_INSTALL_NPM_CACHE` is set, it uses that directory as the consumer npm cache. When the variable is not set, it uses a new empty cache, as before. `docker-runner-check.yml` and `release-smoke.yml` do not change. - `pr-trusted.yml` (Build job): a new step starts the warm-up in the background after `Install dependencies`. The verify step waits for the warm-up for a maximum of 180s and then gives the cache to the verifier. If the warm-up fails, the step writes a notice and the verifier continues as before. - Add `scripts/__tests__/public-install-closure.test.mjs` and add it to `test:release-registry`. Update the closure assertions in `grok-public-install-sandbox.test.mjs`. ## Verification - `node --test scripts/__tests__/public-install-closure.test.mjs`: 4/4 pass. - `node --test scripts/__tests__/grok-public-install-sandbox.test.mjs`: 24/24 pass. - `node --test scripts/__tests__/run-vitest-stable-shard.test.mjs scripts/__tests__/e2e-shard.test.mjs scripts/__tests__/runner-release-crate-cache.test.mjs`: all pass. - `release-verify-workflow.test.mjs`: the two "publisher lockfile" tests fail in my sandbox on clean master too, because they need pnpm. Two canary git-fixture tests timed out once under load. They pass when they run alone. - I ran the warm-up against current master: 62 direct dependencies, 628 packages, 51s cold. The same install with the warm cache took 21s. - Important: `pr.yml` calls `pr-trusted.yml@master`. Thus the CI of this pull request runs the refactored verifier on its default path (empty cache), but not the new warm-up steps. The warm-up steps start after merge. To measure them, compare the `consumer_install_ms` value in the `paperclip.public-npm-install.timing.v1` line of a Build job before and after merge. - Final review: all latest-head CI checks pass (54 successes, one neutral result, two intentional skips). Fresh Apex is 5/5 on `64d091b8b0c5359fa3dc0edb1fd7ef9d24294477` with no unresolved findings. The two relevant local script suites pass all 28 tests. Current master combines cleanly. ## Risks - Low risk. The verifier result does not change. npm checks each cached tarball against the integrity of its own resolution, and the consumer directory and lock start empty. - npm can use a cached registry packument that is a maximum of about 5 minutes old (registry `max-age`). This has the same effect as starting the verifier a few minutes earlier. - The warm-up runs at the same time as `pnpm build`. It uses network, disk and some CPU. In the measured runs, `pnpm build` took 76-96s. - If the warm-up is slow or fails, the verify step waits a maximum of 180s and then continues with what is in the cache. - The verifier receipt still reports `cleanNpmInstall: true`. The consumer install is clean. Only the download cache is shared. ## Expected time savings - `ci / Build`: an estimated 65-85s less, from 415-446s to about 340-370s. The consumer install goes from 119-129s to about 40-55s, from the local cold/warm ratio. - Full PR time: after this change, `ci / Build` is no longer the longest lane. The longest lanes become `General tests (server N/12)` and `Verify Paperclip Runner (vitest 1/2)` at about 405-496s. Thus the full PR time decreases only when Build is the critical path. That is approximately 0-30s in the runs above. ## Model Used - Anthropic Claude Opus 5.5 (`claude-opus-5-5`), with tool use and code execution in a Paperclip agent run. OpenAI GPT-6 (`gpt-6`) through Codex assisted the final repository review and targeted script validation. This session 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 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
22d05644f4 |
feat(ui): add Speko voice setup, task calls, and Storybook coverage (#15728)
Runtime #15727 is merged. This PR adds the UI. Qualification follows in
#15729.
## Thinking Path
> - Paperclip manages agent work through tasks and governed connections.
> - Chat connections already bind external conversations to those tasks.
> - Speko handles voice and telephony, while the selected Paperclip
agent does the work.
> - A call needs durable session authority, ordered follow-ups, and safe
result delivery.
> - This PR adds the Speko setup and call controls to the existing Apps
and task UI.
> - This PR depends on #15727. The qualification suite follows
separately. Speko stays experimental.
## Linked Issues or Issue Description
**Problem or motivation**
Phone and browser voice conversations cannot use the chat connection
task lifecycle. A separate voice runtime is needed to preserve task
authority, retries, and reply history.
**Proposed solution**
Add company-scoped voice sessions, signed callbacks, durable replies,
inbound intake, and an agent-facing outbound-call tool. Reuse existing
tasks, queues, secrets, and publications.
**Roadmap alignment**
This extends the experimental chat connector entry points under Agent
Chat and Connected Apps. The project owner requested this feature.
Refs #11418 for the original provider catalog proposal. This
implementation uses the newer chat connection infrastructure rather than
an MCP catalog-only integration. Refs #15721 for remote OpenCode
startup.
## What Changed
- Add the Speko Apps catalog entry, provider artwork, and browser SDK.
- Reuse existing agents in setup. Keep the optional Company Phone Agent
in the catalog, with connection instructions available to any assigned
agent.
- Add task voice controls, transcripts, phone callbacks, inbound-line
settings, and call Activity entries.
- Surface retryable connection and incoming-task inventory failures,
preserve active call controls and cached tasks, restore keyboard focus
after recovery, and bound notification polling so a stuck request cannot
hide later results.
- Put Save & exit and Connect Speko in the credential step’s shared
footer.
- Add deterministic production-component Storybook fixtures for setup,
lifecycle, failures, permissions, and phone surfaces.
- Include voice components in the design guide. Stories never request a
real microphone or place calls.
## Verification
- All 27 focused UI/controller regressions, UI typecheck, token gates,
and 28 map/catalog structural tests pass. The shared connection cache
test covers pause/resume invalidation during the 30-second fresh period.
- Storybook builds 157 Speko production-component stories. The complete
prior 156-story set passed all 624 checks on UI source
|
||
|
|
433d94ee0b |
refactor(maps): generate indexes from local story and feature metadata (#16214)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Feature recipes and Storybook help contributors find behavior, examples, and verification steps. > - Independent feature changes currently update shared catalogs, indexes, and review hashes. > - Those shared files cause merge conflicts and repeated bookkeeping during parallel work. > - This pull request stores metadata in each feature recipe and story, then generates the combined views. > - Contributors can merge independent work without editing a common index. Git and PR evidence retain change and review history. ## Linked Issues or Issue Description **What existing behavior does this improve?** Maintaining the product, agent-access, and Storybook maps while multiple agents change different features. **Current behavior** A story or recipe change can update `catalog.json`, `INDEX.md`, review hashes, verification tables, and tracked generated navigation. Two unrelated changes then conflict in the same files. **Proposed behavior** Each story declares capability links and classification in `parameters.paperclip`. Each feature recipe declares its navigation and optional verification guidance. Startup, build, and UI typechecking discover these sources and generate ignored indexes and Storybook pages. **Reason and benefit** A routine change edits its own source files. Aggregate metadata is rebuilt from the merged checkout. There is no sidecar registry, shared review journal, or hash acknowledgment to maintain. **Breaking changes** The tracked Storybook catalog and index paths are retired. Consumers use `ui/storybook/generated/` or `maps/generated/` after generation. Contributor instructions and the existing feature-gap browser suite use the new paths. Story and overview IDs remain stable. ## What Changed - Move the existing annotations into 262 story files. Preserve classifications, capability associations, exports, and explicit IDs. - Discover all 35 feature recipes. Store section/order beside each recipe and move durable verification routes out of the shared table. - Remove tracked catalogs, inventories, overview pages, and inline preview ordering. Keep authored preview behavior in `preview-base.tsx`. - Generate the Storybook guide, feature/access Markdown indexes, gap report, page-reference inventory, and preview wrapper automatically. - Update the map contracts and maintenance skills to use Git history and revision-specific PR/CI evidence. - Add schema, identity, regeneration, and actual Git merge tests. Run these through the existing UI Vitest suite. Add focused browser navigation checks. This is one coordinated migration. Most of the 367 changed files contain only moved metadata or deleted generated content. Review the generator scripts, map contracts, Storybook configuration, and tests first. No product API or authorization behavior changes. ## Verification Passed: - `node scripts/check-maps.mjs`: 35 paired areas and 175 capabilities. - `node scripts/storybook-catalog.mjs --check`: 262 suites and 2,485 authored stories after incorporating current master. - `node --test scripts/check-maps.test.mjs scripts/storybook-catalog.test.mjs scripts/storybook-feature-index.test.mjs`: 28 tests, including independent branches merged in both orders with identical generated output and no tracked changes. - `pnpm --filter @paperclipai/ui exec vitest run storybook/map-tooling.test.ts`: the CI entrypoint runs those map tests. - `pnpm check:token-gates`. - `pnpm -r typecheck` and `pnpm build` before the final master rebase. - `pnpm build-storybook`: all 2,517 original story/docs URLs retained. Current master contributes exactly four additional recovery stories. - Focused Playwright navigation checks: search and open a feature without examples; expand verification guidance and check source links; retain capability order and follow a related Foundations suite. The final clean Storybook build passed after deleting every ignored map output. Post-rebase UI typechecking and both browser tests passed. The working tree stays clean after generation. The concurrent-cleanup regression fails with `ENOENT` without the fix and passes with it. All GitHub CI gates passed on `00fc7ec18e`, which also received Greptile 5/5 with no unresolved findings. The final merge commit `1c3c5143a6` incorporates master and resolves only the two modify/delete conflicts by retaining removal of the aggregate index and catalog. Master’s new workspace feature and access guidance is preserved. Map validation, catalog generation, overview generation, all 28 map tests, and diff checks pass after conflict resolution. The maintainer explicitly requested merging without another Greptile review. CI has not been rerun to completion on this merge commit. The local repository-wide `pnpm test:run` was stopped before completion after the earlier CI matrix passed; it is not reported as a local pass. No screenshot baselines or production acceptance are claimed. To repeat the browser check against an owned Storybook server: ```sh PAPERCLIP_GAP_STORYBOOK_URL=http://127.0.0.1:6136 pnpm exec playwright test --config tests/storybook-visual/feature-gap-stories.config.ts map-navigation.spec.ts ``` ## Risks - Existing branches need a one-time rebase to move their catalog changes into local annotations. The PR incorporates the recovery changes from current master. - Changing the same story or capability can still produce a meaningful conflict. This removes the shared aggregate bottleneck. - The generator uses Storybook's existing CSF parser. Literal-only annotations and parser regression tests protect the current contract. - Generated Markdown is available after running the generator; the published Storybook provides a browsable guide. - Shared source changes still require review. Removing hashes removes mechanical acknowledgments; it does not establish runtime parity. ## Model Used OpenAI Codex, based on GPT-6, with repository inspection, code execution, and browser-test tools. The exact deployment model ID and context window were not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [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 on the previously reviewed head `00fc7ec18e`; final conflict-resolution checks are documented above - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups on `00fc7ec18e`; another review was waived by the maintainer - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
5e8e992df2 |
fix(storybook): reconcile capability associations and map omissions (#16154)
## Thinking Path > - Paperclip helps people manage AI agents and their work. > - The feature map describes user capabilities and verification recipes. > - Storybook holds isolated examples of those capabilities. > - Missing catalog links can hide existing examples. > - Some stories also expose shipped capabilities absent from the map. > - This pull request adds verified source associations and three paired map entries. > - Readers can find existing examples without changing their homes or URLs. ## Linked Issues or Issue Description Refs #16052, #16049 and #16046. **What existing behavior does this improve?** Storybook capability lookup and the feature/agent access maps. **Current behavior** Seventy capabilities have no example link. Some matching stories already exist. Primary-agent preferences and company decision/fast-response services appear only under broad neighboring capabilities. **Proposed behavior** Add source-supported links across 34 suites. Keep shared foundations in place while cross-listing them. Add primary-agent, decision-model and fast-response capabilities to both upstream maps. Retain explicit simulation and partial-example limits. **Reason and benefit** The catalog distinguishes missing associations from missing examples. The upstream map describes three existing product capabilities more precisely. **Breaking changes** None to product behavior, story exports, folders, sidebar titles or URLs. A shared foundation can declare a reasoned `home: "foundations"` override while referencing related capabilities. ## What Changed - Add 55 references across 34 suites. Replace primary-agent suites' reporting-line association with their own capability. - Add three source-reviewed capabilities and their API/actor boundaries to paired maps. - Preserve the shared Foundations home when cross-listing developer design examples. Add a validation regression test. - Record which exports demonstrate each association and what remains simulated or unverified. - Regenerate the catalog and capability data. Preserve all original 223 authored suites and 2,210 story IDs. Retain the two skill-removal stories added by current master, for 2,212 authored stories in total. - Reduce empty example lookups from 70 of 171 capabilities to 59 of 174. Links do not establish complete capability coverage. ## Verification - Passed: 27 catalog/generator/map tests, catalog validation, map structural checks, token gates and skill validation. - Passed: source inventory comparison preserves all authored files, titles, meta IDs and story IDs. - Passed: repository typecheck/build and Storybook build. Final built index has 2,248 entries and preserves all previous entries, including the two skills stories added by current master. - The broad local repository test run was interrupted before completion to resolve a new master conflict. A complete local suite pass is not claimed; fresh CI passed on the reconciled branch. - Browser: Design links to preserved Foundations stories; company-service sections link settings/history/journey suites; decision SetupToHistory passed 12 interaction steps; primary-agent ReplacePrimary passed four steps. No console errors in selected checks. - Greptile: 5/5 on final commit `805a8af62abe589907e7cc6ca1b415ce1e0cc3c0`, with no findings or unresolved threads. - Final-revision CI passed all 57 checks/statuses, including all eight browser shards, server and Runner tests, typecheck and build. The unchanged Cloud-auth mocked-response race seen on a superseded revision did not recur on the final commit. No test expectations were changed. - New agent-access evidence is source-only. Live provider and agent-credential verification is not established. ## Risks - Suite-level associations can represent only selected states. Notes retain those limits and existing review classifications. - In-memory connection drafts do not prove reload persistence. Resume-failure UI does not prove successful continuation. No-op budget controls do not prove relief or resumption. - Three map capabilities document existing behavior. No permission, API, provider or production component changes. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, code execution and source inspection. The exact runtime model ID and context window are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
60bc0d5fee |
fix(release): run native builds and canary smoke after skipped channels (#16149)
## Thinking Path > - Paperclip lets people manage AI agents for work. > - Published packages need the native runner artifacts from their exact source. > - The release workflow selects one channel and deliberately skips the other channels. > - The native producer used an implicit success condition across those skipped dependencies. > - The merged-source release selected native artifacts but skipped their build and canary publication. > - This pull request makes the existing producer and canary smoke conditions explicit. > - Successful source selection, artifact verification and cancellation checks still apply. ## Linked Issues or Issue Description Refs #16028. **What happened?** [Release 38389963483](https://github.com/paperclipai/paperclip/actions/runs/38389963483) passed source selection, then skipped native production, canary publication and onboarding smoke. The exact source script requires native artifacts; the API does not expose the source job outputs. The registry canary still points to an older source. **Expected behavior** The selected release channel builds its required native artifacts, publishes its verified package, then runs the exact-version onboarding smoke. Skipped inactive channels must not suppress these jobs. **Steps to reproduce** Inspect the linked master-push run at `d67e3507b23041212fa26302ce6de078c5ebcc05`. Compare the successful source job and exact source script with the three skipped jobs. The two existing workflow contract cases also fail against the original conditions. **Paperclip version or commit** `d67e3507b23041212fa26302ce6de078c5ebcc05`. **Deployment mode** GitHub Actions release workflow. ## What Changed - Require `!cancelled()`, successful source selection and `required=true` for native production. - Require `!cancelled()` and successful publication for canary onboarding smoke. - Extend the existing workflow tests for selected channels, skipped ancestors, missing outputs, failed jobs and cancellation. ## Verification - The two affected contract cases fail before treatment and pass after treatment. - Focused source controls cover 28 producer and five smoke condition combinations. - Independent source review found no changes to source, trust, artifact, channel, permission or publication gates. - These tests check source predicates. Actual hosted routing and publication must still pass after merge. - Full existing release suite: 70/70 pass. Existing source-verification neighbors: 20/20 pass. - Workflow structure passes actionlint. Full shell lint reports five hints in unchanged commands. - Full hosted checks and fresh Greptile review are pending. ## Risks The producer serves all release channels. The explicit source-result and required-output checks retain each channel's admission gates. Cancellation still prevents new work. This does not change runtime code, packages, agent selection, or stored configurations. [GitHub documents the implicit status check](https://docs.github.com/en/actions/reference/workflows-and-actions/expressions#status-check-functions) and [skipped dependency behavior](https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/use-jobs). ## Model Used OpenAI Codex, based on GPT-6, with reasoning and code tools. This session does not expose a verifiable exact model ID or context window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] 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> |
||
|
|
9bd820e687 |
feat(storybook): mirror the complete feature-map index (#16052)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The feature map describes its user-facing capabilities and verification recipes. > - Storybook provides isolated UI examples for those capabilities. > - The previous organization showed only features with primary story suites. > - This pull request derives the complete Storybook index from the upstream map. > - Readers can find the same features in both places and see related examples or explicit gaps. ## Linked Issues or Issue Description Refs #16046 and #16049. **What existing behavior does this improve?** Storybook navigation and the downstream feature catalog. **Current behavior** The sidebar has 28 primary feature homes. The feature map lists 35. The main guide groups suites alphabetically by area slug. Related examples can live under a different feature. **Proposed behavior** Use the feature map's eight sections and 35 features in the same order. Give each feature an Overview page with all its capabilities, related example links, and missing-example messages. Keep shared foundations outside the product index. Preserve all existing stories and URLs. **Reason and benefit** Readers can move between the feature map and Storybook without learning a second index. A feature without cataloged examples remains visible. **Breaking changes** None to existing story IDs or product behavior. Storybook start and build now reject stale generated feature pages and ordering. Run the catalog generator after upstream changes, inspect the output, and review affected source fingerprints. ## What Changed - Generate 35 feature Overview stories and capability data from the upstream map. Generate the inline sidebar order required by Storybook. - Replace the main guide with the full ordered feature index and search. Link all related suites from feature pages, even across primary homes. - Preserve all 223 authored files, 2,210 story IDs, and the existing docs ID. Keep status, implementation, and fixture classifications visible. - Put the generated Markdown catalog in feature-map order. Keep generated guides outside example counts. - Update maintenance and review skills, documentation, and generator tests. Keep the feature map independent of Storybook. ## Verification - Passed: 16 catalog and generator tests; map checks; token gates; both skill validators. - Passed: `pnpm -r typecheck`, `pnpm build`, and the Storybook build. - Built-index comparison preserved all 2,211 previous entries and added only 35 feature overviews. Feature order matches the map. - Browser: inspected the complete index and sidebar, searched for Goals, opened its overview, and followed a related suite under Projects. The original suite renders. - Passed: all 8,170 UI tests in 728 files. Browser checks also covered empty search, capability-ID search, missing-example pages, the original editable-text bookmark, the CLI sidebar label, and searching/opening shared foundations. - The broad local `pnpm test:run` was stopped after a failure in the unchanged GitHub chat test `authorizes description edits as the editor, never inheriting the original author's access`. That exact test passed alone without code or expectation changes. A complete local repository suite pass is not established. - Original revision CI passed after one runner retry. The merged revision `5ca01c70716f23974680a8019ddc613035d11bc4` passed fresh CI. Local UI typecheck, catalog checks, 16 generator tests, map checks and token gates pass. - Greptile: 5/5 on final commit `5ca01c70716f23974680a8019ddc613035d11bc4`, with all findings resolved. - Master merge: inspected source drift in 61 catalog entries and regenerated INDEX, preserving upstream notes. Marked the sidebar suite that mounts IssueDetail unreviewed for the new activity query; recorded limits for composer and channel-default changes. No stories removed. - Final Storybook build passed. Browser filename searches for `new-task-composer` and `forms-editors` return the expected feature and shared example. - No visual-baseline or full production acceptance claim. The deeper authored scenario groups remain intact. ## Risks - The parser depends on the feature-map Markdown contract. It rejects unknown index rows, omitted feature recipes, and unexpected generated files. - A suite can reference several capabilities. A link proves catalog association, not complete behavior coverage or production parity. - Storybook treats `/` as a folder separator. Sidebar labels use a comma for that character; the guide and page headings retain the upstream name. - No database, API, authorization, or production component changes. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, code execution, and browser inspection. The exact runtime model ID and context window are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> |
||
|
|
d67e3507b2 |
feat(runner): qualify Codex platform packages and cache hosted builds (#16028)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Native execution needs a compatible installed daemon and provider dependency. > - The Codex-default work found missing platform packages and clean-install startup failures. > - Release builds also repeat dependency compilation and run preparation serially. > - This prerequisite packages four daemon targets and verifies installed native startup. > - It also caches hosted Cargo dependencies and overlaps JavaScript preparation with compilation. > - Agent creation defaults and experimental gates stay at the current master behavior. ## Linked Issues or Issue Description Refs #15683. Refs #15555. Refs #15422. Refs #15926. Refs #15932. Extract runtime and installation support from #15683. This prerequisite has 65 changed files. Creation, onboarding, imports, UI runner selection and graduation remain in the dependent PR. Feature/access maps and the Storybook source catalog stay synchronized. Existing agents keep their execution choices. ## What Changed - Correct the existing runner test fixtures. Reserve owned credential quorum listeners through the existing bounded fixture helper. Keep foreign listeners intact, run actual credential staging once, and preserve its rejection and unchanged-auth assertions. Reuse the durable-resume outer-limit correction. Wait for actual warm-completion and held-authorization callback entry under the existing recovery deadline and surface early request errors. Preserve every semantic assertion. - Retain bounded installation failure diagnostics through the existing qualification receipt upload. Keep the original error, 10-minute deadline and all success checks. - Keep startup ownership until credential preparation and registration drain. Reject duplicate and post-close startup/resume work. Observe shutdown during normal and adopted authentication readiness. Preserve the primary failure and retain private state when cleanup is unconfirmed. - Package Linux x64/ARM64 and macOS Apple Silicon/Intel daemons. Verify target headers, source identities, manifests, and hashes before assembly and installation. - Reuse the existing release producer/consumer workflows. Cache Cargo dependencies by target, OS, compiler, lockfile, and contract inputs. Rebuild workspace binaries. Permit trusted cache writes only for canonical exact-source master pushes. - Overlap JavaScript preparation with native compilation. Join both commands and failure/cancellation cleanup before artifact verification. - Preserve shell positional arguments in the shared SSH runner and apply environment assignments correctly. Reject environment option keys. Six before/after controls and two real SSH subprocess paths pass with zero provider calls; this fix lands before both Codex and Claude defaults. - Admit verified suspended SSH backups during cold controller continuation, using the same full-scope, integrity and lifecycle checks as sandbox targets. Two positive SSH cases fail before; all 14 positive/negative matrix cases pass afterward. Active ownership and corrupt/malformed/nonempty state remain rejected. - Record measured sandbox platform facts through the existing explicit environment probe. Bind facts to the company, effective provider configuration, immutable OCI image and actual captured image binding. Check the returned cleanup receipt. Reject client-authored proof and stale or named boot identities. Creation and discovery allocate nothing. Preserve connection-only behavior. - Resolve the actual remote Codex target and preserve same-host development overrides. Preserve runtime artifact verification. Use actual protocol/model compatibility rather than a numerical CLI version fence. - Resolve the installed Codex login dependency on 64-bit Linux and Mac independently of the daemon libc baseline. Preserve account homes and safe errors. - Fix actual clean-install TOML table comparison. Preserve strict semantic checks, comments, private writes, and malformed-input rejection. Preserve primary startup failures and bounded cleanup. - Document GNU libc 2.39+ and stock Ubuntu sandbox prerequisites. Qualify ARM startup with a scoped distribution profile and unchanged global restrictions. Preserve Windows and Alpine deferral. - Preserve selected and saved native Codex reasoning effort in the existing UI builder, while excluding it from other providers. This small shared correction prevents import edits higher in the stack from dropping effort. - Reuse existing installed-package checks and assertions. Paperclip tarballs contain no Codex native payloads. Official npm dependencies supply the consumer's Codex binaries. All Docker and native builds stay remote. ## Verification Candidate: `271d434c170e74bdedde65d0b13059a55419c943`. It includes current master `e168512f7bdbb6af6ea01954c6d7ed80b91e903e` and preserves prior candidates through ordinary commits. Current [full CI](https://github.com/paperclipai/paperclip/actions/runs/38346601686) is successful on attempt 2. GitHub reports 54 successful checks and four conditional skips, including required verify and browser aggregates, workspace typecheck/tests/build, Linux DB controls, both runner shards and [isolated native compilation](https://github.com/paperclipai/paperclip/actions/runs/38346601609). Fresh current-head Greptile is 5/5 with all four threads resolved. The passing build's clean Grok/Codex report records CI merge source `7a82a37438e6e448abc7cc5caa60dc2519a97be0`, 18 installed packages, omitted Codex payloads, official host-only npm dependencies and zero provider calls. Pi setup and its no-prompt lease verification also pass. The first attempt's single 60-second Node archive download timeout remains retained; its DNS/TLS/download cause remains unknown. One unchanged-source retry was requested through the normal Build-job dialog with debug logging disabled. GitHub's attempt 2 graph reports the other CI jobs as well; no second retry or source/deadline relaxation was made. The [final exact-source package campaign](https://github.com/paperclipai/paperclip/actions/runs/38347027535) is successful on literal `271d434c170e74bdedde65d0b13059a55419c943`. It passes all four native producers, public Linux package assembly and clean installed consumers on Apple Silicon, Intel Mac and Linux ARM64. The nine qualification-mode skips are intentional; full CI above covers their ordinary gates. Native builds and Docker assembly ran remotely. The predecessor [`dae808` package campaign](https://github.com/paperclipai/paperclip/actions/runs/38342104102) remains literal historical evidence. Only tests and the dated record differ from that source; runtime, package and workflow code is unchanged. The reused credential fixture correction passes all 42 canonical Node 24 controls with synthetic data and independent matching-source review, and the current hosted runner shard passes. Production credential behavior is unchanged. **Merge hold:** current-source CI, fresh 5/5 review and exact-source package qualification pass. Actual code-owner approval and normal protected merge remain pending. No slice has merged or deployed. GitHub CLI authentication needs refresh; the normal signed-in embedded GitHub UI provided this status without credential workarounds. - The master merge preserves both Storybook source-review appendices and the guarded test-home cleanup. All six existing cleanup controls pass without skips. Master's isolated-home helper/test/setup are byte-identical. The two existing whitespace lines in master's unrelated privacy test remain outside this PR's diff. - Canonical Node 24 passes all 24 existing public-install helper tests. Three narrow added cases prove bounded/redacted failure metadata, symlink exclusions, original exception identity, failed diagnostic writes and no false failure on success. The Mac installer now uses `--timing`; at most two 16 KiB tails and 32 structured entries per tail enter the existing receipt upload. Raw argv, URLs, environment, error text and stacks are omitted. A failed receipt explicitly remains FAILED/unqualified/runtime-not-attempted. The 600,000 ms install deadline and every real package/hash/payload/lock/lifecycle/runtime oracle are unchanged. - Canonical Node 24 reproduces the durable-resume outer timeout under controlled fake latency. Only its outer test limit changes to 15 seconds; internal 500 ms/5 second deadlines and usage/effect assertions remain. Controlled warm-recovery and before-bootstrap authorization scheduling delays reproduce their callback polling failures, while the explicit entry signals pass. Early recovery errors surface unchanged. Independent review is clear. Historical mock binaries support the fixture controls; fresh full hosted CI remains decisive. The original hosted callback failure cause is inconclusive. - The composed runner/surfaces/server/E2E TypeScript checks pass. Map checks pass 35 areas/171 capability IDs. Token gates pass. The existing Storybook catalog passes 223 files/2,210 stories; story IDs and classifications remain intact. The current master had 25 inherited stale fingerprints from three changed map recipes. Only those guarded fingerprints and a source-only review note change; all 92 non-map story/component/fixture inputs remain unchanged. Existing classifications are retained. This proves source structure, not visual or live acceptance. - The 65-file contribution audit has no code file crossing from below 1,000 lines to above the limit. Earlier comment cleanup preserves executable emissions, parsed workflows and action pins. Independent cleanup/catalog and three-file reporting reviews are clear. No new workflow, suite, grader or local native/Docker build was added. **Prior `dae808` gate evidence:** fresh Greptile is 5/5 with four resolved threads, isolated native compilation and the browser aggregate pass. Its first runner shard passes the previous two corrections but fails a different held-authorization cell at the implicit one-second polling deadline. It records 1,672 passes/one failure/three skips. This candidate applies the verified entry-signal correction without changing production deadlines or any semantic assertions. Its original hosted cause remains inconclusive until fresh CI. **Previous-source evidence, kept literal:** the [exact `16a532` package campaign](https://github.com/paperclipai/paperclip/actions/runs/38338806076) passes all four native producers, public Linux package assembly, Apple Silicon, Intel Mac and Linux ARM64 installed consumers. Its fresh review is 5/5 with all four threads resolved. Full CI records 52 successful checks, four conditional skips and the two fixture failures corrected here. This is not a green full-CI candidate or proof for the new source. `64c074fb8da1b31f8d6042c4fef48dc4164e759b` passed [full CI](https://github.com/paperclipai/paperclip/actions/runs/38332726938), 54 checks/four conditional skips, [isolated native compilation](https://github.com/paperclipai/paperclip/actions/runs/38332726787/job/115085895328), and fresh Greptile 5/5/all four resolved threads. The hosted transport suite passed 246 tests and startup trust passed 22, closing that source's local fake-binary limitation. These are historical after reconciliation. The [previous exact-source package campaign](https://github.com/paperclipai/paperclip/actions/runs/38332921463) built all four platform daemons and passed public Linux package assembly plus Apple Silicon and Linux ARM64 installed consumers. **Intel Mac failed:** its initial scripts-disabled npm install timed out before lifecycle/runtime assertions. The underlying download/resolution/host cause is unknown because the old helper deleted the npm logs. This is the concrete baseline for the diagnostic change. The failed campaign remains failed; no all-platform signoff or automatic retry is claimed. The earlier `a200495` [four-target campaign](https://github.com/paperclipai/paperclip/actions/runs/38283695248) and [scoped ARM qualification](https://github.com/paperclipai/paperclip/actions/runs/38291535914) remain component evidence. Cargo restores were cold misses; no warm-cache speedup is claimed. Paperclip tarballs contain no Codex payloads. Official npm dependencies supply Codex on the user's platform. Current-source full workspace typecheck/tests/build, Linux DB controls, static/Rust/native tests, all browser shards and exact-source package consumers must pass. New-agent defaults and final managed onboarding belong to #15683. Actual private Cloud composition, warm/cold signup, task/follow-up and rollback compatibility remain later release gates. Source audits found that ordinary managed onboarding does not run the saved platform probe and Cloud distributes named snapshots without a verified final boot-image binding. These dependent release blockers remain open; prequalified E2E fixtures do not close them. Master adds task-workspace migrations; the final image/migrator and previous-image checks must include them. ARM paid task/follow-up and ordinary OS APT installation are not proven. ## Risks - Multi-target packages require source and header agreement. Missing or mismatched artifacts fail explicitly. Existing execution choices remain unchanged. - Linux requires GNU libc 2.39+ and compatible sandbox prerequisites. The scoped hosted ARM preparation does not qualify arbitrary containers or kernels. Windows, 32-bit ARM, and Alpine remain deferred. - Only dependency crates are cached. Preview jobs cannot write trusted caches. Concurrent command cleanup must preserve the primary failure. - Native-free Paperclip packaging retains official Codex npm dependencies. No Codex payload bundling, schema migration, automatic agent migration, or production deployment is included. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, repository tools, code execution, and parallel agents. The exact serving model snapshot and context-window size are not exposed. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have 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> |
||
|
|
88bf4c6c1d |
refactor(storybook): organize folders and navigation by feature map (#16049)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The feature map describes product areas and verification entry points. > - Storybook has 223 story suites that show production components, proposals, and retained history. > - The parent PR maps those suites to features, but their folders and sidebar still use unrelated groups. > - This pull request puts the existing suites under feature folders and uses the feature map's names and order in the sidebar. > - Explicit meta IDs preserve existing story links while the titles change. > - Contributors can find stories through the same product structure without losing examples. ## Linked Issues or Issue Description Refs #16046. This is the requested follow-up. Parent #16046 is merged. This PR now targets master, with its single follow-up commit rebased onto the parent squash merge. The Storybook implementation is unchanged by that rebase. Related open Storybook PRs were checked; this change organizes existing suites and adds no product capability. ## What Changed - Move all 223 story files into folders named for their primary feature area. Keep useful scenario groups below the feature's sidebar label. - Order the sidebar by the eight feature-map sections. Put Overview first and shared Foundations last. Leave areas with no stories out of the sidebar. - Move 19 support files into `ui/storybook/support/` and update relative imports and active documentation. - Preserve all 2,210 story IDs and the single docs ID through explicit CSF meta IDs. Keep all entry names and story exports. - Record stable IDs and sidebar titles in the downstream catalog. Validate feature folders, title prefixes, and IDs. Update the maintenance skill and review evidence. ## Verification - Storybook build passed. Built index comparison against parent `75bd3c977cd828d5222823850339e8204f40eb47` found the same 2,211 entries, IDs, and names. - UI typecheck passed (`ui/node_modules/.bin/tsc -b` from `ui`, invoked as `./node_modules/.bin/tsc -b`). - UI Vitest project: 728 files and 8,176 tests passed. - Catalog checker and its nine tests passed. Feature-map checks, token gates, and the maintenance-skill validator passed. - Chromium: nine existing play cases and one render case reached `storyFinished: success` with no page exceptions. The guide rendered, sidebar sections followed map order, and a search for `steering/queue` opened its preserved story link. - Source comparison found only meta title/ID changes, rebased relative references, and updated fixture path text in story files. - To inspect: build Storybook, start `node scripts/serve-storybook-static.mjs --port 6136`, and open the Overview guide. Expand feature folders and use existing story links. - The complete repository suite was not repeated for this organization change. The parent records a backend timeout that passed in isolation, without a complete broad-suite pass. Visual comparisons remain blocked by the unpublished empty baseline. The separate fixture-server story was not run. ## Risks - Open branches that add stories under old paths will need to choose a feature folder and update the catalog. Cross-feature suites have one primary home and retain related capability references. - Sidebar paths change; story and docs IDs remain stable. Automated references to source paths may need the new location. - This is one requested follow-up with 258 changed files, mostly moves. It exceeds the usual review-size guideline because splitting it would leave the sidebar and folder convention partly migrated. - Browser verification samples ten stories, not all 2,210. Existing production/prototype classifications and review gaps remain unchanged. - Required CI gates and a 5/5 review passed on the original head. Fresh checks and review are running for the rebased head. Catalog validation and all nine checker tests passed after rebase; UI, map, skill, and checker contents are identical to the original reviewed head. ## Model Used - OpenAI Codex, GPT-6. The exact runtime model ID and context-window size are not exposed in this session. Used reasoning, repository inspection, code execution, and local 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 - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
9e721264e9 |
feat: maintain Storybook through a downstream feature catalog (#16046)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Storybook supports review of its production UI and proposed designs. > - Its 223 story files have no consistent link to product capabilities or record of component and mock provenance. > - Old compositions can drift while they still look like current product examples. > - This pull request adds two maintenance skills and a catalog that consumes the existing feature map. > - The first audit preserves all stories and fixes proven fixture drift. > - Contributors can now find examples by feature and see what still needs review. ## Linked Issues or Issue Description **What existing behavior does this improve?** Storybook maintenance, feature discovery, and the accuracy of isolated UI examples. **Current behavior** Stories are already centralized under `ui/storybook/`, but their sidebar has 51 top-level groups. Production components, local prototypes, and historical designs are not consistently distinguished. The old guide uses manual coverage claims. GitHub searches found no duplicate feature-map catalog change. **Proposed behavior** Keep existing story locations and IDs. Add a downstream catalog keyed to stable feature capabilities. Record product status, rendered subject, data boundary, and declared review dependencies separately. Use dedicated maintenance and review skills to reconcile drift and report evidence. **Reason and benefit** The catalog makes existing examples reusable without treating mock behavior or old designs as production acceptance. The feature map remains independent of Storybook. ## What Changed - Add `maintain-storybook` and `review-storybook` skills with contributor guidance. - Inventory all 223 story files. Generate a feature index and provide searchable navigation in the existing Overview story. Track direct subjects through relative imports and local wrappers, including the primitives demonstrated by foundation suites. - Add a checker for inventory, capability references, duplicate IDs, and declared-source drift, with eight regression tests. The parser test covers real nested CSF files, export filters, explicit IDs, and play counts. - Preserve historical designs and classify mixed wrappers. Record the initial audit and remaining parity work. - Align the question-dismiss/send fixture with production behavior. Add dismissal and confirmation-reopen regressions and repair the editor selector. - Exclude three exported fast-response fixtures from story discovery and add the missing render-time callback spy. ## Verification - Passed: `node scripts/storybook-catalog.mjs`, `node --test scripts/storybook-catalog.test.mjs` (8 tests), and `node scripts/check-maps.mjs`. - Passed: validators for both new skills, `pnpm check:token-gates`, `pnpm -r typecheck`, and `pnpm build`. - Passed: final Storybook build; nine selected browser `play` cases; three fast-response render cases; feature-guide search/link navigation; question-fixture reset on reload. - Built-index comparison preserved all 2,208 original story IDs and added only two new regression cases. - Passed: `pnpm exec vitest run --project @paperclipai/ui` (728 files, 8,176 tests). - The full `pnpm test:run` has reported a 15-second timeout in the untouched backend case `connects advertised Workspace gmail.read without mutating definitions in authenticated`. The exact test passed standalone without changing code, expectations, or timeouts. The remaining broad run was stopped after this failure. The full suite is not verified. - Visual comparison is blocked by the existing empty baseline manifest. The managed-accounts API/DB fixture was not started. See `maps/storybook-map/REVIEW.md` for exact scope. ## Risks - This is an initial inventory and targeted audit. 188 suites still require deeper state and fixture parity review. - Review hashes cover declared dependencies. They do not follow all transitive production imports or prove semantic correctness. - The catalog requires upkeep when stories, mapped recipes, or declared subjects change. Shared mocks still need feature-by-feature contract review. - No production application source, database schema, or upstream feature-map contract changes. ## Model Used OpenAI GPT-6 via Codex. Used reasoning, shell tools, file editing, and Chromium browser verification. The exact runtime 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 - [ ] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
f5346c05b9 |
ci: route PR admission through reserved AWS capacity (#16042)
## Thinking Path
> - Paperclip uses CI to verify changes before release.
> - Trusted PR tests can run on isolated AWS workers.
> - Their runner-selection job currently waits for GitHub-hosted
capacity.
> - A large hosted test queue therefore blocks admission to AWS.
> - A dedicated routing workflow lets us reserve capacity for metadata
validation.
> - This PR moves the routing job to reserved AWS capacity after the
bootstrap workflow and pool are available.
## Linked Issues or Issue Description
**Issue type**
CI reliability enhancement.
**Where is the issue?**
The Select trusted runner job in PR CI.
**What's wrong?**
The routing job competes with a large hosted test queue. Its sampled
median wait was about 20 minutes. AWS tests cannot begin before this job
finishes.
**Suggested fix**
Add a protected reusable routing workflow. Deploy its dedicated AWS
pool, then switch the PR caller in a follow-up PR. No overlapping open
PR or issue was found.
## What Changed
- Call ci-routing.yml on protected master from pr-trusted.yml.
- Check the canonical repository and approved PR author/sender before
allocating reserved AWS metadata capacity. Unapproved PRs continue to
use hosted routing.
- Permit approved manual routing canaries on protected master.
- Use a validated roster snapshot for placement. Invalid JSON, missing
settings, stale snapshots, and unapproved identities select hosted
routing without a placement-time JSON parse.
- Preserve the full in-job identity, rerun actor, repository, head,
merge, and stack checks.
- Update stack-scope and placement regression tests and document the
pool and rollback.
## Verification
- The routing scripts and placement expression tests passed (44 tests),
routing-plus-shard tests passed (56 tests), and the existing
.github/scripts suite passed (381 tests).
- Existing routing allow/deny scenarios passed with the extracted script
(16 cases).
- actionlint passed with the dedicated custom runner label declared in
its local configuration.
- git diff --check passed.
- Full pnpm typecheck/test/build cannot run in this worktree because
dependencies are not installed. The change is limited to workflow YAML
and Node tests.
- The dedicated pool is deployed with two warm On-Demand workers and a
four-worker ceiling. The routing qualification passed: it started about
five seconds after workflow creation, selected AWS, and finished while
the hosted gate in the same PR remained queued.
- Bootstrap https://github.com/paperclipai/paperclip/pull/16039 is
merged. The deployed group now authorizes only ci-routing.yml on
protected master, and its master canary passed.
## Risks
- The maintainer explicitly approved a queued-CI admin bypass after
current-head Greptile 5/5 and focused verification.
- Activation requires the deployed routing Fleet and its group to
authorize the routing workflow on protected master. Keep the bootstrap
dependency explicit.
- The group must authorize only ci-routing.yml on protected master and
canonical repository ID 1170821064.
- The routing workflow runs no checkout or PR code and has read-only
permissions. The test admission checks are unchanged.
## Model Used
- OpenAI GPT-6 via Codex, with reasoning, shell tools, and file editing.
The exact runtime 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 (focused routing and
workflow tests; full pnpm commands are blocked by missing worktree
dependencies)
- [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] Required CI status checked; the maintainer explicitly approved
admin bypass for queued CI after clean current-head review and focused
verification
- [x] Greptile is 5/5 on
|
||
|
|
7d9b93aee2 |
docs: establish paired feature and agent access maps (#16025)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Contributors use the feature map to understand and verify product capabilities. > - Agents need APIs and usable entry points within their permission boundaries. > - Product recipes and agent access need separate records with shared capability IDs. > - This pull request establishes that contract and gives maintenance ownership of both maps. > - The benefit is repeatable access review without changing product behavior or permissions. ## Linked Issues or Issue Description Refs: #15983, which added the portable verification skills and updated the feature map. This is its contract-only follow-up. Related: #15288 added the original feature map. **Issue type** Missing documentation and maintenance contract. **Where is the issue?** The product map, its missing agent access companions, and the verification skills. **What's wrong?** There is no shared convention for API presence, agent entry points, permission boundaries, access gaps, or evidence. An API declaration does not prove that a permitted native or remote agent can use it. **Suggested fix** Keep the product and agent access maps as siblings under `maps/`. Reuse capability IDs. Record representative source inventory separately from operation review and live proof. Keep both maps aligned through the maintenance skill. ## What Changed - Move the existing product map to `maps/feature-map/`. Preserve its recipes and Poteto format. Update relative links and add companion links. - Add `maps/agent-access-map/` with 35 area files and 171 matching capability IDs. Seed representative API operations, agent paths, policies and known gaps from the reviewed source inventory. Mark entries as `baseline`, `source-only`, and live verification `not-run`. - Define the shared contract in `maps/README.md`. Track API presence, agent availability, policy, evidence and review depth separately. Require operation enumeration before marking a broad capability operation-reviewed. - Extend `maintain-verification-skill` to reconcile both maps and inspect actual route policy and production tool admission. Update creation, verification, notices and contributor references to use the shared contract. - Add `scripts/check-maps.mjs` and ten regression tests. Check matching areas/IDs, indexes, references, contract fields, API method/path examples, justified exceptions and evidence-state consistency. - Keep the coverage inventory unchanged. Preserve skill invocation policies and both MIT license blocks. No product API, permission, UI, runtime helper, migration, dependency or workflow changes. ## Verification - Passed: `node scripts/check-maps.mjs` reports 35 paired areas and 171 matching capability IDs. All local map references resolve. - Passed: `node --test scripts/check-maps.test.mjs` runs ten tests. Fixtures cover missing companions, renamed/orphan/duplicate IDs, broken references, missing operation fields, empty exceptions, missing API examples, empty policy fields, and verified evidence without passed verification. - Passed: metadata validation for all three verification skills. Skill and contributor links resolve. Invocation policies and both license blocks are unchanged. - Compared relocated recipes with current master. Contents differ only in relative links and companion links. `coverage.json` is byte-for-byte unchanged. Master's updated read-only interaction test reference is retained. - Passed: `git diff --check`. The branch starts from current master and contains only this contract change. - Repository-wide typecheck, tests and build were not run locally for this documentation and Node structural-check scope. Live agent access was not exercised. Those gaps are explicit in the baseline entries; the structural check does not certify behavior. CI and automated review are pending. ## Risks - The companions are representative source baselines. They are not complete operation inventories or passed agent journeys. - The checker cannot establish actual permissions, native tool admission, operation completeness or truthful live evidence. Maintenance must inspect source and verify with the actual permitted agent context. - External links to the old product-map directory may need updates. Repository references have been updated. - Existing access gaps and board/user restrictions remain recorded. This contract does not change authority or implement missing paths. ## Model Used OpenAI GPT-6 through Codex assisted with this change. The session does not expose the exact serving model ID, configured context-window size, or reasoning setting. Capabilities used: source analysis, file edits, shell commands, and structural regression tests. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
8227485372 |
perf(ci): cache the Runner's release crate artifacts keyed by their inputs (#15932)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - Its trusted PR workflow builds the Runner's Rust binary in five
jobs: Typecheck + Release Registry, Build, Canary Dry Run, and the
`rust` and `vitest 2/2` lanes of Verify Paperclip Runner. The `Build`
job is the slowest check in almost every green run (461s, 489s and 515s
in runs 38180574768, 38182717052 and 38183149920 on 2026-10-11).
> - Each of those jobs restores master's `release-runner-v2` dependency
cache. That cache holds only third-party crates. `rust-cache` removes
workspace crates when it saves, and a fresh checkout invalidates cargo's
mtime fingerprints for workspace crates in any case. So cargo compiles
`paperclip-runner-core` in release mode from scratch on every run. The
job logs show one `Compiling` line and 28s to 49s for it.
> - 18 of the 239 commits on `master` in the seven days before this
change touched the crate's inputs. The other 221 compiled the same
sources to the same binary again.
> - This pull request adds a second cache that holds only that crate's
release artifacts (about 70 MB). The key is made from the compiler, the
checkout root and a hash of every input the build reads. The master Rust
lane writes it. A pull request whose merge tree has byte-identical
inputs restores it and marks the artifacts newer than the checkout, so
cargo keeps them. Every other pull request misses and compiles as
before.
> - The benefit is about 28s to 49s less on `Build`, which is the run's
critical path, and the same on Typecheck, Canary Dry Run and two Runner
lanes, for about nine of ten pull requests.
## Linked Issues or Issue Description
No GitHub issue exists for this. The description below follows the
enhancement template.
**What existing behavior does this improve?**
The time the trusted PR workflow spends to compile the Runner's own
crate on every run.
**Subsystem affected**
CI / build
**Current behavior**
Every PR job that builds the Runner binary compiles
`paperclip-runner-core` in release mode from scratch. The compile takes
28s to 49s on the `runs-on` fleet (one `Compiling paperclip-runner-core`
line, then `Finished release profile` in runs 38169436532 to 38183149920
on 2026-10-11). The shared Rust cache cannot help: it holds only
third-party crates, and a fresh checkout gives every source a new mtime,
which makes cargo discard the crate's fingerprints.
**Proposed behavior**
The master Rust lane in `release-verify.yml` saves the crate's release
artifacts under a key made from the compiler, the checkout root and a
hash of every input the release build reads. The PR jobs that build the
binary restore that entry read-only. On a hit, a script sets the mtime
of every restored artifact to now, so cargo sees every source as older
than the build and keeps the artifacts. `pnpm build` then prints
`Finished release profile` in under a second for that crate. On a miss,
cargo compiles the crate exactly as before.
**Reason and benefit**
About 28s to 49s off `Build`, the slowest check in almost every green
run, and the same off the Typecheck, Canary Dry Run and two Verify
Paperclip Runner lanes. The saving applies to every pull request whose
merge tree does not change the crate's inputs, which was 221 of 239
`master` commits in the week before this change.
**Breaking changes**
None. The checks are unchanged. A miss or an eviction costs the compile
time it costs today and nothing else.
**Additional context**
This is a workflow change. `pr.yml` calls `pr-trusted.yml@master`, so
this pull request's own run uses the current reader steps, and the
writer runs only on a master push. The saving becomes visible on the
first PR runs after the merge and after the next master push has written
the entry.
## What Changed
- `scripts/runner-release-crate-cache.mjs` (new): the one place that
defines the cached path list (`CACHED_PATHS`), the hashed inputs
(`HASHED_INPUTS`) and the files a restore must contain (`REQUIRED`). The
`scope` subcommand prints the platform, the `rustc --version --verbose`
release, commit and host, and a hash of the checkout root. The
`mark-current` subcommand sets the mtime of every restored artifact to
now and prints a `paperclip.runner-release-crate.v1` JSON line with the
file count and bytes. If the restored set lacks any of the seven files
cargo's freshness check reads or checks for (the fingerprint hash and
dep-info of each unit, the lib's rlib and rmeta, the binary under
`deps`), it removes the restored files, prints `action: discarded`
naming the missing file, and exits 0, so cargo compiles as on a miss.
- `.github/workflows/pr-trusted.yml`: after the `release-runner-v2`
restore in `typecheck_release_registry`, `build` and `canary_dry_run`,
and in the `rust` and `vitest 2/2` lanes of `verify_paperclip_runner`
(new matrix key `release_crate: true`), three steps: compute the key
scope, `actions/cache/restore` the crate under
`runner-release-crate-v1-<scope>-<hashFiles(...)>` with no
`restore-keys`, and run `mark-current` when `cache-hit == 'true'`. The
`hashFiles` list covers the toolchain pin, the manifests and lockfile,
the crate sources, the protocol tree and the three fixture trees the
test modules include (two under the Runner package and
`tests/runner-e2e/fixtures` at the repository root).
- `.github/workflows/release-verify.yml`: in the Rust lane of an
own-repository master push, after the debug warm-up: compute the key
scope, look the key up (`lookup-only: true`), and on a miss run `cargo
clean --release -p paperclip-runner-core` and `pnpm build:binary` (the
exact command the readers run, so the entry carries no test-profile
variants), then `actions/cache/save` the same path list under the same
key.
- `scripts/__tests__/runner-release-crate-cache.test.mjs` (new, 10
tests, in `test:release-registry`): the path list and hashed inputs are
the expected ones and exist; every `include_str!` and `include_bytes!`
in the crate sources resolves under a hashed input, whether its argument
is a literal or a `concat!` of literals, `env!("CARGO_MANIFEST_DIR")`
and macro metavariables, and any other form fails the test by name (this
guard found the `test/fixtures` tree during development and the
`tests/runner-e2e/fixtures` tree in review); the parser itself is tested
on a synthetic crate for each supported form and six rejected ones;
every PR reader restores after the dependency cache and marks before its
build command with the script's exact path list and key and no
`restore-keys`; the Verify lanes are gated by `release_crate`; the
writer runs after the checks with the lookup, the clean and build, and
the save under the readers' exact path list and key; the scope changes
with the compiler and the checkout root and survives a missing `rustc`;
`mark-current` makes every artifact newer than the checkout, leaves a
dependency's artifacts alone, discards a restore missing any one of the
seven required files (one case each, checking the named reason), and
still marks a restore missing any one of the seven files cargo does not
need.
## Review fixes
Greptile's two findings on the first commit were both valid and are
fixed in the second commit:
- **Incomplete caches looked usable.** `REQUIRED` checked four files,
but cargo's freshness check needs seven. Measured with cargo 1.97.1 on
the real crate (restore, touch the artifacts, delete one file, build):
without the lib's fingerprint hash, dep-info, rlib or rmeta it
recompiles the crate (24s to 27s); without the bin's fingerprint hash,
dep-info or the binary under `deps` it relinks (1.5s); without either
`.json` fingerprint record, either rustc `.d` file, the uplifted binary
or its `.d` it reports the crate fresh in 0.15s and recreates the
uplifted binary from `deps`, and the staging step then copies it.
`REQUIRED` now lists exactly the seven files, the glob for the binary
under `deps` excludes the `.d` beside it, and the test removes each of
the seven in turn (discarded, naming it) and each of the other seven in
turn (still marked).
- **Composed include paths escaped the guard.** The regex matched only
`include_str!("literal")` and skipped `include_str!(concat!(...))`,
which the crate uses four times (30 of 34 includes were checked). The
guard now parses every include argument and resolves the `concat!`
forms; one of them, in `provider_events.rs`, reads
`tests/runner-e2e/fixtures/native-completion/terminal-tool-carrier.json`
at the repository root, outside every hashed input. It is test-only, so
today's release binary does not read it, but the key is meant to cover
every include whatever its build, so `tests/runner-e2e/fixtures/**` (9
files, 80 KB) joins `HASHED_INPUTS` and the six key embeddings in the
two workflows. With the first commit's input list, the new guard fails
on exactly that include.
- `doc/RELEASE-AUTOMATION-SETUP.md`: a "Runner release crate cache"
section under the Runner verification dependency cache, with the key,
the writer, the readers and the trust boundary.
- `package.json`: the new test file in `test:release-registry`.
## Verification
- `node --test scripts/__tests__/runner-release-crate-cache.test.mjs`:
10 tests pass, three consecutive runs.
- The second commit, with the real toolchain on the real crate (`rustc
1.97.1`, cold build 2m20s, the crate's artifacts 74 MB): every source
touched to a fresh-checkout mtime and the archived artifacts restored,
cargo compiles (`Compiling paperclip-runner-core`, 24.8s and 25.1s, the
two controls); restored and marked by `mark-current`, `Finished release
profile in 0.16s` with no `Compiling`, and the same on a second build.
Then, for each of the fourteen files cargo wrote for the two units, one
at a time: restored, marked and that file deleted, cargo recompiles
without any of the seven `REQUIRED` files and reports fresh without any
of the other seven; restored with that file deleted and run through
`mark-current`, the seven required ones print `action: discarded` naming
the file and the others print `marked`. A restore holding only the seven
required files builds fresh in 0.15s, cargo recreates the uplifted
binary, and `stage-runner-binary.mjs` copies it into `dist/bin`.
- `node --test '.github/scripts/tests/*.test.mjs'`: 378 of 381 pass. The
3 failures are in `docker-canary-promotion.test.mjs` and fail the same
way on an unmodified `master` checkout in this sandbox (the stand-in
docker writes no `calls.jsonl`).
- `node --test scripts/__tests__/release-verify-workflow.test.mjs
scripts/__tests__/e2e-shard.test.mjs
scripts/__tests__/run-vitest-stable-shard.test.mjs`: 99 of 101 pass; the
2 failures spawn `pnpm`, which is not on this sandbox's PATH, and fail
the same way on `master`.
- Both workflows parse as YAML. No job has a duplicate step name or step
id.
- The mechanism, with the real toolchain (`rustc 1.97.1`, the package's
pin) on a copy of the crate: a cold `cargo build --release -p
paperclip-runner-core --bin paperclip-runnerd` (2m23s here). Then the
artifact set was archived with `tar`, removed, every source re-copied so
each had a new mtime, and the set restored:
- restored, not marked: `Compiling paperclip-runner-core`, 24.6s (the
control; this is what CI does today);
- restored and marked by `mark-current`: `Finished release profile in
0.15s`, no `Compiling`; a second build is the same;
- one Rust source edited after a marked restore: `Compiling`, 24.0s;
- one protocol schema edited after a marked restore: `Compiling`, 23.9s
(the protocol files enter cargo's dep-info as absolute paths and are
hashed into the key);
- the rlib removed from a restored set: `mark-current` prints `action:
discarded, reason: incomplete: the lib rlib is missing` and removes the
rest, and cargo compiles.
- Not run here: the workflow steps themselves. `pr.yml` pins
`pr-trusted.yml@master`, so this pull request's own `Build` job runs the
current reader steps, and the writer runs only on a master push. The
first PR runs after the merge and after the next master push show the
`Restore the Runner release crate` step's result and the
`paperclip.runner-release-crate.v1` line in their `Build` logs.
## Risks
- Correctness: a reader can only restore artifacts that master built
from inputs byte-identical to its own merge tree, because every input
the build reads is in the key, and the key has no prefix match. A pull
request cannot write. The trust boundary is unchanged: master writes, a
pull request restores master's entry.
- An input the build reads that is outside the hashed patterns would let
a stale artifact pass. The release dep-info lists the crate sources and
the protocol schemas and fixtures; all are hashed. The guard test
resolves every `include_str!` and `include_bytes!` in the crate, literal
or `concat!`, and fails if one lands outside the hashed inputs or uses a
form it cannot resolve, so a new include form cannot slip past it by not
matching a regex.
- GitHub-hosted runners check out under `/home/runner/work`, the
`runs-on` fleets under `/home/runner/_work`. Cargo records the included
protocol files as absolute paths, so an entry from one root is useless
under the other. The checkout root is in the key, so the other root
misses instead of restoring something cargo then discards.
- A cache that does not keep mtimes on restore changes nothing: the
artifacts are then already newer than the checkout, and `mark-current`
sets them to now in any case.
- Cost: one new entry of about 70 MB per distinct input set, written
only by the master Rust lane on a miss, plus one `cargo clean` and
`build:binary` (about 40s to 50s) on that lane when the inputs changed.
The readers pay one restore of about 70 MB (two to three seconds at the
fleet's observed restore speed) and a sub-second `mark-current`.
- An incomplete entry (a writer that saved a partial set) is discarded
by `mark-current` and costs one compile, the same as a miss.
## Model Used
- Claude (Anthropic), model id `claude-fable-5-1` (Claude Fable 5.1),
extended thinking, with tool use (shell, file editing, GitHub CLI, a
local Rust toolchain for the experiment) in a Paperclip 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
- [ ] 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: devinfoley <139239+devinfoley@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
|
||
|
|
4f399cec9f |
fix(docker): skip the full-tree ownership walk on routine boots (#15992)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - The Docker image keeps all instance state under `PAPERCLIP_HOME`,
and deployments mount a volume there
> - Before it drops privileges, the entrypoint makes sure that the
`node` user owns the home (#10530)
> - The ownership probe is a first-mismatch `find` over the whole tree.
When ownership is correct, `-quit` never fires, so every boot stats
every file on the volume
> - On homes with many agent worktrees and `node_modules` trees, this
walk takes minutes before Node starts. That is close to common 300s
healthcheck windows
> - This pull request keeps a cheap shallow probe on every boot. It runs
the full-tree probe only once per volume and node UID/GID, and records
the result in a marker file
> - The benefit is that routine boots no longer scale with the file
count, and the original root-owned-volume fix stays in place
## Linked Issues or Issue Description
Refs #10431 (the open follow-up about the remaining cost of the
ownership walk). Related: #10530 (the change that added the full-tree
probe).
**What happened?**
On a hosted multi-instance deployment, we measured the time from
container start to the first app log line. Instances with many files on
the volume (agent worktrees with `node_modules`) took about 190-235s.
Small instances took 5-22s. One 30 GB volume with few files took 24s, so
the cost follows the file count, not the volume size. Almost all of this
time is the `find "$home_dir" \( ! -user node -o ! -group node \) -print
-quit` walk in `scripts/docker-entrypoint.sh`. When ownership is already
correct, `-quit` never fires, so the walk stats every inode on every
boot.
**Expected behavior**
When ownership is already correct, the entrypoint pre-start phase is
short and does not depend on the number of files in `PAPERCLIP_HOME`. A
fresh root-owned volume, a UID/GID remap, and an upgrade from an older
image are still repaired before the privilege drop.
**Steps to reproduce**
1. Run the image with a volume on `/paperclip` that holds a few hundred
thousand files, all owned by `node:node`.
2. Restart the container.
3. Compare the container start time with the first server log line. The
gap grows with the file count, even though no `chown` runs.
**Paperclip version or commit**
`master` at
|
||
|
|
db2f00947b |
fix(runner): include Claude ACP in the server package (#15912)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The server ships a copy of Paperclip Runner for native agent execution. > - The Claude ACP bridge is a runner dependency, but it was absent from the server package. > - The runner resolves this bridge dynamically, so the import-based packaging check missed it. > - A Claude session then failed before startup and showed a generic connection error. > - This pull request ships the qualified bridge and reports a missing runtime with repair steps. ## Linked Issues or Issue Description **What happened?** A server install with the vendored runner could not load `@agentclientprotocol/claude-agent-acp/package.json`. The runtime test suggested checking the model or provider connection. The task reported an interrupted runner session. **Expected behavior** The server package includes its qualified Claude ACP runtime. A missing bundled runtime reports an installation error and explains how to repair it. **Steps to reproduce** 1. Use a server install with the vendored runner and no Claude ACP bridge. 2. Select the Paperclip Runner ACP harness and the Claude provider. 3. Run the runtime test or open a session. 4. Observe a missing-module failure before Claude starts. **Paperclip version or commit** Reproduced on `e733bddc45`. This branch is based on current master. **Deployment mode** Self-hosted server built from source. Related: #15224 upgrades the Claude bridge. This PR fixes its omission from the server package and keeps the current qualified version. A future bridge upgrade must update the server pin too. ## What Changed - Add Claude ACP `0.73.0` to the server dependencies and bundled dependencies. - Pin the qualified Claude SDK and bridge dependencies in the npm bundle producer graph. Publish its native packages as consumer optional dependencies instead of shipping the producer executable. - Bind source-built vendored runners to the shared pnpm dependency store while retaining the server manifest as the provider authority. Keep published npm and self-rooted deployment roots unchanged. - Include dynamically resolved Claude and Codex bridges in the vendor dependency check. - Preserve the missing-package category through the sidecar, Rust transport, and native session executor. Stop automatic retries for this installation failure. - Show **Runtime missing** in the runtime test and task thread. Explain the reinstall or rebuild, server restart, and runtime test steps. - Add regression tests and document the repair procedure. ## Verification - Red/green comparison with the production sidecar: the same missing-package setup returns a raw require-stack error on the original code and an actionable, non-retryable missing-runtime error on this branch. - The rebuilt server's vendored Claude installation probe passes using the source-server authority selected by the launcher, without starting a provider or making a model request. - Focused server verification: 830 tests passed. Runner installation and sidecar error tests: 83 passed, with 6 platform-specific skips. Packaging tests: 28 passed. Rust transport tests: 7 passed. - Source/deployment authority tests: 3 passed. Red/green packaging tests include a Linux-produced Claude SDK bundle, actual npm pack, and closed executable admission on Linux x64 and macOS ARM64/x64. - Full UI suite: 8,113 tests passed. - `pnpm -r typecheck` and `pnpm build` passed on the rebased branch. - Full current-head CI passed, including all general and serialized test lanes, Runner Rust/Vitest verification, typecheck, build, and all eight e2e shards. Greptile reviewed `d6a2741834ff922956560f2f689382827bbaf9e0` at 5/5 with no unresolved threads. - Local full-suite limitation: an earlier parallel attempt hit Postgres startup failures and timeouts; the affected server tests and a database fixture passed in isolation. The subsequent serial `pnpm test:run` was stopped while still running after complete CI passed. Focused local tests, full UI tests, typecheck, and build completed as listed above. - Token gates and `git diff --check` passed. ## Risks - Bundling the Claude bridge increases the server package size. The producer graph retains the qualified SDK version and existing isolation patch. Native platform declarations move to the published server manifest, while the runtime keeps its exact version, declared-slot, no-follow, and executable digest checks. - The new failure category is permanent. Operators must repair the server installation before they retry the task. - Existing failed runs retain their recorded error. The clearer message applies to new runtime tests and runs. - No database schema or migration changes. ## Model Used OpenAI GPT-6 through Codex. The system reports the model family; the exact deployment ID and context-window size are not exposed in this session. Used reasoning, browser inspection, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
2223b7de9e |
perf(ci): stop building the standalone packages inside the public-install verifier (#15908)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Every pull request runs the `Build` check. Its last step is the public npm install verifier, `scripts/verify-grok-npm-install.mjs`, which stages the eighteen public packages reachable from the server and the CLI, packs them, and installs them in a clean consumer. > - Before it stages anything, the verifier runs `scripts/build-standalone-public-packages.mjs`. That script installs and compiles the seven sandbox-provider plugins that live outside the pnpm workspace: one network `pnpm install --ignore-workspace` and one `tsc` per plugin. The line was copied from the build block of `release.sh` when the verifier was written in #14024. > - release.sh needs that build because it publishes those plugins. The verifier does not for anything it stages. Its package closure follows `workspace:` specs from the server and the CLI, and a `workspace:` spec can only name a workspace package, so none of the eighteen packages it packs is a standalone package and no tarball reads that build's output. > - One optional path at the end of the verifier does read it: qualification-package retention, which `docker-runner-check.yml` enables with `PAPERCLIP_RUNNER_QUALIFICATION_PACKAGES_DIR` after running only `pnpm build`, packs the Daytona plugin from its `dist`. The PR `Build` job never sets that variable. > - The timing line from #15868 and #15888 puts the verifier's staging phase at 75.8s on the latest run, of which the staged sources, the bundled installs and the packs account for 46.5s. The rest, about 29s, is the work before staging, and the standalone build is almost all of it. `Build` at 433-530s is the slowest check in most PR runs once the server shards drop, so that time sits on the run's critical path. > - This pull request runs the standalone build only when retention is requested, keeps the `ui-dist` copy the server package needs, and times both on the timing line so what is left before staging is visible. > - The benefit is a `Build` job about 21-28s shorter, with no change to what the verifier installs or checks, no loss of coverage for the standalone build because Canary Dry Run still runs it through `release.sh`, and no change to the retention path that reads it. ## Linked Issues or Issue Description Replaces #15892, which GitHub closed automatically when the branch of #15888 (its base at the time) was deleted on merge. Same two commits, rebased onto `master` on top of #15888 ( |
||
|
|
1ac48aff8d |
perf(ci): pack the verifier's staged packages concurrently (#15888)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Every pull request runs the `Build` check. Its last step is the public npm install verifier, `scripts/verify-grok-npm-install.mjs`, which stages the eighteen public packages, packs them, and installs them in a clean consumer. > - The verifier packs the eighteen packages one after another with `npm pack`. Each pack is a Node start-up plus gzip of that package's files. The timing line added in #15868 shows this loop at 35.6-37.9s on four `Build` runs, the largest part of the staging phase now that the bundled installs overlap. > - `Build` at 433-530s is the slowest check in most PR runs once the server shards drop, so its staging phase sets the wall-clock time of the run. > - Each pack reads only its own `package-<index>` directory and writes one tarball. The runner has four cores and the packs are CPU-bound. There is no reason to run them one after the other. > - This pull request runs the packs as concurrent children through the prefetch helper, one per core, bundled packages first, each into its own directory, and puts the results back into dependency order before every tarball is checked. > - The benefit is a shorter `Build` job, and a timing line that reports the packs' serial cost next to their wall time, so the saving is measured on this PR's own run instead of estimated. ## Linked Issues or Issue Description Refs #15868, #15861. This branch is stacked on the branch of #15868, which is stacked on #15861, because the same execution branch holds both open PRs. The diff here is this PR's one commit. After #15868 merges, this PR is retargeted to `master` and rebased. **What existing behavior does this improve?** The `Build` PR check. Its public npm install verifier packs the eighteen public packages in one serial loop. **Subsystem affected** CI and release scripts (`scripts/verify-grok-npm-install.mjs`, `scripts/prefetch-child.mjs`). **Current behavior** After the bundled installs are joined, the verifier runs `npm pack --pack-destination <root>` for each of the eighteen packages in turn, finds the new tarball by listing the shared root, and checks it with `tar -tzf`. `stage_pack_ms` was 35.8s, 37.1s, 35.6s and 37.9s on the four runs of #15868. The parent is idle apart from the one pack it waits on, and three of the four cores are idle. **Proposed behavior** Start the packs as children through `startPrefetch`, at most one per core (`os.availableParallelism()`), bundled packages first because they make the largest tarballs. Each child packs into its own `pack-<index>` directory, so the tarball a package produced is read from there instead of guessed from a shared directory. Register each child for cleanup as it starts. Put the results back into dependency order, then check every tarball with `tar -tzf` as before, then copy them into the assets directory as before. Report `stage_pack_check_ms`, `pack_concurrency`, `pack_serial_ms` and `pack_longest_ms` on the timing line, and keep `stage_pack_ms` as the whole step. **Reason and benefit** With four slots the step takes about the longest single pack or a quarter of the serial sum, whichever is larger. The expected saving is 20-25s of the 36-38s, measured on this PR's own `Build` job by `pack_serial_ms` against `stage_pack_ms`. **Measured on this PR's first run ([38146108750](https://github.com/paperclipai/paperclip/actions/runs/38146108750), `Build` 433s, verifier 214s):** `stage_pack_ms` 29.9s against 35.6-37.9s before, so the step shed 6-8s, not the 20-25s estimated. `pack_serial_ms` is 44.4s with `pack_concurrency` 4, and `pack_longest_ms` is 28.3s: one pack (the server with its 513 MB bundled closure, gzip level 9 inside npm) runs for almost the whole step, so the step is bounded by that pack and not by the slot count. The seventeen other packs fit inside it. The serial sum is 7-9s higher than the old serial step, which is the four processes contending for the runner's cores. `stage_packages_ms` 75.8s against 80.4-89.6s on #15868's runs; `image_wait_ms` and `grok_wait_ms` stay 0. **Breaking changes** None. The same packages are packed with the same `npm pack` arguments, the tarballs are checked the same way, and the consumer receives them in the same order. ## What Changed - `scripts/pack-staged-packages.mjs` (new): `packStagedPackages` launches the packs in the order given with at most `concurrency` children at once, through the prefetch helper, and resolves with each entry's tarball path and wall time in the same order. Every child is passed to `register` as it starts. The first failure rejects with the tail of that child's log and nothing further is launched. A child that leaves anything other than one tarball in its directory is a failure. `packConcurrency` is one per core. `packTimings` gives the timing-line keys. - `scripts/verify-grok-npm-install.mjs`: each entry gets its `index` and its own `pack-<index>` destination. The pack loop is replaced by one `packStagedPackages` call, launched bundled-first and registered into the `prefetches` list as each child starts, so an earlier failure stops any pack still running before the scratch root is removed. The results are sorted back into dependency order, every tarball is checked in that order, and the copy into the assets directory is unchanged. Only the lifecycle sentinel is still packed in-process. - Timing line: `stage_pack_check_ms`, `pack_concurrency`, `pack_serial_ms` and `pack_longest_ms` are added. `stage_pack_ms` still covers the whole step, so the before and after numbers compare directly. - `scripts/__tests__/pack-staged-packages.test.mjs` (new): five tests with a local stand-in for npm and no network. The default concurrency and the pack arguments; four packs with two slots run the two slow packs together, start a third only once a slot is free, receive the exact `npm pack` argument list, register every child, and come back in entry order with their tarballs and timing keys although the fast packs finish first; a failed pack rejects with its log tail, launches nothing more, and leaves the running pack to be stopped; a pack that produces two tarballs or none is a failure; and no entries resolve at once. - `scripts/__tests__/grok-public-install-sandbox.test.mjs`: the guard test on the verifier source now checks the import, the bundled-first launch with cleanup registration, the reorder before the checks, the checks before the copy, that only the sentinel is packed in-process, that each pack has its own directory, and the new timing keys. - `package.json`: the new test file is in `test:release-registry`. ## Verification - `node --test scripts/__tests__/pack-staged-packages.test.mjs scripts/__tests__/grok-public-install-sandbox.test.mjs scripts/__tests__/stage-bundled-packages.test.mjs scripts/__tests__/prefetch-child.test.mjs`: 35 tests pass (30 on #15868's head plus the five new ones). The new file passes three consecutive runs. - `node --check` passes on both scripts. - With the real npm 11.12.1 on Node 25.9: two small packages packed through `packStagedPackages` with two slots produce one tarball each in their own `pack-<index>` directory, with the expected `package/` listing from `tar -tzf`. - The verifier itself needs Docker and a network, which this workspace does not have. This PR's own `Build` job runs the branch's verifier; its timing line carries `stage_pack_ms`, `pack_serial_ms`, `pack_longest_ms` and `pack_concurrency`, which is the measurement. Before, on #15868's four runs: `stage_pack_ms` 35.8s / 37.1s / 35.6s / 37.9s. - `docker-runner-check.yml` runs the same script after `pnpm build` and needs no change. ## Risks - Four `npm pack` processes run at once and share the host npm configuration and cache. `npm pack --ignore-scripts` reads the package directory and writes one tarball; it does not write to the cache beyond its per-process log file. If a shared-state race appears, the failing pack's log tail is in the error and the fix is to lower the concurrency. - Memory and CPU: four Node processes instead of one on the four-core `Build` runner, for about thirty seconds. The largest pack (the server with its bundled dependencies) is the same process as before. - The pack output moves from the CI log into per-pack log files in the scratch root. A failure reports the last 2000 characters of the failing pack's log; a successful pack's output is discarded with the scratch root. - The tarball checks (`tar -tzf`) now run after all packs instead of after each pack. A bundled Codex payload is still rejected before any tarball reaches the consumer; the only change is that the error arrives a few seconds later. - Low risk otherwise. The bundled installs, the consumer install, and every probe are unchanged. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used - Claude Fable 5.1 (Anthropic), model ID `claude-fable-5-1`, run as a Paperclip agent through the Claude Code local adapter with tool use (shell, file edits, GitHub CLI). Reasoning mode: 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 - [x] All Paperclip CI gates are green (run 38146108750: `server (11/12)` failed on its first attempt on a teardown `EACCES` while removing the per-worker `PAPERCLIP_HOME` after all 74 files and 1257 tests had passed, in a file this PR does not touch; the re-run of that job passed and every check is 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: devinfoley <139239+devinfoley@users.noreply.github.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> |