mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-24 10:13:11 +02:00
fd7cb77d8e952a28e448d0be6159eb2febec734f
1208
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
fd7cb77d8e |
feat(runner): isolate Codex runtime context (#12376)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The runner package now has a Codex-only native backend > - A native Codex process needs an isolated runtime context before it can start safely > - Assigned skills, local authentication, and MCP bindings cross separate trust boundaries > - Runtime materialization must reject symlink escapes and unsafe remote bindings > - This pull request adds the package-local Codex runtime context boundary > - It does not start runnerd or enable the Paperclip Runner adapter ## Linked Issues or Issue Description **Subsystem affected** `packages/paperclip-runner` Codex runtime context materialization. **Problem or motivation** The runner needs a private Codex home for each native session. It must stage only assigned skills, copy local Codex authentication safely, and validate native MCP bindings before it exposes them to the child process. **Proposed solution** Create an isolated runtime directory. Validate the skill tree before and after copying it. Make staged skill files read-only. Read authentication through a no-follow file descriptor with a size bound. Accept only HTTPS or loopback MCP endpoints and bounded tokens. **Alternatives considered** Using the operator Codex home directly would expose unrelated state and skills. Following symlinks while copying skills or authentication could escape the assigned source. Accepting arbitrary MCP URLs could send a bearer token to an untrusted endpoint. **Roadmap alignment** This adds a package-local safety boundary for the reviewed Codex runner path. It does not enable a new adapter or change an existing direct adapter path. ## What Changed - Added the native MCP binding contract and strict validation. - Added isolated Codex home materialization with shell snapshots disabled. - Added assigned-skill staging with lexical containment and two-pass symlink checks. - Added read-only permissions for staged skill trees. - Added owner-only authentication staging with no-follow reads and a size bound. - Added cleanup for complete and partially materialized runtime directories. ## Verification - The focused runtime context suite has 7 passing cases. - `pnpm --filter @paperclipai/paperclip-runner test:typescript` (36 files, 351 tests) - `pnpm -r typecheck` - `pnpm build` ## Risks The main risks are filesystem escape, secret exposure, and token delivery to an unsafe endpoint. The materializer rejects symlinks before and after skill copying, resolves existing source paths, reads authentication with `O_NOFOLLOW`, applies private permissions, and restricts MCP URLs to HTTPS or loopback hosts. Existing direct adapters do not use this package-local runtime context. ## Model Used OpenAI Codex with GPT-5 and repository tool use. ## 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 |
||
|
|
6d358e646d |
feat(runner): add Codex native backend (#12374)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The runner package now has a complete Codex session driver > - The driver needs a package-owned construction boundary before server code can use it > - Persisted provider contracts must not make deferred providers executable > - Provider selection must fail closed when an implementation is not included > - This pull request adds a Codex-only native backend and factory > - It does not expose or enable the Paperclip Runner adapter ## Linked Issues or Issue Description **Subsystem affected** `packages/paperclip-runner` native backend construction. **Problem or motivation** The runner needs one normalized backend seam that constructs the reviewed Codex driver. The seam must not route OpenCode, ACPX, Claude Managed, or AWS AgentCore through an incomplete fallback. **Proposed solution** Add a Codex backend constructor and a Codex-first factory. Reject every deferred provider at the factory and provider-specific constructor boundaries. **Alternatives considered** Routing all provider contracts through the Codex protocol facade would give deferred providers runtime behavior before their implementations are reviewed. Including all provider backends would also broaden this pull request beyond the Codex-first series. **Roadmap alignment** This connects reviewed runner package layers. It does not enable a new adapter or change an existing direct adapter path. ## What Changed - Added the Codex native backend constructor. - Added the Codex-first native backend factory. - Preserved the execution contract, runtime instructions, plan constraints, dynamic tools, transport injection, and durable identity requirements. - Rejected every deferred provider with an explicit error. - Added tests for lazy transport construction and both fail-closed boundaries. ## Verification - `pnpm --filter @paperclipai/paperclip-runner test:typescript` (35 files, 340 tests) - `pnpm -r typecheck` - `pnpm build` - The focused native backend factory suite has 3 passing cases. ## Risks The main risk is starting the wrong provider or starting a provider before its runtime is ready. The factory and Codex constructor both reject non-Codex inputs. Existing direct adapters do not call this package-local factory. ## Model Used OpenAI Codex with GPT-5 and repository tool use. ## 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 |
||
|
|
06f8773097 |
feat(runner): add Codex session driver (#12371)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The package now has bounded Codex transport, security, question, diff, value, and thread helpers > - Those isolated boundaries can now be composed into one provider session lifecycle > - The driver must preserve controller-owned identity, results, terminals, and recovery invariants > - Unsupported or mismatched provider traffic must fail closed without weakening legacy adapters > - This pull request adds only the Codex app-server driver and its package-local tests > - It does not expose or enable the Paperclip Runner adapter ## Linked Issues or Issue Description **Subsystem affected** `packages/paperclip-runner` Codex app-server session driver. **Problem or motivation** The runner needs a production-shaped Codex session implementation that turns provider facts into canonical PRP events while keeping task identity, semantic completion, runtime input, and recovery under controller authority. **Proposed solution** Compose the previously reviewed transport and normalization boundaries into a Codex-only harness driver with session open/resume, turns, streaming events, semantic tools, structured questions, goals, lineage, usage, cancellation, reconciliation, and deterministic persisted snapshots. **Alternatives considered** Keeping the full implementation in one initial transport pull request would obscure the trust boundaries. Adding the deferred ACPX or OpenCode paths here would also broaden the provider scope beyond the Codex-first series. **Roadmap alignment** This implements the Codex provider slice inside the package. It does not enable the runner adapter or change any existing direct adapter path. ## What Changed - Added the Codex app-server harness driver and session lifecycle. - Added controller-bound semantic completion and terminal handling. - Added runtime requests, structured questions, goals, lineage, usage, steering, interruption, and recovery. - Added workspace diff and file-reference projection. - Connected bounded/redacted provider data and notification identity checks. - Kept deferred provider identities and replacement behavior out of the Codex-only driver. - Added 62 focused driver cases covering lifecycle, security, recovery, and protocol failures. ## Verification - `pnpm --filter @paperclipai/paperclip-runner test:typescript` (34 files, 337 tests) - `pnpm -r typecheck` - `pnpm build` - The focused Codex driver suite has 62 passing cases. ## Risks The main risks are accepting provider events from the wrong session, duplicating terminal facts, retaining unsafe provider data, or resuming a different session. Tests cover pre-turn, cross-thread, stale-turn, post-terminal, duplicate-result, cancellation, transport loss, provider identity, workspace, redaction, structured input, and recovery cases. ## Model Used OpenAI Codex with GPT-5.6 and repository tool use. ## 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 |
||
|
|
a9297c3c07 |
test(runner): add Codex trace conformance (#12370)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The Codex driver needs a controller-owned oracle for semantic completion and replay > - Provider proposals are advisory and must satisfy the exact task envelope > - Persisted events must be bounded and validated before deterministic replay > - Live provider behaviors also need one checked-in, schema-validated fixture > - This pull request adds that test and conformance layer before the full driver > - The runner adapter remains disabled and no production execution path changes ## Linked Issues or Issue Description **Subsystem affected** `packages/paperclip-runner` Codex trace, result-validation, and replay conformance. **Problem or motivation** A provider-completed turn is not sufficient authority to finalize a Paperclip run. Results must match the controller-owned completion contract, and persisted provider events must be validated before they can rebuild controller state. **Proposed solution** Add a bounded Codex trace harness that validates result proposals, emits controller decisions and terminals, verifies live/replay parity, and rejects malformed persisted streams. Add a validated fixture for runtime requests, goals, lineage, controls, reconnect identity, and redaction cases. **Alternatives considered** Embedding these assertions only in the production driver would mix controller authority with provider transport behavior and make deterministic replay harder to review. **Roadmap alignment** This supports the Codex-first experimental runner. It does not enable the runner adapter or add another provider. ## What Changed - Added exact task-envelope result validation. - Added bounded persisted-event validation and deterministic replay. - Added a controller-owned Codex trace harness and parity assertions. - Added and validated the checked-in Live console conformance fixture. - Updated the generated protocol manifest with the fixture source. - Added focused result and fixture tests. ## Verification - `pnpm --filter @paperclipai/paperclip-runner test:typescript` - `pnpm -r typecheck` - `pnpm build` - The focused trace-conformance test has 2 passing cases. ## Risks The main risks are accepting a mismatched semantic result or replaying corrupted provider history. Validation covers schema, contract revision, criteria identity, disposition invariants, event identity, uniqueness, ordering, terminal count, and byte limits. ## Model Used OpenAI Codex with GPT-5.6 and repository tool use. ## 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 |
||
|
|
6f6415d07e |
feat(runner): verify workspace file references (#12368)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Runner replies can refer to files produced inside an assigned workspace > - The task page needs stable file metadata without trusting arbitrary Markdown paths > - File verification must stay within the canonical workspace even through symlinks > - Reads and previews also need strict count and byte bounds > - This pull request adds that provider-neutral file-reference boundary > - A later pull request will connect it to the Codex session driver ## Linked Issues or Issue Description **Subsystem affected** `packages/paperclip-runner` workspace file-reference discovery. **Problem or motivation** Assistant-authored Markdown can contain external, absolute, escaping, or symlinked paths. Reading those paths directly could disclose files outside the assigned workspace or retain unbounded content. **Proposed solution** Parse a bounded set of local Markdown references, normalize them relative to the workspace, verify canonical paths before reading, reject symlink escapes, and retain bounded previews plus content digests. **Alternatives considered** Leaving path handling inside a provider driver would duplicate a security-sensitive boundary and make it harder to test independently. **Roadmap alignment** This supports the Codex-first experimental runner and future provider-neutral task projection. It does not enable the runner adapter. ## What Changed - Added stable workspace file-reference records. - Added local Markdown link extraction and path normalization. - Added canonical-path and symlink-escape checks. - Added bounded file reads, previews, and SHA-256 digests. - Added focused path, preview, and symlink tests. ## Verification - `pnpm --filter @paperclipai/paperclip-runner test:typescript` - `pnpm -r typecheck` - `pnpm build` - The focused workspace-reference test has 3 passing cases. ## Risks The main risk is reading outside the assigned workspace or retaining excessive data. Tests cover absolute and external paths, symlink escapes, preview bounds, and deterministic metadata. ## Model Used OpenAI Codex with GPT-5.6 and repository tool use. ## 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 |
||
|
|
ac7f6ec1a3 |
feat(runner): normalize Codex thread state (#12367)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Codex thread state arrives as provider-specific goals, lineage, notifications, and workspace paths > - That data must be normalized before the full driver can retain or project it > - Notifications also need run and thread binding so unrelated provider traffic is ignored > - This pull request adds pure normalization helpers before the full driver > - A later pull request will use these helpers for the Codex session lifecycle > - The benefit is a small, independently tested trust boundary for thread state ## Linked Issues or Issue Description **Subsystem affected** `packages/paperclip-runner` Codex thread-state normalization. **Problem or motivation** Provider thread data can contain unsupported goal shapes, unrelated notifications, unsafe workspace paths, or unbounded response values. Passing it through directly would weaken run isolation and durable-data bounds. **Proposed solution** Normalize goals and lineage into stable runner shapes, accept notifications only when their run and thread identities match, constrain workspace references to the assigned root, and retain only bounded safe provider responses. **Alternatives considered** Keeping these rules embedded in the full driver would make the trust boundary harder to review and test independently. **Roadmap alignment** This supports the Codex-first experimental runner. It does not enable the runner adapter. ## What Changed - Added normalized Codex thread goals and lineage. - Added run- and thread-bound notification filtering. - Added safe workspace-relative path and stat projection. - Added bounded provider-response retention. - Added focused normalization and isolation tests. ## Verification - `pnpm --filter @paperclipai/paperclip-runner test:typescript` - `pnpm -r typecheck` - `pnpm build` - The focused thread-normalization test has 3 passing cases. ## Risks The main risk is retaining data from the wrong provider thread or accepting an unsafe workspace reference. Tests cover identity binding, path normalization, response bounds, goal parsing, and lineage projection. ## Model Used OpenAI Codex with GPT-5.6 and repository tool use. ## 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 |
||
|
|
905177c93b |
feat(runner): bound Codex workspace values (#12366)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Provider data crosses workspace, event, trace, and tool-result boundaries > - Codex payloads can contain large or protected values > - The runner also needs to reject unsafe working directories > - This pull request adds pure boundary helpers before the full driver > - A later pull request will use these helpers for Codex event handling > - The benefit is bounded and redacted provider data with focused tests ## Linked Issues or Issue Description **Subsystem affected** `packages/paperclip-runner` Codex value and workspace boundaries. **Problem or motivation** Raw provider payloads can exceed durable limits or contain credentials. An invalid working directory can expose host state or escape the assigned workspace. **Proposed solution** Validate the workspace against host and assignment roots. Bound retained values by depth, count, string length, and byte size. Redact protected keys and diagnostic credentials. **Alternatives considered** Keeping these checks inside the driver would make them harder to review and reuse at every provider-data boundary. **Roadmap alignment** This supports the Codex-first experimental runner. It does not enable the runner adapter. ## What Changed - Added assigned-workspace validation. - Added host home and Codex home overlap checks. - Added retained payload bounds. - Added recursive protected-value redaction. - Added semantic completion tool disposition checks. - Added focused security and bounds tests. ## Verification - `pnpm --filter @paperclipai/paperclip-runner test:typescript` - `pnpm -r typecheck` - `pnpm build` - The focused boundary test has 3 passing cases. ## Risks The main risk is accepting an unsafe workspace or retaining sensitive provider data. Tests cover root escape, host overlap, size limits, credential redaction, and completion-tool separation. ## Model Used OpenAI Codex with GPT-5.6 and repository tool use. ## 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 |
||
|
|
f44f5b1ab1 |
feat(runner): normalize Codex structured questions (#12365)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Existing adapters already use provider-neutral structured questions > - Codex emits several provider-specific input and elicitation forms > - Malformed native forms must fail closed instead of degrading to an opaque prompt > - This pull request adds the Codex question adapter without adding the full driver > - A later pull request will connect it to provider request handling > - The benefit is a small compatibility boundary that preserves legacy question behavior ## Linked Issues or Issue Description **Subsystem affected** `packages/paperclip-runner` Codex structured input handling. **Problem or motivation** Codex user-input and MCP elicitation requests use different shapes. The runner needs one canonical question set and must map validated answers back to the correct provider response. **Proposed solution** Normalize native forms into `paperclip.question_set.v1`. Preserve optional answers, select modes, validation bounds, and stable IDs. Map canonical responses back only after validation. **Alternatives considered** Passing provider-native forms through PRP would couple the app to Codex and would not preserve the existing provider-neutral question boundary. **Roadmap alignment** This supports the Codex-first experimental runner and existing structured-question compatibility. It does not enable the runner adapter. ## What Changed - Added request-kind detection for approval, input, and elicitation requests. - Added requestUserInput normalization. - Added JSON Schema elicitation normalization. - Added canonical runtime request payloads. - Added response mapping for Codex answers and MCP elicitation content. - Added malformed-form and multi-question tests. ## Verification - `pnpm --filter @paperclipai/paperclip-runner test:typescript` - `pnpm -r typecheck` - `pnpm build` - The focused question adapter test has 3 passing cases. ## Risks The main risk is changing question semantics. Tests verify optional answers, single and multi select modes, text validation, duplicate IDs, numeric elicitation, and canonical response mapping. ## Model Used OpenAI Codex with GPT-5.6 and repository tool use. ## 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 |
||
|
|
9d7d9ea724 |
feat(runner): isolate Codex security configuration (#12364)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Codex executes commands inside the runner workspace > - The provider process must not inherit host credentials or broad file access > - Planning mode also needs a read-only workspace boundary > - This pull request defines the isolated launch and thread configuration > - A later pull request will use it from the Codex driver > - The benefit is an independently reviewed security boundary ## Linked Issues or Issue Description **Subsystem affected** `packages/paperclip-runner` Codex launch security. **Problem or motivation** A provider process can inherit host paths, environment secrets, network access, or write permissions unless the runner constructs a closed configuration. **Proposed solution** Build explicit app-server arguments and thread parameters. Deny host roots and network access, allow only a small environment list, and use a read-only profile for plan mode. **Alternatives considered** Relying on ambient Codex defaults would make runner safety depend on each host installation. **Roadmap alignment** This supports the Codex-first experimental runner. It does not enable the runner adapter. ## What Changed - Added deny-by-default filesystem rules. - Added separate execution and planning permission profiles. - Added network denial. - Added an explicit environment allowlist. - Disabled host apps, plugins, memories, multi-agent behavior, and image generation. - Added security configuration tests. ## Verification - `pnpm --filter @paperclipai/paperclip-runner test:typescript` - `pnpm -r typecheck` - `pnpm build` - The focused security configuration test has 3 passing cases. ## Risks The risk is an overly broad provider launch. Tests verify denied host roots, read-only context roots, workspace permissions, network denial, and secret exclusion. ## Model Used OpenAI Codex with GPT-5.6 and repository tool use. ## 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 |
||
|
|
3942739906 |
feat(runner): parse bounded Codex turn diffs (#12363)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Runner events need provider-neutral workspace change facts > - Codex reports one complete unified diff snapshot per turn > - Provider diff text can be large and can contain unsafe paths > - This pull request adds only the bounded pure parser > - A later pull request will connect it to the Codex driver > - The benefit is an independently tested workspace boundary ## Linked Issues or Issue Description **Subsystem affected** `packages/paperclip-runner` Codex event normalization. **Problem or motivation** Codex turn diffs need stable file operations and statistics. Raw diff input must not escape the workspace or grow without bounds. **Proposed solution** Parse complete unified diff snapshots into normalized file records. Bound file count and retained text, reject unsafe paths, and represent binary changes without text. **Alternatives considered** Parsing diffs inside the main driver would make provider lifecycle review larger and harder to test in isolation. **Roadmap alignment** This supports the Codex-first experimental runner. It does not enable an adapter. ## What Changed - Added create, modify, delete, rename, mode-change, and binary parsing. - Added workspace-relative path validation. - Added file-count and per-file text bounds. - Added focused rename, binary, hostile path, and size tests. ## Verification - `pnpm --filter @paperclipai/paperclip-runner test:typescript` - `pnpm -r typecheck` - `pnpm build` - The focused parser test has 2 passing cases. ## Risks Low risk. This is a pure parser with no file-system access and no production caller yet. ## Model Used OpenAI Codex with GPT-5.6 and repository tool use. ## 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 |
||
|
|
83243d4b5d |
feat(runner): add bounded Codex app-server transport (#12362)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The first production runner provider is Codex > - Codex app-server communicates with JSON-RPC over a child process > - The process boundary needs explicit resource, environment, and diagnostic limits > - This pull request adds only the bounded transport layer > - A later pull request will add the Codex event-mapping driver > - The benefit is a small reviewable process boundary before provider behavior is added ## Linked Issues or Issue Description **Subsystem affected** `packages/paperclip-runner` Codex transport. **Problem or motivation** The runner needs a safe way to start and communicate with Codex app-server. Unbounded lines, queued notifications, pending requests, and inherited credentials would make that boundary unsafe. **Proposed solution** Add a JSON-RPC process transport with explicit byte and count limits, sanitized environment construction, process-group metadata, server-request handling, redacted diagnostics, and deterministic closure. **Alternatives considered** Adding transport and the full Codex driver in one change would create a much larger review surface. This pull request isolates the child-process boundary. **Roadmap alignment** This supports the Codex-first experimental runner. It does not enable the runner adapter. ## What Changed - Added bounded JSON-RPC request and notification queues. - Added malformed-message and oversized-line fail-closed behavior. - Added sanitized Codex environment construction. - Added process-group tracking and deterministic shutdown. - Added redacted diagnostics and server-request replies. ## Verification - `pnpm --filter @paperclipai/paperclip-runner test:typescript` - `pnpm -r typecheck` - `pnpm build` - The focused transport test has 6 passing cases. ## Risks The main risk is child-process cleanup. Tests cover closure, pending request rejection, queue bounds, process metadata, and malformed input. ## Model Used OpenAI Codex with GPT-5.6 and repository tool use. ## 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 |
||
|
|
ea86e780af |
feat(runner): add authorized scenario tool runtime (#12361)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The runner action catalog defines what scenario tools can exist > - A catalog entry must not grant authority by itself > - Scenario runs need run-scoped discovery and invocation checks > - Observable results must not expose protected values > - This pull request adds an authorized package-local scenario tool runtime > - The benefit is deterministic tool testing without production service authority ## Linked Issues or Issue Description **Subsystem affected** `packages/paperclip-runner` scenario tool runtime. **Problem or motivation** Scenario tests need to expose only authorized actions. They also need stable denial records, redaction, and idempotent command handling. **Proposed solution** Project the canonical scenario contracts into a visible catalog. Recheck policy at invocation. Dispatch allowed operations through the mock control-plane port and return redacted receipts. **Alternatives considered** Direct production bindings are outside this pull request. The runtime uses only the package-local mock port. **Roadmap alignment** This supports runner conformance and scenario testing. It does not enable an adapter or production service call. ## What Changed - Added run-scoped scenario tool discovery. - Added claim, role, task-mode, and policy authorization. - Added input validation, redaction, and authorization records. - Added fake-agent and Codex definition projections. - Added deterministic mock dispatch and idempotency coverage. ## Verification - `pnpm --filter @paperclipai/paperclip-runner test:typescript` - `pnpm -r typecheck` - `pnpm build` - The focused semantic runtime test has 10 passing cases. ## Risks Low risk. The runtime is package-local and uses the mock control-plane port. It creates no production binding. ## Model Used OpenAI Codex with GPT-5.6 and repository tool use. ## 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 |
||
|
|
e11b457fd9 |
feat(runner): complete the canonical action catalog (#12360)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The Paperclip Runner needs a stable list of semantic actions > - Earlier pull requests define the core and collaboration action groups > - The remaining domain and administration actions need the same contract form > - The complete catalog must remain data only until a later pull request binds actions to services > - This pull request completes and validates the canonical action inventory > - The benefit is one frozen source of truth for later discovery and authorization work ## Linked Issues or Issue Description **Subsystem affected** `packages/paperclip-runner` protocol contracts. **Problem or motivation** The runner does not yet have a complete canonical inventory for domain and administration actions. Later authorization code cannot project a stable operation catalog without this inventory. **Proposed solution** Add the remaining action contracts and aggregate all 41 actions. Validate every declared live and scenario projection with its own schema. **Alternatives considered** Binding these actions directly to production services would combine data contracts with authority. This pull request keeps every production service binding unbound. **Roadmap alignment** This change supports the experimental Paperclip Runner. It does not enable the runner or change an existing adapter. ## What Changed - Added 14 domain and administration action contracts. - Added the complete immutable 41-action catalog. - Added validation for live inputs and outputs. - Added validation for scenario inputs and capability-result envelopes. - Kept every production service binding unbound. ## Verification - `pnpm --filter @paperclipai/paperclip-runner test:typescript` - `pnpm -r typecheck` - `pnpm build` - The focused catalog test validates 41 actions. ## Risks Low risk. This pull request adds package-local contract data and tests. It does not authorize an action or change an adapter. ## Model Used OpenAI Codex with GPT-5.6 and repository tool use. ## 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 |
||
|
|
4eb32d7532 |
Add collaboration action contracts (#12359)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Agents collaborate through discovery, delegation, dependencies, and governed approvals > - These optional operations need stable contracts before any run may discover them > - The core action contracts are already isolated in the lower stack > - This pull request adds the 13 collaboration and governance action definitions > - It does not grant claims or bind production services > - The benefit is a reviewable contract layer for later run-scoped authorization ## Linked Issues or Issue Description **Subsystem affected** packages/paperclip-runner protocol action contracts **Problem or motivation** Optional collaboration operations need one provider-neutral definition for policy metadata, documentation, live and scenario schemas, and canonical examples. **Proposed solution** Add one immutable module for each discovery, delegation, dependency, and governance action. Add a collaboration aggregate and validate all examples with JSON Schema. **Alternatives considered** These contracts could land with executable authorization. That would make contract review depend on runtime policy and server service bindings. **Roadmap alignment** This supports the existing experimental Paperclip Runner rollout. It does not make any optional operation discoverable or invocable. ## What Changed - Add 13 collaboration and governance action definitions. - Add immutable policy, schema, documentation, and example data. - Add a collaboration-only aggregate. - Validate every action example against its declared schema. ## Verification - `pnpm --filter @paperclipai/paperclip-runner test:typescript` - `pnpm --filter @paperclipai/paperclip-runner typecheck:typescript` - `pnpm -r typecheck` - `pnpm build` - The branch changes 15 files relative to its declared base. ## Risks Low production risk. The declarations do not grant claims or contain executable service bindings. Tests require optional placement, immutable metadata, stable identities, and schema-valid examples. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI Codex, `gpt-5`, with agentic reasoning, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either linked an existing public issue or described the issue in-PR - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal Paperclip ticket id - [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 |
||
|
|
08b5d6bd9b |
Add core runner action contracts (#12358)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Runner tools need stable provider-neutral action contracts > - Core task work must use the same names, policy metadata, schemas, and examples on every provider surface > - A single large 41-action review would hide contract drift > - This pull request adds only the 14 always-present core action definitions > - It does not grant discovery or execution authority > - The benefit is a reviewable immutable contract base for later authorization wiring ## Linked Issues or Issue Description **Subsystem affected** packages/paperclip-runner protocol action contracts **Problem or motivation** The runner has an older compact catalog, but it does not single-source the full policy metadata, documentation, live shape, scenario shape, and examples for each core action. **Proposed solution** Add one immutable definition module per core action. Add an internal core aggregate and validate every input and output example against its declared JSON Schema. Keep all production authorization and execution unavailable. **Alternatives considered** All 41 action definitions could land in one pull request. That would create more than 7,000 changed lines and reduce useful review depth. **Roadmap alignment** This supports the existing experimental Paperclip Runner rollout. It does not enable the adapter or expose any new production tool. ## What Changed - Add 14 core protocol action definitions. - Add immutable policy, schema, documentation, and example data for each action. - Add a deep-freeze helper and a core-only aggregate. - Validate all core examples with JSON Schema. ## Verification - `pnpm --filter @paperclipai/paperclip-runner test:typescript` - `pnpm --filter @paperclipai/paperclip-runner typecheck:typescript` - `pnpm -r typecheck` - `pnpm build` - The branch changes 17 files relative to its declared base. ## Risks Low production risk. These declarations do not contain executable authorization or service bindings. The main risk is schema drift. Tests validate operation identity, placement, immutability, and canonical examples. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI Codex, `gpt-5`, with agentic reasoning, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either linked an existing public issue or described the issue in-PR - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal Paperclip ticket id - [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 |
||
|
|
300b7f4b7e |
Add deterministic capability control plane (#12355)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Semantic operations need a control plane that owns authorization and state changes > - Conformance tests need this authority without a live server or database > - The existing in-memory port covers transport facts but not capability-governed domains > - This pull request adds a deterministic capability-aware control plane for tests > - It keeps the implementation behind the package testing entry point > - The benefit is repeatable authorization and mutation tests before production wiring lands ## Linked Issues or Issue Description **Subsystem affected** packages/paperclip-runner testing and semantic capability contracts **Problem or motivation** Later semantic action slices need deterministic company, actor, task, governance, workspace, secret, budget, routine, and audit state. A live Paperclip server would make those tests slow and environment-dependent. **Proposed solution** Add serializable capability fixture types and an in-memory control-plane adapter. Enforce company scope, claims, roles, idempotency, redaction, faults, and audit records. Export the adapter only from the testing entry point. **Alternatives considered** The tests could mock each action separately. That would duplicate authorization rules and would not verify state transitions across multiple actions. **Roadmap alignment** This supports the existing experimental Paperclip Runner rollout. It does not enable production semantic operations or change app execution. ## What Changed - Add deterministic capability fixture types and seed state. - Add an in-memory capability control-plane adapter. - Enforce run, company, actor, claim, role, and idempotency boundaries. - Model governed task, document, interaction, workspace, secret, routine, and audit changes. - Add deterministic tests and testing-entry-point exports. ## Verification - `pnpm --filter @paperclipai/paperclip-runner test:typescript` - `pnpm --filter @paperclipai/paperclip-runner typecheck:typescript` - `pnpm -r typecheck` - `pnpm build` - The branch changes 5 files relative to its declared base. ## Risks The main risk is a permissive mock that hides a production authorization error. The adapter fails closed for missing claims, wrong roles, cross-company access, duplicate mutations, invalid state, and restricted secret access. Tests cover each fixture domain and serialized restore behavior. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI Codex, `gpt-5`, with agentic reasoning, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either linked an existing public issue or described the issue in-PR - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal Paperclip ticket id - [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 |
||
|
|
773d357d8a |
Add deterministic runner conformance core (#12354)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The runner needs repeatable tests at the provider and control-plane boundaries > - Network services and live providers cannot produce deterministic conformance results > - Small in-memory adapters can exercise the same public contracts without production side effects > - This pull request adds a deterministic harness driver, control-plane adapter, and fixture runner > - It exposes these helpers only from the testing entry point > - The benefit is stable cross-boundary verification for later runtime changes ## Linked Issues or Issue Description **Subsystem affected** packages/paperclip-runner testing and conformance support **Problem or motivation** The public runner contracts have unit tests, but later provider and server slices need a deterministic way to exercise session, event, replay, checkpoint, and result behavior together. **Proposed solution** Add in-memory implementations of the harness-driver and control-plane ports. Add a canonical conformance fixture and runner. Export these utilities only from `@paperclipai/paperclip-runner/testing`. **Alternatives considered** The tests could start a real provider or server. That would make the conformance gate slower, less portable, and dependent on credentials or network state. **Roadmap alignment** This supports the existing experimental Paperclip Runner rollout. It does not enable a production adapter or change current app execution. ## What Changed - Add a deterministic harness-driver implementation. - Add an in-memory control-plane adapter with replay and checkpoint support. - Add a canonical provider-neutral conformance fixture. - Add a reusable conformance runner and contract tests. - Export the helpers from the package testing entry point only. ## Verification - `pnpm --filter @paperclipai/paperclip-runner test:typescript` - `pnpm --filter @paperclipai/paperclip-runner typecheck:typescript` - `pnpm -r typecheck` - `pnpm build` - The branch changes 10 files relative to its declared base. ## Risks Low risk. This pull request adds test-only adapters and conformance helpers. It does not select a runtime or change production behavior. Contract tests verify event identity, replay, checkpoints, and deterministic results. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI Codex, `gpt-5`, with agentic reasoning, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either linked an existing public issue or described the issue in-PR - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal Paperclip ticket id - [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 |
||
|
|
e18632ebcb |
Add durable semantic tool receipts (#12353)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Semantic tools cross a trust boundary between a provider and the control plane > - Durable runs need exact input, result, denial, duplicate, and reconciliation receipts > - Replay must reject unsupported required versions and mismatched receipt pairs > - This pull request adds the receipt builders and deterministic replay fixtures > - It keeps newer sequence and gap safety limits from the current stack > - The benefit is auditable semantic activity before more providers use it ## Linked Issues or Issue Description **Subsystem affected** packages/paperclip-runner **Problem or motivation** Semantic tool calls have basic authorization records, but durable replay does not yet cover reconciled calls, denial redaction, duplicate receipts, governance targets, or artifact references. **Proposed solution** Add bounded semantic receipt builders, a reconciled phase, strict pair binding, fail-closed version checks, and generated replay oracles for the important lifecycle cases. **Alternatives considered** The runner could store provider-native tool payloads. That would weaken protocol portability and make redaction and retry behavior provider-specific. **Roadmap alignment** This supports the existing experimental Paperclip Runner rollout. It does not enable a production adapter. ## What Changed - Add semantic input and result receipt builders. - Add optional reconciliation receipts for pending calls. - Reject unsupported semantic receipt versions. - Validate receipt correlation, operation, idempotency, and digest bindings. - Add deterministic replay fixtures and generated golden outputs. ## Verification - `pnpm --filter @paperclipai/paperclip-runner test:typescript` - `pnpm --filter @paperclipai/paperclip-runner typecheck:typescript` - `pnpm -r typecheck` - `pnpm build` - Replay golden and protocol manifest checks pass. - The branch changes 27 files relative to its declared base. ## Risks The main risk is accepting a receipt that belongs to another call or replaying a duplicate as a new mutation. Binding checks compare correlation, operation, idempotency, and content digest fields. Fixtures cover denials, duplicates, governance chains, optional fields, artifacts, and unsupported versions. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI Codex, `gpt-5`, with agentic reasoning, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either linked an existing public issue or described the issue in-PR - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal Paperclip ticket id - [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 |
||
|
|
d18e281c33 |
Add the native runner session runtime (#12352)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The Paperclip Runner package needs one provider-neutral session loop > - Native execution contracts now define the accepted input and output > - Backends still need bounded execution, recovery, and control-plane ports > - This pull request adds that package-local session runtime > - It does not change server runtime selection or start the experimental runner > - The benefit is a tested execution core for later provider and server layers ## Linked Issues or Issue Description **Subsystem affected** packages/paperclip-runner **Problem or motivation** The runner contracts do not yet have a shared session loop. Each backend would otherwise duplicate event handoff, terminal handling, recovery cursors, timeouts, and checkpoint behavior. **Proposed solution** Add the native session runtime, backend interfaces, control-plane port, harness driver contract, deterministic conformance helpers, and bounded tests. **Alternatives considered** The server could own this loop. That would mix provider process behavior with server persistence and authority logic. **Roadmap alignment** This is part of the existing experimental Paperclip Runner rollout. It does not enable a production adapter. ## What Changed - Add a provider-neutral native session execution loop. - Add recovery cursor reconciliation and checkpoint hooks. - Add bounded timeout and governed-wait behavior. - Add harness driver and control-plane conformance helpers. - Add deterministic backend and session runtime tests. ## Verification - `pnpm --filter @paperclipai/paperclip-runner test:typescript` - `pnpm --filter @paperclipai/paperclip-runner typecheck:typescript` - `pnpm -r typecheck` - `pnpm build` - Protocol generation and manifest checks pass. - The branch changes 14 files relative to its declared base. ## Risks The main risk is a session that hangs, duplicates an event, or restores the wrong cursor after reconnect. Tests cover terminal events, timeouts, durable handoff, duplicate receipts, recovery, continuity breaks, and checkpoint updates. The change remains package-local. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI Codex, `gpt-5`, with agentic reasoning, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change and contains no internal Paperclip ticket id - [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 |
||
|
|
d8dfa27a1e |
Define native runner execution contracts (#12351)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The Paperclip Runner package gives providers one stable execution boundary > - Later runner backends need one validated input and result contract > - Provider-specific shapes cannot leak into server orchestration > - This pull request adds the provider-neutral native execution contracts > - It also keeps legacy input versions readable while it validates new input strictly > - The benefit is a stable boundary for later backend and server pull requests ## Linked Issues or Issue Description **Subsystem affected** packages/paperclip-runner **Problem or motivation** The runner has protocol transport and Codex support, but later backends do not have one public contract for execution input, runtime context, completion output, and recovery state. **Proposed solution** Add versioned native execution input parsers, model envelopes, completion result helpers, runtime context contracts, and durable recovery types. Keep these changes package-local. Do not change server runtime selection. **Alternatives considered** Each provider could define its own server-facing input. That would couple server orchestration to provider details and make compatibility harder to verify. **Roadmap alignment** This is part of the existing experimental Paperclip Runner rollout. It does not enable a new production adapter. ## What Changed - Add versioned native execution input contracts and strict parsers. - Add provider-neutral runtime context and completion contracts. - Add durable recovery and local runner types. - Add structured question compatibility and parser tests. - Export only the contracts that exist in this stack layer. ## Verification - `pnpm --filter @paperclipai/paperclip-runner test:typescript` - `pnpm --filter @paperclipai/paperclip-runner typecheck:typescript` - `pnpm -r typecheck` - Protocol generation and manifest checks pass. - The branch changes 12 files relative to its declared base. ## Risks The main risk is accepting malformed or future input as a supported contract. The parsers reject unknown required versions and unknown fields. The change is package-local and does not select or start the experimental runner. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI Codex, `gpt-5`, with agentic reasoning, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge |
||
|
|
b1cd261212 |
feat(runner): normalize provider event contracts (#12350)
## Thinking Path > - The runner already persists PRP events, but provider-native activity needs one bounded, provider-neutral vocabulary before additional providers can be added safely. > - The protocol catalog must describe capabilities without enabling or authorizing a provider. > - Provider normalization must not require an ACPX runtime dependency merely to compile the shared event layer. > - This pull request adds the event contract and pure normalizers only; provider transports and production selection remain unchanged. ## Linked Issues or Issue Description This is the first follow-up stacked on #12321. Codex, OpenCode, and ACP runtimes expose different activity shapes. Without canonical normalization, downstream task threads and traces would need provider-specific branching and could retain unbounded or unsafe payloads. ## What Changed - Expand the PRP provider descriptor and canonical activity event families. - Add bounded Codex, OpenCode, and ACP event normalizers for plans, tools, research, delegation, artifacts, review, safety, waits, and notices. - Preserve strict schema validation and regenerate the checked-in schema bundle and manifest. - Use a structural ACP event input so the provider-neutral layer does not introduce or authorize an ACPX runtime dependency. - Export the provider-event contract from the existing package root. ## Verification - `pnpm --filter @paperclipai/paperclip-runner typecheck:typescript` - `pnpm --filter @paperclipai/paperclip-runner test:typescript` — 11 files and 88 tests passed. - `pnpm -r typecheck` - `pnpm build` - `git diff --check` - The local full repository runner reached unrelated macOS workspace-path fixture failures; the affected runner suites pass and the repository CI shards are the handoff authority. - Diff against the declared base: 8 files. ## Compatibility Boundary - No provider transport, adapter, server route, feature flag, or runtime selection changes. - Catalog presence does not authorize discovery or execution. - Existing Codex execution continues through its current path. - No dependency, migration, workflow, or lockfile change. ## Risks The main risk is accepting malformed or unbounded provider payloads. Schema validation remains fail-closed, text/output fields are bounded and redacted, unsafe paths and URLs are discarded, and representative variants for every declared event family are covered by tests. ## Model Used OpenAI Codex, GPT-5 family. The client does not expose the exact deployment ID or context window. Agentic reasoning, tool use, and code execution were enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have described the issue in-PR following the relevant template - [x] I have not referenced internal/instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal task identifier - [x] I have run the affected local tests and they pass - [x] I have added or updated tests where applicable - [x] I have updated the compatibility notes for this change - [x] I have considered and documented risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open actionable comments - [x] I will address all Greptile and reviewer comments before requesting merge |
||
|
|
bc9ba7cd26 |
feat(runner): project native runs into task threads (#12321)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The experimental Paperclip Runner can execute a guarded Codex run and persist provider-neutral events. > - The task page still reads direct-adapter transcripts and cannot present those native events. > - Structured runner questions must also use the existing task interaction experience. > - Runtime selection must use the persisted run mode, not an adapter name or a current feature flag. > - This pull request projects native events and questions into the existing task thread. > - Direct adapters keep their existing transcript, composer, interaction, and finalization paths. > - The benefit is a complete native Codex task thread without a behavior change for existing adapters. ## Linked Issues or Issue Description Refs #12202. This pull request replaces that stale implementation on current `master`. **What happened?** The server persists native runner events and structured input requests. The task page only consumes direct-adapter transcripts. A native run therefore cannot present a complete transcript, usage, or question flow through the normal task experience. **Expected behavior** Native runs project persisted provider-neutral events into the existing task thread. Native structured questions use the existing interaction card. Direct adapters retain their current behavior. **Steps to reproduce** 1. Enable the experimental runner. 2. Start a native Codex run that emits progress, usage, a structured question, and a final reply. 3. Open the task page. 4. Observe that the direct-adapter transcript path cannot project the native event records. **Paperclip version or commit** `master` at `67f9867bc`. ## What Changed - Add the canonical structured-question validator and shared contract exports. - Materialize native input requests as existing task interactions. - Validate native answers and deliver them through the durable question-response receipt. - Resume the original PRP request with an idempotent `request.resolve` command. - Project native messages, tool activity, cumulative usage, and final replies into the existing transcript model. - Propagate persisted `runtimeMode` to the task page and select native handling only for `runtimeMode: "native"`. - Expire pending interactions through the shared issue service on every terminal transition, including decisions, stalled reviews, tree control, and pipeline retry cleanup. - Queue native run cancellation while a transaction is open and execute it only after the owning transaction commits. - Keep nonterminal and non-runner issue paths on their existing service call shapes and behavior. ## Verification - `pnpm --filter @paperclipai/server typecheck` — passed, including the Rust runner release build and protocol/catalog drift gates. - Focused native-thread and lifecycle suites — 18 files and 481 tests passed during review. - `issue-execution-policy-routes.test.ts` — 19/19 passed after the final transactional-queue expectation update. - `issue-agent-mutation-ownership-routes.test.ts` — 87/87 passed in the final isolated compatibility rerun. - GitHub Actions — policy, build, canary, typecheck/release registry, 5 serialized server shards, 8 general-test shards, 3 browser shards, and both aggregate gates passed on `7793f3193`. - Security — Snyk, Socket Project Report, Socket PR Alerts, and Superagent passed. - Greptile — 5/5 on `7793f3193`; all actionable review threads resolved. - `git diff --check` — passed. - Diff against `master`: 44 files. ## Compatibility Boundary - Native transcript polling only runs when the persisted run reports `runtimeMode: "native"`. - Missing or legacy runtime modes continue through `useLiveRunTranscripts`. - Legacy questions keep the existing optional free-text choice. - Native closed select sets can suppress that legacy fallback. - Terminal cleanup uses the same issue service for native and legacy interactions; only a bound native question schedules a native run cancellation. - Native cancellation happens after transaction commit, so failed or rolled-back writes do not cancel a still-valid run. - The durable delivery service checks the original native request before it considers a continuation run. - This pull request adds no migration, dependency, workflow, manifest, or lockfile change. ## Risks The main risk is routing a direct-adapter task through native handling or changing terminal issue behavior. The implementation selects the native path only from persisted runtime facts, retains the existing nonterminal call shape, and schedules native cancellation only for a validated bound native question after commit. Focused and repository-wide tests cover both paths. Native requests remain bound to the company, issue, run, and agent; answers are validated, durable, and idempotent across reconnects. ## Model Used OpenAI Codex, GPT-5 family. The client does not expose the exact deployment ID or context window. Agentic reasoning, tool use, and code execution were enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change and contains no internal Paperclip ticket id or instance-derived details - [x] I have run the affected local tests and they pass - [x] I have added or updated tests where applicable - [x] I have updated the compatibility notes for this change - [x] I have considered and documented risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I addressed all Greptile and reviewer comments before requesting merge |
||
|
|
a560b48d6d |
feat(apps): refine Postman and Shopify setup (#12357)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Apps give those agents governed access to external tools. > - Provider catalogs must match each provider's current protocol and credential contract. > - Postman method labels and API-key placement were outdated. > - Shopify now offers a UCP commerce endpoint that needs a managed agent-profile argument. > - This pull request updates both providers and documents the complete connection-authoring workflow. > - The benefit is accurate setup, safer runtime defaults, and a repeatable provider review process. ## Linked Issues or Issue Description Refs #11965 This is stack 10 of 11. It depends on stack 9 and preserves the final catalog work recovered from #11965. Related: #5904 covers Shopify skill routing. This pull request covers the Apps connection contract instead. ## What Changed - Update Postman hosted MCP methods, capability choices, default selection, and bearer-token placement. - Add Shopify UCP commerce and Storefront compatibility methods with public-store prerequisites. - Inject the reviewed Shopify UCP agent profile at runtime and remove that managed field from user input schemas. - Classify Shopify checkout completion and cancellation as destructive actions. - Expand the connection authoring runbook from provider research through verification and pull request handoff. - Add focused shared, server, and UI coverage. - Make the approved-execution waiter phase-aware so slow preparation cannot consume the provider execution timeout and grace period. - Settle legacy pre-execute-on-approve requests and invocations as failed, clear their stale idempotency key, and allow a fresh governed approval instead of leaving work stuck in `executing`. ## Verification - `pnpm exec vitest run packages/shared/src/app-definitions.test.ts server/src/__tests__/tool-access-service.test.ts ui/src/pages/apps/AppsConnect.test.tsx -t "Postman|Shopify|normalizeConnectionMethodConfig|classifyRisk"` (16 passed) - `pnpm exec vitest run server/src/services/approved-execution-wait.test.ts` (4 passed) - `pnpm exec vitest run server/src/__tests__/tool-gateway.test.ts -t "enforces policy, approvals, retries, rate limits, and company boundaries for connected remote MCP calls"` (1 passed) - `pnpm exec vitest run server/src/__tests__/tool-gateway-service.test.ts` (21 passed; includes legacy approval settlement and fresh-approval recovery) - `pnpm --filter @paperclipai/server typecheck` - `pnpm check:token-gates` - `pnpm -r typecheck` - `pnpm build` ## Risks - Shopify UCP calls now include a Paperclip-managed agent profile that overrides caller input at the same path. - Postman EU credentials now use the hosted MCP server's bearer-token contract instead of the general REST API header. - The catalog generator and checked-in definitions change together to prevent regeneration drift. - Approved execution preparation has an explicit two-minute bound; provider execution retains its own 65-second timeout and persistence grace starting from durable provider start. - Legacy approvals created before execute-on-approve are intentionally terminalized and must be requested again under the current signed contract. > I checked `ROADMAP.md`. This provider update does not duplicate planned core work. The related open Shopify PR addresses skill routing, not Apps connections. ## Model Used OpenAI Codex, GPT-5. The runtime exact model ID and context window were not exposed. The model used reasoning, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change 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 |
||
|
|
d387cc0ff0 |
feat(connections): add managed external MCP connectors (#12346)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Connection intents need secure provider implementations to complete setup. > - Some providers use managed OAuth or external credential brokers. > - Those tokens must stay out of durable Paperclip state and fail closed when refresh fails. > - This pull request adds managed connector backends and the required storage contract. > - The benefit is safer provider setup with governed credential lifecycles. ## Linked Issues or Issue Description Refs #11965 This is stack 8 of 11. It depends on stack 7 and replaces another reviewable part of #11965. ## What Changed - Add managed Google Workspace and external connector backends. - Add Vercel Connect support without storing provider bearer tokens. - Add replay-safe migration 0232 and its generated snapshot. - Fail closed and clear stale token bindings when organization OAuth refresh needs reauthorization. ## Verification - `pnpm --filter @paperclipai/server typecheck` - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/tool-access-service.test.ts` - Result: 194 tests passed. - `pnpm --filter @paperclipai/db check:migrations` - `pnpm build` - `pnpm exec vitest run --project @paperclipai/server server/src/services/remote-url-credentials.test.ts` (5 passed, including URL userinfo vault extraction) ## Risks - Broker metadata errors can block provider setup. - OAuth refresh failure disables the shared organization connection until reauthorization. - Migration 0232 is generated, ordered after 0231, and safe to replay. > I checked `ROADMAP.md`. This stack continues the existing app connection work from #11965 and does not duplicate another planned item. ## Model Used OpenAI Codex, GPT-5. The runtime model ID and context window were not exposed. The model used reasoning, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have linked the public source pull request with `Refs #` - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [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 |
||
|
|
b3343dbd64 |
feat(connections): add self-serve intent runtime (#12345)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agents need a governed way to request app connections during issue work. > - The catalog now describes the available providers and setup methods. > - A request must become a durable, company-scoped intent before an operator acts on it. > - This pull request adds that intent runtime across server, agent, CLI, and shared contracts. > - The benefit is a safe bridge from agent need to operator-approved setup. ## Linked Issues or Issue Description Refs #11965 This is stack 7 of 11. It depends on stack 6 and replaces another reviewable part of #11965. ## What Changed - Add connection intent types, validation, service logic, and routes. - Add agent runtime tools and CLI support for connection requests. - Add issue-thread interaction support for connection intents. - Add runtime, route, adapter, and contract tests. - Hold the final resolved-continuation row lock through asynchronous adapter preparation until an actual process spawn, so parking or reassignment cannot cross that boundary. - Report Hermes Gateway's first remote run request through the shared dispatch hook so the resolved-intent lock is released at the true dispatch boundary. - Revalidate the addressed user's live non-viewer membership and connection-management authority for every intent mutation, including OAuth completion. ## Verification - `pnpm --filter @paperclipai/server typecheck` - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/tool-access-service.test.ts` - Result: 176 tests passed. - `pnpm build` - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/heartbeat-stale-queue-invalidation.test.ts` (32 passed; includes non-process dispatch lock-release coverage) - `pnpm exec vitest run --project @paperclipai/server server/src/__tests__/connection-intents-service.test.ts -t "addressed-user mutation"` (1 passed) - `pnpm exec vitest run --project @paperclipai/server server/src/__tests__/tool-access-service.test.ts -t "binds OAuth callback completion to the initiating board session"` (1 passed) - `pnpm --filter @paperclipai/hermes-paperclip-adapter test -- src/gateway/server/execute.test.ts` (23 passed; includes dispatch-hook ordering and exactly-once coverage) - `pnpm --filter @paperclipai/hermes-paperclip-adapter typecheck` ## Risks - A malformed intent could create an unusable operator request. - Validators and company checks reject invalid or cross-company requests. - The final continuation gate holds the issue row lock through adapter preparation until process or remote dispatch; later operator changes use the normal active-run interruption path. - The change does not add a database migration. > I checked `ROADMAP.md`. This stack continues the existing app connection work from #11965 and does not duplicate another planned item. ## Model Used OpenAI Codex, GPT-5. The runtime model ID and context window were not exposed. The model used reasoning, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have linked the public source pull request with `Refs #` - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [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> |
||
|
|
fcb2e99e8f |
feat(apps): expand the self-serve connection catalog (#12344)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - A useful app store needs accurate and selectable provider definitions. > - Local brand assets now cover the expanded provider set. > - Provider methods differ in transport, authentication, ownership, and required scope. > - This pull request expands the catalog and encodes those provider contracts. > - The benefit is a larger self-serve store with explicit setup choices. ## Linked Issues or Issue Description Refs #11965 This is stack 6 of 11. It depends on stack 5 and replaces another reviewable part of #11965. ## What Changed - Add and update provider definitions for the self-serve catalog. - Add Google Workspace connection methods and capability profiles. - Add catalog generation, ingestion, URL matching, and contract tests. - Update legacy key tests to use a provider that still uses header credentials. ## Verification - `pnpm --filter @paperclipai/server typecheck` - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/tool-access-service.test.ts` - Result: 164 tests passed. - `pnpm build` ## Risks - An incorrect provider definition can offer the wrong setup method. - Contract tests verify transport, authentication, and provider URL behavior. - The change does not add a database migration. > I checked `ROADMAP.md`. This stack continues the existing app connection work from #11965 and does not duplicate another planned item. ## Model Used OpenAI Codex, GPT-5. The runtime model ID and context window were not exposed. The model used reasoning, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Refs #` or (b) described the issue in this pull request - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [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> |
||
|
|
6244e4cf32 |
feat(apps): add Composio and Gmail connectors (#12342)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - App connections need both direct providers and managed provider hubs. > - The grant layer now defines safe credential ownership. > - Composio needs parent and child connection lifecycle rules, and Gmail needs governed setup. > - This pull request adds both connector families on the grant foundation. > - The benefit is broader app access without weakening credential isolation. ## Linked Issues or Issue Description Refs #11965 This is stack 4 of 11. It depends on stack 3 and replaces another reviewable part of #11965. ## What Changed - Add Composio parent and child connection support. - Add Gmail connection setup and governance. - Preserve credential paths and remove duplicate binding declarations. - Cascade Composio pause and restore actions to child connections. ## Verification - `pnpm --filter @paperclipai/server typecheck` - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/tool-access-service.test.ts` - Result: 164 tests passed. - `pnpm build` ## Risks - Parent lifecycle changes can affect every Composio child. - The service restores only children whose provider accounts remain active. - Credential binding paths are normalized before secret resolution. > I checked `ROADMAP.md`. This stack continues the existing app connection work from #11965 and does not duplicate another planned item. ## Model Used OpenAI Codex, GPT-5. The runtime model ID and context window were not exposed. The model used reasoning, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links - [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> |
||
|
|
20ccf3f476 |
feat(apps): add connection grants and delegated identities (#12341)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - External tools need explicit identity and access boundaries. > - Shared connection credentials cannot represent every user-scoped use case. > - Grants must stay company-scoped and support safe delegation. > - This pull request adds connection grants, identity rules, and their database contract. > - The benefit is durable control over which identity an agent may use. ## Linked Issues or Issue Description Refs #11965 This is stack 3 of 11. It depends on stack 2 and replaces another reviewable part of #11965. ## What Changed - Add company and user connection grants. - Add delegated identity and membership rules. - Synchronize database, shared, server, and UI contracts. - Register the grant-member replacement route in the OpenAPI surface in the same layer that mounts it. - Add migration 0231 with replay-safe guards and coverage. ## Verification - `pnpm -r typecheck` - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/tool-access-service.test.ts` - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/openapi-routes.test.ts` (5 passed) - `pnpm --filter @paperclipai/db check:migrations` - `pnpm build` ## Risks - Incorrect grant selection could expose the wrong credential scope. - The service enforces company and subject boundaries before credential use. - Migration 0231 is generated, ordered after 0230, and safe to replay. > I checked `ROADMAP.md`. This stack continues the existing app connection work from #11965 and does not duplicate another planned item. ## Model Used OpenAI Codex, GPT-5. The runtime model ID and context window were not exposed. The model used reasoning, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either linked a public issue or pull request with `Refs #` - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [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> |
||
|
|
b51112798f |
feat(apps): improve gateway and workspace connection UX (#12340)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - App connections must work in both the operator UI and agent tool gateway. > - The first stack layer adds secure remote connections. > - Operators still need clear setup, test, and recovery states. > - This pull request adds the gateway behavior and the workspace connection experience. > - The benefit is a connection flow that is easier to understand and recover. ## Linked Issues or Issue Description Refs #11965 This is stack 2 of 11. It depends on stack 1 and replaces another reviewable part of #11965. ## What Changed - Improve remote tool gateway connection behavior. - Add clearer app setup, test, and recovery states. - Add focused server and UI tests for the new paths. - Keep the diff isolated from later identity and catalog work. - Stabilize DNS-pinned remote HTTP protocol fixtures and the managed-runtime public-origin fixture for this independently tested layer. ## Verification - `pnpm -r typecheck` - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/tool-access-service.test.ts` (150 passed) - `pnpm test:run` - `pnpm check:token-gates` - `pnpm build` ## Risks - Gateway errors now surface through new user-facing states. - A stale connection can require a new setup attempt. - The change does not add a database migration. - The injected HTTP transport and public URL are test-only fixtures; production DNS pinning and runtime behavior are unchanged. > I checked `ROADMAP.md`. This stack continues the existing app connection work from #11965 and does not duplicate another planned item. ## Model Used OpenAI Codex, GPT-5. The runtime model ID and context window were not exposed. The model used reasoning, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links - [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> |
||
|
|
cabc9146d0 |
feat(apps): add secure remote MCP and PostHog setup (#12339)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Apps give those agents governed access to external tools. > - Remote MCP setup needs secure endpoint validation and durable credentials. > - PostHog needs both browser sign-in and personal API key setup paths. > - This pull request adds the shared remote MCP foundation and the PostHog definition. > - The benefit is a secure and reusable base for later app connection work. ## Linked Issues or Issue Description Refs #11965 This is stack 1 of 11. It replaces the first reviewable part of #11965. ## What Changed - Add guarded remote MCP setup and credential handling. - Add PostHog OAuth and API key connection methods. - Add focused server, shared contract, and UI coverage. - Keep the migration replay-safe and idempotent. - Give the late-close security regression the same 10-second CI headroom as the adjacent real-timer handshake test. - Synchronize fake-timer handshake tests at the exact ensure-session boundary so real filesystem setup cannot race the fake deadline. - Drive PTY overflow coverage only after listener registration so scheduling cannot reorder the test fixture. ## Verification - pnpm exec vitest run packages/adapter-utils/src/acpx-engine/execute.test.ts server/src/__tests__/plugin-worker-manager.test.ts (220 passed; affected cases also passed five focused stress repetitions) - `pnpm exec vitest run packages/adapter-utils/src/acpx-engine/execute.test.ts -t "never leaks a sandbox-provided value from a late close rejection into logs or the result"` (1 passed) - `pnpm exec vitest run packages/adapter-utils/src/acpx-engine/execute.test.ts -t "never promotes a late ensureSession resolution|closes a late-resolving real handle exactly once"` (2 passed) - `pnpm -r typecheck` - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/tool-access-service.test.ts` - `pnpm --filter @paperclipai/db check:migrations` - `pnpm build` ## Risks - Remote endpoint validation can reject configurations that previously passed without checks. - OAuth configuration errors can block setup until the operator corrects the provider settings. - The migration uses guarded statements so repeated execution is safe. - The test-only synchronization changes do not affect runtime behavior; they remove filesystem/fake-clock and listener-registration races observed under parallel CI load. > I checked `ROADMAP.md`. This stack continues the existing app connection work from #11965 and does not duplicate another planned item. ## Model Used OpenAI Codex, GPT-5. The runtime model ID and context window were not exposed. The model used reasoning, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change 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> |
||
|
|
6154e00f26 |
feat(server): add a task-drain admission hold to the instance API (#12485)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The server admits agent work through heartbeat scheduling and execution paths > - Operators need to stop new work before maintenance or a graceful shutdown > - A process restart alone does not provide a reusable admission control primitive > - This pull request adds an instance API that holds new task admission and reports process quiescence > - The benefit is a small, auditable control that lets operators wait for active work without a restart ## Linked Issues or Issue Description **Problem or motivation** Operators cannot hold new task admission without restarting the Paperclip process. A restart can interrupt maintenance flows and does not provide a status signal for active work. **Proposed solution** Add `GET /instance/task-drain`, `POST /instance/task-drain`, and `DELETE /instance/task-drain`. The server keeps the drain state in process memory, applies it to every scheduling suppression path, supports an optional TTL up to 24 hours, and reports active wake and run counts. **Alternatives considered** A timer would clear the drain after its TTL, but it could keep the Node.js event loop open during shutdown. A database row would add storage and query work for process-local state. The implementation uses lazy expiry and process memory instead. **Roadmap alignment** The change supports the roadmap goal for enforced outcomes and safe recovery actions. It does not duplicate a listed roadmap item. **Additional context** This is a server and shared-package change. It adds no user interface and no database migration. ## What Changed - Add process-local task-drain state with lazy TTL expiry. - Add task-drain admission suppression to the shared heartbeat resolver. - Add instance routes to read, start, and stop a task drain. - Add validation for positive TTL values and the shared 24-hour maximum. - Add activity records for drain mutations and tests for status, access control, validation, and suppression. ## Verification - Run `pnpm exec vitest run --project @paperclipai/server server/src/__tests__/heartbeat-task-drain.test.ts server/src/__tests__/instance-settings-routes.test.ts server/src/__tests__/heartbeat-scheduling-suppression.test.ts`. - Run `pnpm --filter @paperclipai/shared exec tsc --noEmit`. - Run `pnpm --filter @paperclipai/server exec tsc --noEmit` and compare its known pre-existing errors with the base commit. - Confirm that pull request CI reaches a terminal green state. ## Risks The drain state exists only in process memory, so a restart clears it. This behavior matches the process-local design. A drain without a TTL remains active until an operator calls the delete route. The status route reads in-memory activity sets and does not query stale database rows. ## Model Used OpenAI Codex, GPT-5, extended reasoning with tool use and code execution. The exact runtime context window is not exposed by the execution environment. ## 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> |
||
|
|
a20a4944ec |
feat: add Grok device login to the sandbox login panel (#12469)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Paperclip uses adapters to connect agents and model providers to its control plane > - The sandbox login panel supports displayed-code login for selected adapters > - Grok users need the same login path and a private credential home for later runs > - This pull request adds Grok support to the shared device-login path and preserves the existing Codex path > - The benefit is one secure login flow for both adapters with company-scoped credential storage ## Linked Issues or Issue Description **Agent or provider** Grok Local needs displayed-code login support in the sandbox login panel. **Why this adapter is useful** This change lets users sign in to Grok from the sandbox login panel. It also gives later Grok runs access to the stored credential. **How the agent is invoked** The Grok local adapter uses its login command through the shared displayed-code login flow. Later runs receive the managed home through `GROK_HOME`. **Additional context** The change uses adapter-scoped login lifecycle handling. It stores the credential in a company-scoped directory with mode `0700`, and it stores the credential file with mode `0600`. ## What Changed - Rename the shared device-login modules to adapter-neutral names. - Scope the shared login lifecycle to a closed adapter set. - Return the device-login URL that the provider prints. - Add the Grok prompt parser, login command, capability, and login panel entry. - Store the Grok credential in a private, company-scoped home directory. - Pass `GROK_HOME` to later Grok runs. - Add tests for the Grok adapter, the Daytona sandbox provider, the server login path, and the user interface. ## Verification - Run `pnpm vitest run packages/adapters/grok-local/src/server/adapter-auth-promotion.test.ts`. - Run the Grok adapter package suite. - Run the Daytona sandbox provider suite. - Run the server device-login suites. - Run the user interface suite. - Confirm the full CI suite passes. ## Risks The change extends shared login lifecycle code to another adapter. A regression could affect Codex login. The credential path uses explicit `chmod` calls to keep the directory at mode `0700` and the file at mode `0600`. ## Model Used OpenAI Codex, GPT-5. The runtime used tool calls and code review support. The runtime did not provide a context-window value. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have 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 - [ ] 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> |
||
|
|
64b7dce0ad |
refactor(adapter-utils): replace the process-wide byte ledger with route-local byte bounds (#12465)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The adapter layer carries sandbox requests to host processes. > - The HTTP/2 bridge used one process-wide byte ledger for all routes. > - One busy route could exhaust that shared budget and move another route to file transport. > - This pull request gives each host retention site a fixed byte bound and limits concurrent HTTP/2 streams. > - The benefit is local protection: one route cannot consume the byte budget of another route. ## Linked Issues or Issue Description **What happened?** The HTTP/2 bridge used one aggregate byte ledger for retained bytes across all routes. A busy route could exhaust the shared budget and force an unrelated route to use file transport. **Expected behavior** Each route should protect its own retained bytes. A reset on one HTTP/2 stream should cancel only that stream's host forward. **Steps to reproduce** 1. Start the HTTP/2 bridge with multiple sandbox routes. 2. Send enough retained data through one route to reach the aggregate byte limit. 3. Send a request through a sibling route. 4. Observe that the sibling route can fall back to file transport because the first route used the shared ledger. **Paperclip version or commit** `47639e227e78e3c5e0dd1a3c0e2d792fe86895a3` **Deployment mode** Built from source with the adapter-utils and server test suites. ## What Changed - Bound each host retention site with a fixed local byte limit. - Limited concurrent live HTTP/2 streams with one built-in stream limit. - Bound each host forward and response-body read to its own HTTP/2 stream lifetime. - Removed the process-wide byte ledger, its environment override, its metrics, and its file-transport fallbacks. - Added tests for the stream limit, host body budget, and sibling-stream cancellation. ## Verification - Run `pnpm vitest run --project adapter-utils`. - Confirm that 996 adapter-utils tests pass. - Confirm that `test_live_forward_work_never_passes_the_stream_limit` passes. - Confirm that `test_the_host_body_budget_matches_the_stream_limit` passes. - Confirm that the sibling-stream cancellation test passes. - Run `pnpm tsc --noEmit`. - Confirm that all pull request checks pass. ## Risks The bridge no longer uses a process-wide byte ledger. A local bound or stream limit that is too low can reject or delay valid work. The tests cover the new limits and stream cancellation behavior. ## Model Used OpenAI GPT-5 Codex. Runtime model ID: GPT-5. The model used code execution and repository tools. The runtime does not expose the context window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes: #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
a3b78f9d34 |
fix(cli): make embedded-Postgres tests survive runner contention (#12466)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The CLI test suite uses embedded Postgres for worktree checks. > - Several tests start a cluster and run migrations on each test. > - Runner contention can make this cost class exceed small hand-written time budgets. > - A timed-out test can also leave the cluster alive while cleanup removes its data directory. > - This pull request gives the cost class one measured timeout and registers cleanup for the timeout path. > - The benefit is stable tests and fewer orphaned embedded Postgres processes. ## Linked Issues or Issue Description No public GitHub issue tracks this defect. Related PRs #10987 and #10961 address wider embedded-Postgres test setup issues. This pull request addresses the CLI timeout and cleanup path described below. **What happened?** Five CLI tests used different hand-written time budgets while they started embedded Postgres and ran migrations. Runner contention made one test exceed its budget. A timeout also skipped the `finally` cleanup path and left a Postgres process alive. **Expected behavior** Each embedded-Postgres test gets a budget that covers measured runner contention. Cleanup stops the cluster before the test removes its data directory, including after a timeout. **Steps to reproduce** 1. Run `npx vitest run cli/src/__tests__/worktree.test.ts` on a contended runner. 2. Observe the embedded-Postgres tests take longer than their small hand-written budgets. 3. Inspect the process list after a timeout and observe an orphaned Postgres process. **Paperclip version or commit** The defect reproduces on `master` before this pull request. **Deployment mode** Built from source with Vitest. **Installation method** Built from source with pnpm. ## What Changed - Export `EMBEDDED_POSTGRES_TEST_TIMEOUT_MS` from the embedded-Postgres test helper. - Apply the shared timeout to every test defined by `itEmbeddedPostgres`. - Replace the five hand-written timeout values in `worktree.test.ts`. - Register temporary-directory removal and cluster stop with `onTestFinished` in the correct order. - Restore the working directory during timeout cleanup. ## Verification - `npx vitest run cli/src/__tests__/worktree.test.ts` passes 63 tests. - `npx vitest run cli/src` passes 424 tests across 59 files. - `tsc --noEmit` in `cli/` adds no new error in the touched files. - CI must pass on the pull request head. - Greptile must report 5/5 with no unresolved blocking thread. ## Risks - Low risk. The change affects test helpers and test cleanup only. - The shared budget can lengthen a failing test before Vitest reports the failure. - The cleanup order depends on Vitest callback order, which the tests now use explicitly. ## Model Used OpenAI Codex, GPT-5. The model used tool calls and code review support. The context window size and internal reasoning mode were not exposed in this run. ## 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> |
||
|
|
e127faa14c |
fix(adapter-utils): bound the ACP startup handshake and fence the abandoned session promise (#12454)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Adapter utilities start and control agent sessions. > - The ACP startup handshake can stay pending when the sandbox transport closes. > - A pending handshake keeps the run active and prevents a clear operator result. > - This pull request bounds the handshake and fences its abandoned promise. > - The result gives each startup failure a terminal state and a safe host-authored diagnostic. ## Linked Issues or Issue Description No matching public issue or pull request appeared in the GitHub search for this failure. The issue details follow. **What happened?** The adapter engine awaited `runtime.ensureSession()` without a startup bound. A lost sandbox transport could leave the await pending. **Expected behavior** The engine must end the run when the startup deadline expires or the duplex transport closes. A late session result must not reopen the settled run. **Steps to reproduce** 1. Start an ACP-backed agent run. 2. Keep the ACP initialization call pending. 3. Let the startup deadline expire or close the duplex transport. 4. Confirm that the run reaches a terminal state and that a late session result does not reopen it. **Paperclip version or commit** `66e1c0df8b23cb8354b36dd446d9548dc4389191` merge base. **Deployment mode** Local dev (`pnpm dev`). **Installation method** Built from source (`pnpm dev`). **Agent adapter(s) involved** Custom / external plugin adapter. **Database mode** Not database-related. **Relevant logs or output** The new tests use fixed host-authored diagnostics for handshake guard failures and late close failures. **Additional context** The change updates the execution semantics document and adds regression coverage. The three existing failures in `execute.test.ts` also occur at the merge base. ## What Changed - Bound `runtime.ensureSession()` with a startup deadline and a duplex transport loss check. - Added terminal error codes for handshake timeout and transport loss. - Fenced late session resolution and rejection so the settled run has one owner. - Suppressed sandbox-controlled diagnostic values on the guard-failure and late-close paths. - Added regression tests for timeout, transport loss, late resolution, and late close rejection. - Documented the startup live-path contract. ## Verification - `pnpm --filter @paperclipai/adapter-utils exec tsc --noEmit` exits 0. - The engine test suite runs from the repository root. - The new regression cases pass. - The three known failures remain the only failures and also fail at the merge base. The board approved this pre-existing test exception. - Cold start and session resume cases pass. - All required GitHub checks pass. - Greptile reports 5/5 with no open P2 findings, recommendations, or follow-ups. ## Risks The startup guard changes only the ACP startup path. A slow but valid startup can now end at the configured deadline. The fence closes a late handle once and records fixed host-authored diagnostics. ## Model Used OpenAI Codex, GPT-5, current model version, tool use and code execution, with the full task context. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes: #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally. Three pre-existing failures remain and have an approved exception. - [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> |
||
|
|
b2752b21d5 |
fix(adapter-utils): allow process sessions without birthtime (#12451)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Remote agent adapters use a process-session wrapper inside a sandbox. > - Some supported sandbox filesystems do not report inode creation time. > - The wrapper rejects a zero creation time before it launches the agent. > - This pull request accepts that filesystem shape and keeps the existing change-time probe. > - The benefit is that valid sandbox runs can start without a birth-time field. ## Linked Issues or Issue Description **What happened?** The remote process-session wrapper exited before it launched the agent when the sandbox filesystem reported `birthtimeMs` as zero. **Expected behavior** The wrapper must start on a filesystem that does not report inode creation time. **Steps to reproduce** 1. Start the remote process-session wrapper. 2. Make `lstat()` report a zero `birthtimeMs` for its session directory. 3. Observe that the pre-fix wrapper terminates before the child process starts. **Paperclip version or commit** Reproduced from `66e1c0df8b23cb8354b36dd446d9548dc4389191`. **Deployment mode** Self-hosted server with a remote sandbox runtime. ## What Changed - Allow a zero reported creation time for process-session directories. - Keep the probe that rejects a creation time copied from change time. - Add a regression test that launches and stops a session with zero birth time. ## Verification - `npx vitest run packages/adapter-utils/src/execution-target-stdin-race.test.ts` - `pnpm --filter @paperclipai/adapter-utils typecheck` ## Risks A filesystem without creation time can reduce the precision of sandbox-local path-swap detection. This change does not change host-file or Paperclip API authority. A follow-up will review that larger security posture alignment. > I checked `ROADMAP.md`. This is a focused compatibility bug fix for the existing sandbox-agent roadmap area. ## Model Used OpenAI Codex — GPT-5.6. The exact deployment suffix and context-window size are not exposed. The model used reasoning, shell tools, 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> |
||
|
|
d9449e636e |
feat(onboarding): sign in to an agent provider during onboarding (#12440)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - New organizations create their first agent through the onboarding wizard > - The wizard does not show provider sign-in when a host credential is absent or unknown > - The create step also gives unclear feedback when the provider needs authentication > - This pull request adds a safe auth signal and a provider sign-in step for sandbox drivers > - The benefit is a clearer onboarding path with no token or account data in the signal ## Linked Issues or Issue Description **Subsystem affected** Cross-cutting (server API, shared types, and UI) **Problem or motivation** The onboarding wizard can fail when the selected provider needs authentication. It does not tell the person how to complete sign-in. **Proposed solution** Add a status-only provider auth signal. Show the sign-in panel for sandbox drivers when the signal says `absent` or `unknown`. Apply a stored Claude login to the new agent and block creation when the adapter test reports missing authentication. **Alternatives considered** The wizard could hide the sign-in panel when the signal read fails. This would hide a needed action, so this pull request shows the panel when the signal is unknown. **Roadmap alignment** The change supports the roadmap goal for scoped and audited credential bindings. **Additional context** The auth signal returns only `present`, `absent`, or `unknown`. It never returns a token, identifier, or account name. ## What Changed - Add `GET /api/companies/:companyId/adapters/:type/auth-signal` with company and permission checks. - Add shared auth-signal types and the UI query path. - Apply a stored Claude login by reference without reading its token. - Show the provider sign-in panel only for sandbox drivers with interactive terminal support. - Block agent creation when the provider test reports missing authentication. - Add route, wizard, and end-to-end test coverage. ## Verification - `pnpm --filter @paperclipai/server test adapter-auth-signal-routes` passes 50 tests. - `pnpm --filter @paperclipai/ui test OnboardingWizard` passes 69 tests. - `pnpm --filter @paperclipai/ui exec tsc --noEmit` exits with code 0. - The `e2e_shards` lane runs `tests/e2e/onboarding.spec.ts`. ## Risks The route reads a host-local readiness signal. It returns `unknown` on read errors and never exposes credential data. The UI may add a sign-in step when the signal is unavailable. ## Model Used OpenAI Codex, GPT-5, extended reasoning, tool use, and code execution. The exact context window was not provided. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes: #` / `Refs: #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [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> |
||
|
|
8316ceb0b9 |
Add the Better Auth issuer column so signup and sign-in work (#12396)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - A self-hosted install in `authenticated` mode signs users in with Better Auth, mounted at `/api/auth` over a hand-written Drizzle `account` table in `packages/db` > - Better Auth 1.7.0 added a required `issuer` field to that `account` model, plus a unique index on `(issuer, accountId)` > - The dependency bump in #11886 changed only `server/package.json` and the lockfile, so the Drizzle table never grew the column > - The Drizzle adapter checks the model against the schema on every write, so `linkAccount` throws and sign-up answers 500 with an empty body; a fresh install cannot create its first user, and an upgraded install locks out every existing user > - This pull request adds the `issuer` column and its unique index, and migrates the column in with a backfill that covers every existing row > - The benefit is that sign-up and sign-in work again, on a new install and after an upgrade ## Linked Issues or Issue Description No existing issue. Describing it inline, following `.github/ISSUE_TEMPLATE/bug_report.yml`. Refs #11886 (the dependency bump that introduced the required field). Refs #12269 (an earlier attempt at this fix; its backfill covers only `provider_id = 'credential'`). **What happened?** Sign-up fails on a self-hosted install. `POST /api/auth/sign-up/email` answers HTTP 500 with a zero-byte body. The server log carries: ``` [Better Auth]: The field "issuer" does not exist in the "account" Drizzle schema. # SERVER_ERROR: [BetterAuthError: The field "issuer" does not exist in the "account" Drizzle schema.] ``` The request writes the `user` row and then fails on the `account` row. The address is stuck after that: a second sign-up answers 422 `USER_ALREADY_EXISTS`, sign-in answers 401, and password reset answers 400 `RESET_PASSWORD_DISABLED` because the account that would hold the password does not exist. An upgraded install is worse. `sign-in/email` matches the credential account on `account.issuer === 'local:credential'`. Rows written before the upgrade have no issuer, so every existing user is locked out. **Expected behavior** `POST /api/auth/sign-up/email` answers 2xx and writes both the `user` row and its credential `account` row. `POST /api/auth/sign-in/email` then answers 2xx and sets a session cookie. An install that upgrades keeps its existing users. **Steps to reproduce** 1. Start a server from `master` with `PAPERCLIP_DEPLOYMENT_MODE=authenticated` against an empty database. 2. `curl -X POST http://127.0.0.1:<port>/api/auth/sign-up/email -H 'Content-Type: application/json' -H 'Origin: http://127.0.0.1:<port>' --data '{"name":"A","email":"a@example.com","password":"a-long-password"}'` 3. The response is HTTP 500 with an empty body. **Paperclip version or commit** `master` at |
||
|
|
dc7a1a020a |
fix(adapter-utils): skip the remote session close when the duplex channel is already lost (#12394)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - The adapter runtime settles each run through a duplex control
channel
> - A lost channel can leave the remote session-close call without a
usable peer
> - The call has no deadline, so run teardown can wait for the full
adapter timeout
> - This pull request skips that remote call after the runtime latches
channel loss
> - The benefit is faster run finalization while the local cleanup
effects remain
## Linked Issues or Issue Description
**What happened?**
The run teardown placed a remote session-close call over a duplex
control channel that the runtime had already latched as lost. The call
blocked until the adapter execution timeout released it.
**Expected behavior**
Run teardown should release the local warm handle and continue when the
duplex control channel has already failed.
**Steps to reproduce**
1. Start an adapter run with the duplex control channel.
2. Latch a channel-loss state before settlement.
3. Use a runtime whose close call never resolves.
4. Confirm that teardown returns without a remote close call.
**Paperclip version or commit**
Commit
|
||
|
|
17ebcc65b7 |
refactor(daytona): simplify the login session-home create (#12348)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Sandbox providers let agents run in remote environments > - The Daytona login flow creates a home directory for each login session > - The create path ran owner, mode, and link-type checks inside the sandbox > - These checks cannot protect the host because sandbox code can change the checked state > - This pull request uses one `mkdir -p` command and removes the unused helper scripts > - The benefit is a simpler login path with the host-side credential checks unchanged ## Linked Issues or Issue Description **What happened?** The Daytona login flow used helper scripts and inside-sandbox checks for the session-home directory. The standalone package build also copied a scripts directory that no longer existed after the helper scripts were removed. **Expected behavior** The login flow must create the session home with one `mkdir -p` command. The package build must complete without copying a removed directory. **Steps to reproduce** 1. Build the Daytona plugin package. 2. Start a Daytona device login. 3. Inspect the session-home create command and the package output. **Paperclip version or commit** Commit `dfdf5914ba37caa1e3bc380236844a7d76237e12`. **Deployment mode** Built from source. ## What Changed - Replace the session-home helper checks with one `mkdir -p` command. - Remove the two unused session-home helper scripts. - Remove the dead build copy steps for the deleted scripts directory. - Add coverage for a failed session-home create command. - Keep the host-side credential reader unchanged. - Keep the Kubernetes provider package unchanged. ## Verification - Package unit tests pass: 220 passed, 6 skipped. - Package typecheck passes. - The package build passes and emits 56 files in `dist`. - The roadmap check confirms that this change stays within the planned sandbox-provider work. - GitHub search found no open duplicate or related pull request. ## Risks The login flow no longer reports owner, mode, or link-type errors from inside the sandbox. Those checks did not protect the host. The host-side credential reader still uses no-follow path opens and accepts only a regular file with owner and exact mode `0600`. Risk is low because this change removes checks that cannot enforce the host security boundary. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. This pull request updates an existing sandbox-provider path, not a new core feature. ## Model Used OpenAI Codex, GPT-5. The runtime provides tool use and code execution. The runtime does not expose the context window size or a more specific model identifier. ## 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> |
||
|
|
3d9be6f7fe |
refactor(daytona): simplify the inbound file-sync path (#12329)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Sandbox providers run agent work in isolated environments > - The Daytona inbound file-sync path writes selected sandbox data to host paths > - Its in-sandbox lexical and realpath guards do not protect host-write or Paperclip API authority > - This pull request removes those guards and simplifies the inbound file-sync commands > - The benefit is a smaller path with the same outbound controls and host extraction validation ## Linked Issues or Issue Description No public issue exists for this change. This pull request describes the enhancement. **What existing behavior does this improve?** It improves inbound file and directory synchronization for the Daytona sandbox provider. **Subsystem affected** `packages/plugins` — the Daytona sandbox provider. **Current behavior** The inbound path checks lexical and realpath confinement inside the sandbox. It uses file-descriptor-pinned commands for file promotion, archive extraction, and decompression. These checks do not protect host-write or Paperclip API authority. **Proposed behavior** Remove the inbound lexical and realpath checks. Use `mv -f` for file mappings, `tar -xf` for directory mappings, and `zstd -d -o` for decompression. Keep outbound source checks, atomic snapshot downloads, and tarball member validation. **Reason and benefit** The sandbox boundary protects the relevant authorities. The removed guards run inside that boundary and only produce early errors. The simpler commands reduce code and preserve the controls that protect the host boundary. **Breaking changes** The inbound path no longer rejects mappings because of sandbox-side lexical or realpath confinement. Outbound source validation and tarball member validation remain unchanged. ## What Changed - Remove lexical and realpath confinement guards from inbound file mappings, inbound directory mappings, and post-upload command working directories. - Replace file-descriptor-pinned promotion with one `mv -f` command per file mapping. - Replace file-descriptor-pinned extraction with one `tar -xf` command per directory mapping. - Replace retained-descriptor decompression with `zstd -d -o`. - Keep outbound source guards, atomic snapshot-and-download, and tarball member validation. - Update Daytona tests for the new command shapes and remove tests for the removed rejections. ## Verification - The author ran the Daytona package test suite: 232 tests passed and 6 tests skipped. - The author ran the Daytona package typecheck successfully. - Review the diff and confirm it changes only the three Daytona files named in this description. - Confirm the Storybook check may report `SKIPPED` as an expected repository state. ## Risks The inbound path now trusts the sandbox boundary for host-write protection. A later change that gives sandbox code host-write or Paperclip API authority could require new guards. Outbound source checks and archive member validation remain in place. No Kubernetes or core runtime file changes exist. ## Model Used OpenAI GPT-5; exact model version and context window were not provided; tool use and code review assistance. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes: #` / `Refs: #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [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> |
||
|
|
036600d922 |
fix(db): close test database clients before the embedded Postgres cluster stops (#12335)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Paperclip uses database clients and embedded PostgreSQL test fixtures > - A fixture stopped its embedded PostgreSQL cluster while clients still held connections > - The postgres.js driver then scheduled a write on a stopped connection > - That write escaped the timer callback and caused a test process to exit with an error > - This pull request closes registered clients before the fixture stops its cluster > - The benefit is stable test teardown and clear failure reporting in continuous integration ## Linked Issues or Issue Description Refs: #10869 **What happened?** An embedded PostgreSQL test fixture stopped its cluster while database clients still held open connections. The postgres.js driver then scheduled a deferred write on a dead connection. The write caused an unhandled error after the test shard reported success. **Expected behavior** The fixture closes all live clients for its cluster before it stops the embedded PostgreSQL cluster. Tests then finish without a deferred write on a dead connection. **Steps to reproduce** 1. Run the database regression test with the embedded PostgreSQL fixture. 2. Stop the fixture while its database client still has an open connection. 3. Observe the deferred write and the process exit status. **Paperclip version or commit** Branch base: |
||
|
|
bdd8f1bedb |
Repair the drizzle snapshot so generate emits no spurious migration (#12333)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Paperclip keeps its state in PostgreSQL, and `packages/db` owns that schema through Drizzle > - `drizzle-kit generate` writes a new migration by diffing `packages/db/src/schema/` against the newest snapshot in `packages/db/src/migrations/meta/`, so the snapshot must describe the schema that the migrations produce > - Snapshot `0228` recorded the new `error_count` column on the wrong table, and snapshot `0229` inherited the error, so the newest snapshot no longer matched the schema > - Because of that, `generate` on `master` folded the drift into any new migration: it emitted an `ADD COLUMN` for a column that migration `0228` already creates, which fails on a fresh database, plus an out-of-scope `DROP COLUMN` > - This pull request moves the column entry to the correct table in both snapshots and adds a test that repeats the diff `generate` performs > - The benefit is that the next person who generates a migration gets only their own change, and CI fails if the snapshot drifts again ## Linked Issues or Issue Description No existing issue. The description below follows `.github/ISSUE_TEMPLATE/bug_report.yml`. **What happened?** `drizzle-kit generate` on `master` emits a wrong migration. The newest snapshot, `packages/db/src/migrations/meta/0229_snapshot.json`, disagrees with the schema in two places. It omits `issue_question_response_deliveries.error_count`, which `0228_nasty_grim_reaper.sql` creates. It also carries `decision_archive_notification_outbox.error_count`, which no migration ever creates and the Drizzle schema never declared. Snapshot `0228` introduced both halves of the error: it added the new `error_count` column to `decision_archive_notification_outbox` instead of the table that the same migration creates. Snapshot `0229` copied it forward. Any new migration therefore starts with two statements that do not belong to it: ```sql ALTER TABLE "issue_question_response_deliveries" ADD COLUMN "error_count" integer DEFAULT 0 NOT NULL; ALTER TABLE "decision_archive_notification_outbox" DROP COLUMN "error_count"; ``` The `ADD COLUMN` fails on a fresh database, because migration `0228` already creates that column. The `DROP COLUMN` targets a column that does not exist on any deployment. **Expected behavior** `drizzle-kit generate` reports "No schema changes, nothing to migrate" on a clean checkout of `master`, and a new migration contains only the author's own schema change. **Steps to reproduce** 1. Check out `master` at commit `bc1a21564`. 2. Run `pnpm install`. 3. Run `pnpm --filter @paperclipai/db generate`. 4. Read the emitted `packages/db/src/migrations/0230_*.sql`. It contains the two statements above, and no schema file was changed. **Paperclip version or commit** `master` at `bc1a21564`. The drift entered in #12307 (snapshot `0228`) and was carried forward by #12291 (snapshot `0229`), which worked around it by building its snapshot by hand. **Deployment mode** Not deployment specific. It affects anyone who generates a migration, and it affects any fresh database that would later run the bad migration. **Database mode** All PostgreSQL modes: embedded, local Docker, and hosted. ## What Changed - Moved the `error_count` column entry from `decision_archive_notification_outbox` to `issue_question_response_deliveries` in `packages/db/src/migrations/meta/0228_snapshot.json` and `packages/db/src/migrations/meta/0229_snapshot.json`. Both files keep their `id` and `prevId`, so the snapshot chain is unchanged. - Added `packages/db/src/migration-snapshot-drift.test.ts`. It reads the newest snapshot named by `_journal.json`, serializes the schema modules with `generateDrizzleJson`, and asserts that `generateMigration` returns no statements. This is the same diff that `generate` performs. - Documented the snapshot rule in `doc/DATABASE.md` under a new "Migration snapshots" section. No migration SQL was added, renumbered, or edited. No schema file changed. The database is correct as it is; only the snapshot was wrong. Why both snapshots and not only the newest one: `0229` is the file that `generate` reads, so repairing it is what fixes the bug. `0228` holds the same error, and `drizzle-kit drop` removes the last migration and its snapshot, which would promote `0228` back to newest and bring the drift back. Repairing both removes that trap. Snapshots are never applied to a database, so neither edit changes any deployment. ## Verification Commands run from the repository root. - `pnpm --filter @paperclipai/db generate` — "No schema changes, nothing to migrate 😴". It writes no SQL file, no snapshot, and no journal entry. `git status` stays clean. Before the fix, the same command wrote `0230_fast_caretaker.sql` with the two spurious statements. - The repaired `0229_snapshot.json` is byte-identical to the snapshot that a real `generate` run produced, except for the `id` and `prevId` that keep the chain intact. - Chain check: the repaired `0228` and `0229` snapshots now differ by exactly the two columns that `0229_drop_company_brand_color_and_attachment_max_bytes.sql` drops, `companies.brand_color` and `companies.attachment_max_bytes`, and by nothing else. - Database check: applied all 229 migrations in order to an embedded PostgreSQL, then compared the live schema with the repaired snapshot. 179 tables and 2687 columns match, with no missing column, no extra column, and no nullability difference. The same comparison against the pre-fix snapshot reports exactly two problems: `column only in snapshot: decision_archive_notification_outbox.error_count` and `column only in database: issue_question_response_deliveries.error_count`. This harness was a scratch script and is not part of the pull request. - `pnpm --filter @paperclipai/db typecheck` — pass. It runs `check:migrations`, which is `check-migration-numbering` and `check-migration-safety`. - `npx vitest run --root packages/db` — 28 files, 102 tests, all pass. This includes the new test. - New test, negative case: with the pre-fix `0229_snapshot.json` restored, `migration-snapshot-drift.test.ts` fails and prints exactly the two spurious statements, plus the instruction to run `generate`. It passes on the repaired snapshot. It takes about 1.2 seconds and needs no database. - `node scripts/check-forbidden-tokens.mjs` and `node scripts/check-no-git-push.mjs` — pass. ## Risks Low risk. A Drizzle snapshot is a build-time record for `drizzle-kit generate`. It is never applied to a database, so this change cannot alter any deployment, and no operator action is needed. Databases that already ran migrations `0228` and `0229` are correct today and stay correct. The proof is a clean `generate`: the command that produced the wrong migration now reports "No schema changes, nothing to migrate" and writes nothing. Two smaller notes: - The new test depends on `drizzle-kit/api`, which is already a dev dependency of `packages/db`. If a future `drizzle-kit` upgrade changes that surface, the test fails loudly at import rather than passing silently. - The test imports every module in `packages/db/src/schema/`, which is the same set that `drizzle.config.ts` points the CLI at. It deduplicates by object identity, because the barrel re-exports the same table objects and `drizzle-kit` rejects a table it sees twice. ## Model Used Claude (Anthropic), Claude Opus, agentic tool use via Claude Code. ## 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 |
||
|
|
bc1a21564f |
Remove the company brand color and per-company attachment limit (#12291)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - A company is the top-level container, and the company General page
holds its settings
> - Two of those settings did almost nothing: the brand color only
tinted the generated company icon, and the attachment size limit sat
under the deployment-level `PAPERCLIP_ATTACHMENT_MAX_BYTES` cap that
already bounded every upload
> - A setting that changes one icon hue, and a setting that can only
lower a limit the operator already set, are not worth the page space or
the code that carries them
> - This pull request deletes both settings from the UI, the validators,
the API contract, the server, and the database
> - With the deployment cap as the only limit left, the message a person
sees when an upload is rejected has to name that limit in terms they can
act on, so the raw byte count becomes a human-readable size
> - The benefit is a shorter company General page for every deployment,
one attachment limit instead of two, and less code between an upload and
its ceiling
## Linked Issues or Issue Description
No existing issue. The description below follows
`.github/ISSUE_TEMPLATE/enhancement.yml`.
**What existing behavior does this improve?**
The company General page (`/company/settings`), the `PATCH
/api/companies/{companyId}` and `PATCH
/api/companies/{companyId}/branding` request contracts, and the
attachment upload limit on task, case, and company-import uploads.
**Subsystem affected**
Cross-cutting: `ui/`, `server/`, `packages/shared`, `packages/db`.
**Current behavior**
The company General page shows an "Appearance" section with three
controls: Logo, Brand color, and Attachment size limit. The brand color
is a hex value that feeds one thing — the hue of the generated company
pattern icon. Companies that never set one already get a hue derived
from the company name. The attachment size limit is a per-company byte
count stored on `companies.attachment_max_bytes`. Every upload path
clamps it against the deployment-level `PAPERCLIP_ATTACHMENT_MAX_BYTES`
cap, so the per-company value can only lower a limit the operator
already chose.
**Proposed behavior**
The Appearance section keeps the Logo control only. The company pattern
icon always derives its hue from the company name. Every attachment path
reads the deployment cap directly, so `PAPERCLIP_ATTACHMENT_MAX_BYTES`
is the single limit. An upload rejected by that limit says so in human
units — "File is larger than the 10 MB limit" rather than a raw byte
count. The `companies.brand_color` and `companies.attachment_max_bytes`
columns are dropped, and both fields leave the company API contract.
**Reason and benefit**
Both settings ask an operator to make a decision that changes almost
nothing. The brand color moves one icon hue on a page that also lets you
upload a real logo, which overrides the icon entirely. The attachment
limit reads as a real control but cannot raise anything, so it is a
second place to look when an upload is rejected. Removing both shortens
the page every deployment sees, removes a company-scoped read from the
task attachment upload path, and leaves one attachment limit to reason
about instead of two.
**Breaking changes**
The company API responses no longer include `brandColor` or
`attachmentMaxBytes`, and `GET /api/invites/{token}` no longer includes
`companyBrandColor`. `PATCH /api/companies/{companyId}/branding` is
strict, so a request that sends `brandColor` now returns 400; the
non-strict `PATCH /api/companies/{companyId}` schema strips it. Company
packages exported by older versions still import: the portability
company manifest schema is non-strict, so the retired keys are stripped
and ignored rather than rejected. Companies that stored a brand color
lose it — their icon reverts to the name-derived hue that every company
without a color already used.
## What Changed
- Removed the "Brand color" and "Attachment size limit" fields from the
company General page, along with their state, dirty checks, save
payload, and Save-button gating.
- Removed `brandColor` and `attachmentMaxBytes` from
`createCompanySchema`, `updateCompanySchema`, and
`updateCompanyBrandingSchema`, and deleted the now-orphaned
`DEFAULT_COMPANY_ATTACHMENT_MAX_BYTES` and
`MAX_COMPANY_ATTACHMENT_MAX_BYTES` constants.
- Removed both fields from the `Company` type, the portability manifest
type and schema, and the `companiesApi.update` payload allowlist.
- Dropped `brandColor` from `CompanyPatternIcon` and its callers, so the
icon hue always comes from the company name. Deleted the now-unused
`hexToHue` helper and the now-unused `pickTextColorForSolidBg` export.
- Stopped emitting `brandColor` from the company service selection and
from the invite-summary and invite-branding payloads in
`server/src/routes/access.ts`.
- Replaced `normalizeIssueAttachmentMaxBytes` with the deployment cap:
task attachments, case attachments, and company import now use
`MAX_ATTACHMENT_BYTES` directly. The helper is deleted.
- Added `formatAttachmentSize()` next to `MAX_ATTACHMENT_BYTES` and
routed every over-limit message through it, so a rejected upload names
the limit in human units instead of raw bytes: `Image exceeds 10485760
bytes` becomes `Image is larger than the 10 MB limit`. Enforcement is
unchanged — the same single cap, the same multer limits, the same status
codes and response shapes.
- Added migration
`0229_drop_company_brand_color_and_attachment_max_bytes.sql` and removed
both columns from the Drizzle `companies` schema.
- Kept legacy imports working: the portability company manifest schema
is non-strict, so older packages carrying the retired keys still import
with the keys ignored.
- Updated the skill API reference and the implementation spec, and
pruned the token-extraction allowlist entries that the removed code made
stale.
## Verification
Commands run from the repository root:
- `pnpm --filter @paperclipai/shared typecheck` — pass
- `pnpm --filter @paperclipai/db typecheck` — pass (includes
`check:migrations`, which validates the new migration number and journal
entry)
- `pnpm --filter @paperclipai/ui typecheck` — pass
- server typecheck via `node_modules/.bin/tsc --noEmit` in `server/` —
pass. `pnpm --filter @paperclipai/server typecheck` could not run
locally because it builds the Rust runner first and `cargo` is not
installed on this machine; the TypeScript step it wraps is the command
above.
- `npx vitest run packages/shared/src/validators/company.test.ts` — 6
passed
- `npx vitest run server/src/__tests__/company-portability.test.ts` — 90
passed
- `npx vitest run server/src/__tests__/attachment-types.test.ts
server/src/__tests__/assets.test.ts
server/src/__tests__/issue-attachment-routes.test.ts
server/src/__tests__/company-portability.test.ts
server/src/__tests__/cases-routes.test.ts` — 165 passed (the
human-readable limit messages)
- `npx vitest run server/src/__tests__/company-branding-route.test.ts
server/src/__tests__/issue-attachment-routes.test.ts
server/src/__tests__/invite-summary-route.test.ts
server/src/__tests__/openclaw-invite-prompt-route.test.ts
server/src/__tests__/companies-route-cross-company-authz.test.ts` — all
passed
- `npx vitest run cli/src/__tests__/company.test.ts
cli/src/__tests__/company-delete.test.ts` — 27 passed
- `npx vitest run` in `ui/` — 4425 passed, 1 pre-existing failure
unrelated to this change (`OnboardingWizard.test.tsx` "renders instead
of throwing when the browser denies storage access", which also fails on
`master`)
- `npx vitest run` in `server/` — see the note below
- `node scripts/check-token-gates.mjs` — no new violations; the only
reported violations are the pre-existing `PillGuy.tsx` ones present on
`master`
New tests added:
- `packages/shared/src/validators/company.test.ts` — the create and
update schemas strip the retired keys, the strict branding schema
rejects `brandColor`, and the portability manifest schema accepts a
legacy entry carrying both keys and drops them.
- `server/src/__tests__/company-branding-route.test.ts` — `PATCH
/api/companies/{companyId}/branding` returns 400 for `brandColor` and
does not call the company service.
- `server/src/__tests__/company-portability.test.ts` — a legacy package
that declares `brandColor` and `attachmentMaxBytes` imports
successfully, and neither key reaches `companies.create`.
- `server/src/__tests__/issue-attachment-routes.test.ts` — the effective
task attachment limit is the deployment cap, and the route no longer
loads the company to size an upload.
- `server/src/__tests__/attachment-types.test.ts` —
`formatAttachmentSize()` renders the default cap as `10 MB`, keeps one
decimal place for fractional sizes and drops a trailing `.0`, falls back
to KB and bytes for small caps, steps up to GB, and never emits `NaN`
for a degenerate input.
- `server/src/__tests__/assets.test.ts` — the asset-image and
company-logo routes both return the human-readable limit message on an
over-cap upload.
## Merge with master
`master` moved while this was open, and the merge needed two
resolutions:
- **`ui/src/pages/CompanySettings.tsx`.** #12243 reworded the
user-facing
copy from "company" to "organization", and that rewording landed inside
the "Brand color" and "Attachment size limit" hints — the two fields
this change deletes. Both fields are removed, so the conflicted block is
dropped whole. The Logo field and every other copy change from #12243
are
kept.
- **Migration renumbered 0228 -> 0229.** #12307 landed
`0228_nasty_grim_reaper`, so this migration is now
`0229_drop_company_brand_color_and_attachment_max_bytes`. Its snapshot
is
rebuilt from master's `0228_snapshot.json` with only the two `companies`
columns removed, and `meta/_journal.json` is master's journal plus a
single `idx: 229` entry. `pnpm --filter @paperclipai/db
check:migrations`
passes.
The snapshot was rebuilt by hand rather than taken from `drizzle-kit
generate`, because master's `0228_snapshot.json` has drifted from
master's
own schema: `issue_question_response_deliveries.error_count` is created
by
master's 0228 SQL but missing from its snapshot, and the snapshot still
carries `decision_archive_notification_outbox.error_count`. Regenerating
folds both into this migration, and the resulting `ADD COLUMN
error_count`
would fail on a fresh database where master's 0228 already created that
column. Rebuilding from master's snapshot leaves that drift exactly
where
it is and keeps this migration to the two column drops. The drift is
pre-existing on master and is not addressed here.
## Risks
- **The migration is a destructive column drop.**
`0229_drop_company_brand_color_and_attachment_max_bytes.sql` removes
`companies.brand_color` and `companies.attachment_max_bytes`. It is safe
because both features are removed in the same change and nothing reads
either column after it. The statements use `DROP COLUMN IF EXISTS`,
matching the convention of the recent drop migrations in this
repository. The drop is not reversible: a downgrade after this migration
loses any stored values.
- **Stored brand colors are lost.** A company that had set a color now
renders the name-derived icon hue that every company without a color
already used. No other surface changes, and an uploaded logo still
overrides the icon.
- **API response shape narrows.** `brandColor` and `attachmentMaxBytes`
leave the company payloads, and `companyBrandColor` leaves the invite
summary payload. A client reading those fields now sees `undefined`. The
bundled UI and CLI are updated in this change.
- **Legacy imports are covered.** Packages exported by older versions
still carry both keys. The manifest schema is non-strict, so the keys
are stripped rather than rejected, and a test locks that in.
- **The over-limit message strings changed.** Anything matching on the
old `... exceeds N bytes` text — a test, a script, or a client that
string-matches `body.error` — needs updating. The status codes (422) and
response shapes are unchanged, so structured clients are unaffected.
- **Attachment limits can only widen.** A deployment that had lowered a
company below the deployment cap now allows uploads up to the cap for
that company. Lower `PAPERCLIP_ATTACHMENT_MAX_BYTES` if a smaller
ceiling is needed.
- **Storybook visual baselines shift** for the `CompanyPatternIcon`
matrix story, because those fixtures had brand colors. That workflow
runs only on a PR labeled `storybook-visual`, so it does not gate this
PR; regenerate the baselines if the label is added.
## Model Used
Claude (Anthropic), Claude Opus, agentic tool use via Claude Code.
## 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
|
||
|
|
7551b63ef2 |
Remove the instance Heartbeats settings page (#12282)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Instance settings collect deployment-wide controls; one of them was the Heartbeats page, an instance-wide list of scheduler heartbeat agents with enable/disable toggles > - The same controls live on each agent's own configuration surface, so the standalone list duplicates them, and its framing no longer matches how heartbeat agents are managed > - Keeping a settings view that no longer makes sense costs every deployment navigation noise and maintenance > - This pull request removes the page, its route, its navigation entries, and its hidden-settings key for all deployments > - The benefit is a smaller, coherent settings surface, with operator hidden-settings lists that still mention the retired key continuing to work unchanged ## Linked Issues or Issue Description No public issue exists; describing the issue inline per the enhancement template: **What existing behavior does this improve?** The instance settings surface — specifically the Settings → Heartbeats page, which listed scheduler heartbeat agents instance-wide with enable/disable toggles. The view no longer makes sense as a standalone settings page: the same controls are available on each agent's configuration surface, and the instance-wide list framing does not match how heartbeat agents are managed. **Subsystem affected** Cross-cutting: `ui/` (page, route, navigation), `packages/shared` (settings-visibility registry), docs. **Current behavior** The page renders at `/company/settings/instance/heartbeats`, appears in the settings sidebar and tab bar, and is hideable by hosting operators via the `instance.heartbeats` key of `PAPERCLIP_HIDDEN_SETTINGS`. **Proposed behavior** The page, route, and navigation entries are removed for every deployment. The `instance.heartbeats` registry key is retired; operator lists that still send it are logged and ignored, so mixed-version fleets keep working. Remembered settings paths pointing at the old page remap to the settings root. Heartbeat APIs are unchanged. **Reason and benefit** A smaller, coherent settings surface with no duplicated controls; less navigation noise and maintenance for every deployment. **Breaking changes** None functional. Bookmarks and remembered paths to the removed page land on the settings root; `PAPERCLIP_HIDDEN_SETTINGS` lists that still include `instance.heartbeats` log a warning and are otherwise honored unchanged. ## What Changed - Deleted `ui/src/pages/InstanceSettings.tsx` (the Heartbeats view) and its route in `ui/src/App.tsx`. - Removed the sidebar entry (`CompanySettingsSidebar`) and tab-bar item (`CompanySettingsNav`). - Removed `"/heartbeats"` from the remembered-settings-path allowlist; remembered heartbeats paths now remap to the settings root. - Retired the `instance.heartbeats` key from the shared settings-visibility registry and the environment-variables doc; documented that retired keys are ignored with a warning. - Dropped the now-unused UI client wrapper for the instance scheduler-agent list (`heartbeatsApi.listInstanceSchedulerAgents`); the server endpoint stays. - Removed the unused `schedulerHeartbeats` query key. ## Verification - `npx vitest run packages/shared/src/settings-visibility.test.ts ui/src/lib/instance-settings.test.ts ui/src/components/CompanySettingsSidebar.test.tsx ui/src/components/access/CompanySettingsNav.test.tsx` — 24 tests passing. - Full `ui` vitest suite: 4426 tests, 4 failures — all in files this PR does not touch; 3 were load-induced timeouts that pass on rerun, and `OnboardingWizard.test.tsx` "renders instead of throwing when the browser denies storage access" fails identically on a clean master checkout (pre-existing). - `pnpm --filter @paperclipai/ui typecheck` and `pnpm --filter @paperclipai/shared typecheck` — clean. - Merged `master` to clear a conflict (see below) and re-ran the four focused suites (24 passing), `ui/src/App.test.tsx` and `ui/src/plugins/bridge.test.ts` (22 passing), and both typechecks — all clean. Full CI is green on the merge commit. ## Merge With master `master` gained the `company` → `organization` copy pass (#12243), which reworded strings inside `ui/src/pages/InstanceSettings.tsx` — the page this branch deletes — producing a modify/delete conflict. Resolved by keeping the deletion: the page is going away, so the rewording of its copy has nothing to apply to. Every other file merged cleanly, and `master`'s rewording in `App.tsx`, `App.test.tsx`, and `CompanySettingsSidebar.tsx` sits away from this branch's structural removals, so both changes survive. The net diff against `master` is unchanged from the pre-merge review: the same 13 files, 23 insertions, 330 deletions. ## Risks - Low. Pure removal of a UI surface; heartbeat data and APIs are untouched. Operators still listing `instance.heartbeats` in `PAPERCLIP_HIDDEN_SETTINGS` get a warning log and otherwise unchanged behavior (covered by the registry's unknown-key handling). Bookmarks and remembered paths to the old page land on the settings root. ## Model Used Claude (Anthropic), model id `claude-fable-5`, extended thinking, agentic tool use via Claude Code. ## 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 |
||
|
|
8f195c2f49 |
Let operators supply defaults for selected instance settings (#12285)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - Hosting operators (a managed cloud, an internal shared server) tune
the settings surface with `PAPERCLIP_HIDDEN_SETTINGS`, but hiding a
control never changes its value
> - An instance whose stored feedback-sharing preference is still the
schema default ("prompt") keeps prompting users even when the operator
hid the control, leaving them no way to answer
> - More generally, operators have no supported way to change what a
setting defaults to without patching code
> - This pull request adds `PAPERCLIP_SETTING_DEFAULTS`, a generic
operator-supplied read-time default overlay for registry-listed general
settings
> - The benefit is that any hosting operator can pair "hide the control"
with "default the value", while explicit user choices and self-hosted
stock behavior stay untouched
## Linked Issues or Issue Description
No public issue exists; following the enhancement template:
**What existing behavior does this improve?**
Hosting operators need to supply the default value of selected instance
settings (first: `feedbackDataSharingPreference`) via configuration,
without patching code and without a hard-coded, opinionated constant in
the product.
**Subsystem affected**
Server (instance-settings service, feedback service, boot) and
`packages/shared` (settings schemas).
**Current behavior**
Setting defaults are fixed in the shared zod schemas.
`PAPERCLIP_HIDDEN_SETTINGS` can hide the feedback-sharing control and
floor writes, but the stored value stays "prompt", so issue-chat
surfaces keep prompting with no way to answer.
**Proposed behavior**
`PAPERCLIP_SETTING_DEFAULTS` takes a JSON object validated against a
shared registry of defaultable fields. The operator value substitutes
for the schema default at read time: a field whose effective value is
still the schema default resolves to the operator value; an explicit
non-default user choice always wins. Never persisted; unsetting the
variable restores stock behavior. Malformed JSON or an invalid value for
a known field refuses startup (fail closed); unknown field names warn
and are ignored (mixed-version fleet safe).
**Reason and benefit**
Any hosting operator can pair "hide the control" with "default the
value" without forking the product. Explicit user choices and
self-hosted stock behavior stay untouched.
**Breaking changes**
None. With the variable unset, every read path is byte-identical to
before.
## What Changed
- New `packages/shared/src/setting-defaults.ts`:
`SETTING_DEFAULTS_ENV_KEY`, `DEFAULTABLE_GENERAL_SETTINGS` registry
(currently `feedbackDataSharingPreference`), `parseSettingDefaults`
(fail-closed for policy content, warn-ignore unknown fields),
`applyOperatorGeneralDefaults` (pure read-time overlay),
`stripOperatorGeneralEchoes` (persist-time echo strip, see below),
re-exported from the package index.
- New `server/src/services/setting-defaults.ts`: parse-once accessor
mirroring `settings-visibility.ts`.
- `server/src/services/instance-settings.ts`: `toGeneralView` applies
the overlay in `get`/`getGeneral`/update responses; persisted writes
never carry operator values. Because general-settings writes materialize
every field, a stored schema-default value is treated as unchosen —
deliberate, documented, and covered by tests.
- `server/src/services/feedback.ts`: the preference-persistence branch
now checks the effective (overlaid) preference, so a stray prompt answer
cannot overwrite an operator default; its local normalize fallback now
returns full schema defaults.
- `server/src/index.ts`: boot-time fail-fast parse with a log line
naming the defaulted settings, mirroring the managed-config posture.
- The hidden-settings write floor (`assertNoHiddenSettingChanges`) keeps
comparing against effective values, so clients echoing a full GET
response keep working. To keep the overlay strictly read-time,
`updateGeneral` strips such echoes at persist time: a write of the
operator value over a field whose stored value is still the schema
default (unchosen) maps back to the schema default, so an echo cannot
promote the operator value into an explicit stored choice and later
changes to (or removal of) `PAPERCLIP_SETTING_DEFAULTS` still take
effect. A write of any other value, or over an explicit stored choice,
persists as given.
- Docs: `PAPERCLIP_SETTING_DEFAULTS` row + "Operator setting defaults"
section in `docs/deploy/environment-variables.md`.
- Tests: `packages/shared/src/setting-defaults.test.ts` (parse matrix,
overlay precedence, echo-strip matrix, immutability) and
`server/src/__tests__/instance-settings-operator-defaults.test.ts`
(accessor, substitution, explicit-choice wins, unset identity,
never-persisted, full-GET echo stays unchosen, explicit non-default
write persists).
## Verification
- `npx vitest run packages/shared/src/setting-defaults.test.ts
server/src/__tests__/instance-settings-operator-defaults.test.ts
server/src/__tests__/instance-settings-managed-overlay.test.ts` — 33
tests passing.
- `npx vitest run server/src/__tests__/instance-settings-routes.test.ts
server/src/__tests__/instance-settings-service.test.ts` — 57 passing;
`npx vitest run server/src/__tests__/feedback-service.test.ts
server/src/__tests__/issue-feedback-routes.test.ts` — 18 passing.
- `pnpm --filter @paperclipai/shared typecheck` and `pnpm --filter
@paperclipai/server typecheck` — clean.
## Risks
- Low. With the variable unset every read path is byte-identical to
before (identity overlay, covered by tests). The overlay is read-time
only and never persisted, so no migration and no data risk. Fail-closed
parsing means a bad policy value is a loud boot failure rather than
silent drift — consistent with the existing managed-config contract.
## Model Used
Claude (Anthropic), model id `claude-fable-5`, extended thinking,
agentic tool use via Claude Code.
## 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
|
||
|
|
e34ed9801b |
Let operators hide the Provider vaults and Proposals tabs (#12284)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Hosting operators (a managed cloud, an internal shared server) tune the settings surface with `PAPERCLIP_HIDDEN_SETTINGS`, which today hides whole pages > - The Secrets page bundles four tabs, and two of them — Provider vaults and Proposals — do not apply to deployments where the operator provisions provider credentials itself > - Hiding the whole Secrets page is too coarse: the Secrets and My secrets tabs stay essential everywhere > - This pull request adds per-tab visibility keys (`company.secrets.vaults`, `company.secrets.proposals`) as a new company-section registry group > - The benefit is that any hosting operator can trim the Secrets page to what fits their deployment, with self-hosted behavior unchanged by default ## Linked Issues or Issue Description No public issue exists; following the enhancement template: **What existing behavior does this improve?** `PAPERCLIP_HIDDEN_SETTINGS` can hide the whole Secrets page (`company.secrets`) but not individual tabs. Operators of managed deployments need to hide the Provider vaults and Proposals tabs while keeping the rest of the page. **Subsystem affected** Settings visibility (`packages/shared/src/settings-visibility.ts`) and the Secrets page UI (`ui/src/pages/Secrets.tsx`). **Current behavior** The Secrets page always renders all four tabs (Secrets, My secrets, Provider vaults, Proposals), polls pending proposals for the badge, and offers "manage vaults" affordances that jump to the vaults tab. **Proposed behavior** Two new registry keys, `company.secrets.vaults` and `company.secrets.proposals`, hide the corresponding tab: the tab-bar entry disappears, an active hidden tab snaps back to Secrets, the manage-vaults affordances are suppressed, and the pending-proposals poll stops. UI visibility only — the provider-config and proposal APIs stay live for agents and integrations, matching the existing `company.*` precedent. Nothing changes when the variable is unset. **Reason and benefit** Any hosting operator (a managed cloud, an internal shared server) can trim the Secrets page to what fits their deployment — for example when the operator provisions provider credentials itself, so the vault and proposal flows do not apply — without losing the Secrets and My secrets tabs, which stay essential everywhere. **Breaking changes** None. With `PAPERCLIP_HIDDEN_SETTINGS` unset (or set to existing keys only) nothing changes; older app versions receiving the new keys ignore them with a warning by design. ## What Changed - `packages/shared/src/settings-visibility.ts`: new `HIDEABLE_COMPANY_SECTIONS` group (`company.secrets.vaults`, `company.secrets.proposals`), `HideableCompanySection` type, `hidesCompanySection()` helper, wired into `HideableSettingKey` / `HIDEABLE_SETTING_KEYS`, re-exported from the package index. - `ui/src/pages/Secrets.tsx`: tab-bar filtering, hidden-tab snap-back effect, gated pending-proposals query, conditional `onManageVaults` on both the import button and dialog (the button's "AWS vault disabled — manage" affordance renders nothing when vaults are hidden), hidden `TabsContent` blocks. - Docs: new bullet in `docs/deploy/environment-variables.md` under "Hiding settings surfaces". - Tests: registry membership/parse cases in `settings-visibility.test.ts`; new render cases in `Secrets.render.test.tsx` (hidden tabs absent + proposals poll skipped; default render keeps both tabs and the poll). ## Verification - `npx vitest run packages/shared/src/settings-visibility.test.ts ui/src/pages/Secrets.render.test.tsx` — 43 tests passing. - `pnpm --filter @paperclipai/shared typecheck` and `pnpm --filter @paperclipai/ui typecheck` — clean. ## Risks - Low. Nothing changes with `PAPERCLIP_HIDDEN_SETTINGS` unset (covered by the default-render test). The keys are UI-visibility only, so agent/integration API access is unaffected. Older app versions receiving the new keys ignore them with a warning by design. ## Model Used Claude (Anthropic), model id `claude-fable-5`, extended thinking, agentic tool use via Claude Code. ## 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 |
||
|
|
325041cb00 |
fix(assets): accept identity-provider characters in image upload namespaces (#12288)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - Humans oversee those agents in teams, so each person has a login and
a profile with an avatar
> - Avatars, logos and pasted images all go to one asset upload API,
which files each object under a namespace
> - The avatar namespace embeds the user id, and a deployment can take
user ids from an external identity layer, where a subject often holds
":", "|", "." or "@"
> - But the namespace validator accepted only letters, numbers, "/", "_"
and "-", so those users got a 400 "Invalid image metadata" error and
could not set a profile photo
> - This pull request widens the accepted characters, rejects "." and
".." path segments with a clear message, and cleans the namespace in the
upload client
> - The benefit is that profile photo upload works for every user, and a
namespace the API refuses now returns a message that says what is wrong
## Linked Issues or Issue Description
No existing issue or open pull request covers this. I searched the issue
and pull request lists for "avatar upload", "profile photo", "Invalid
image metadata" and "asset namespace" and found no duplicate. The bug
report follows.
**What happened?**
Profile photo upload fails. `ui/src/pages/ProfileSettings.tsx` sends the
namespace `profiles/${user.id}` to `POST
/api/companies/:companyId/assets/images`. When the user id comes from an
external identity layer it can contain ":", "|", "." or "@" — for
example `oidc:example|jane.example@example.com`.
`createAssetImageMetadataSchema` in
`packages/shared/src/validators/asset.ts` accepted only
`/^[a-zA-Z0-9\/_-]+$/`, so the route returned 400 "Invalid image
metadata" (`server/src/routes/assets.ts`). The image bytes were never
the problem, but the message pointed at the image, so the toast gave the
user nothing to act on.
A second case has the same cause. The agent instructions editor in
`ui/src/pages/AgentDetail.tsx` builds a namespace that ends with a
filename, such as `agents/<id>/instructions/SKILL.md`. The "." in the
filename also failed the check.
**Expected behavior**
A profile photo uploads for any user id the app itself issues, and an
image pasted into the agent instructions editor uploads for any
instruction filename. A namespace the API does refuse returns a message
that names the field and states the rule.
**Steps to reproduce**
1. Run Paperclip with an external identity provider, so `user.id` holds
an OIDC subject such as `oidc:example|jane.example@example.com`.
2. Open Settings, then Profile.
3. Choose an avatar image.
4. The upload fails and the page shows "Invalid image metadata".
Or, with no identity provider:
1. Open an agent, then the instructions editor, and select a file whose
name contains a "." such as `SKILL.md`.
2. Paste an image into the editor.
3. The upload fails with the same error.
**Paperclip version or commit**
`master` at
|
||
|
|
b06034d762 |
Write mode-constrained inbound files directly to their target (#12320)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Adapter utilities transfer files between the host and an agent environment > - A sandbox target already provides the security boundary for inbound files > - The generic fallback adds a temporary file and a rename that do not add protection inside that boundary > - This pull request writes a mode-constrained inbound file directly to its target and applies the mode after the write > - The benefit is a simpler transfer path while host targets keep the strict pre-write mode rule ## Linked Issues or Issue Description **What existing behavior does this improve?** The inbound file-sync fallback for a mode-constrained file stages the file under a temporary name, applies the mode, and renames the file into place. **Subsystem affected** `packages/adapter-utils` and `packages/plugins`. **Current behavior** A sandbox target uses a temporary path before it receives the file. The host then changes the mode and renames the file to the target path. **Proposed behavior** A sandbox target receives the file at its target path. The host applies the mode after the write. A host target still applies the mode before the first byte. **Reason and benefit** The sandbox boundary already protects the target. The direct write removes an unnecessary staging path and rename. **Breaking changes** None. The directory path and outbound transfer path keep their existing behavior. ## What Changed - Write a mode-constrained single-file inbound transfer directly to the sandbox target. - Apply the mode after the direct write and keep the confinement check before post-upload commands. - Scope the protocol comment by transfer direction and preserve the strict host-target rule. - Keep directory inbound transfers and outbound transfers unchanged. ## Verification - Run the targeted unit suite for the changed package. - Verify the suite covers direct target writes, post-write mode application, and confinement rejection. - Run `tsc --noEmit` for both changed packages. - Review the full GitHub Actions check set after the PR opens. ## Risks - A sandbox provider that assumes a temporary inbound path could expose a behavior mismatch. - The confinement check remains before post-upload commands, which limits escape risk. - Host targets keep the pre-write mode rule, so host permission behavior does not change. ## Model Used OpenAI GPT-5. This model assisted with Git operations, PR preparation, review coordination, and tool use. Context window size and reasoning mode are not exposed by the runtime. ## 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> |
||
|
|
67f9867bc6 |
fix(interactions): deliver question answers durably (#12307)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agents can pause a task and ask the user structured questions. > - The answer is durable in the issue interaction, but delivery to the next run is not durable. > - A process restart can therefore leave an answered interaction without a continuation attempt. > - Native runners also need a provider-neutral question contract before the task page can consume native events safely. > - This pull request adds a content-free delivery outbox and an optional native steering seam. > - Direct adapters keep their existing heartbeat continuation path. > - The benefit is reliable answer delivery without changing runtime selection or task-page behavior. ## Linked Issues or Issue Description Refs #12202. This pull request replaces the question-delivery foundation from that stale task-thread pull request. The task-thread projection will follow in a smaller pull request. **What happened?** Question answers were stored in the issue interaction. The server then made one in-memory continuation wake. A server stop between those operations could leave the answer stored but not delivered. The combined native task-thread pull request also made this behavior hard to review separately from UI changes. **Expected behavior** The answer and its delivery receipt must commit in one transaction. The server must retry pending receipts after a restart. Existing direct adapters must keep the current wake path. A native runtime may use the optional steering seam, but this pull request does not enable native steering in production. **Steps to reproduce** 1. Create an `ask_user_questions` interaction. 2. Answer the interaction. 3. Stop the server before the continuation wake completes. 4. Start the server again. 5. On current master, no durable record tells the server to retry the answer delivery. **Paperclip version or commit** Current `master` at `4d82f5eae`. ## What Changed - Add the `issue_question_response_deliveries` table and migration. - Store only routing state, a correlation ID, and a payload digest in the delivery row. The answer remains in the existing interaction result. - Commit an answered interaction and its pending delivery row in one transaction. - Add bounded claims, retry recovery, cumulative terminal state, and content-free activity records. - Keep every built-in direct adapter and external adapter on the existing heartbeat wake path. - Add an optional native steering seam. No production caller supplies that seam in this pull request. - Retain the provider-neutral `paperclip.question_set.v1` presentation on recovered interactions. - Run delivery immediately after an answer and sweep pending rows at startup and on the existing server interval. - Add focused database, service, route, startup, adapter-matrix, digest, and duplicate-delivery tests. ## Compatibility Boundary - This pull request does not change adapter selection. - This pull request does not start runnerd. - This pull request does not create native run records. - Direct adapters never call the native steering seam. - The existing interaction result stays authoritative for answer content. - The migration is additive and does not rewrite existing rows. - This pull request has no UI, dependency, workflow, package-manager, or lockfile changes. - The diff has 19 files. ## Verification - `pnpm exec vitest run server/src/__tests__/question-response-delivery.test.ts server/src/services/issue-thread-interactions.test.ts server/src/__tests__/issue-thread-interaction-routes.test.ts server/src/__tests__/server-startup-feedback-export.test.ts` — 4 files and 120 tests passed. - `pnpm -r typecheck` — passed for all applicable workspaces. This includes Cargo format and check, protocol drift checks, and migration safety. - `pnpm build` — passed. This includes the Rust release binary, server build, and UI production build. - `git diff --check` — passed. - Secret patterns were not present in the changed text files. - The repository token gates currently report violations from unchanged files on `master`. This pull request does not change those files. ## Risks The main risk is routing a direct-adapter answer into a native session. The service checks the persisted runtime mode, and the adapter matrix proves that all direct adapters use only the existing wake path. The new table is additive. It has foreign keys, unique correlation constraints, bounded attempts, and status checks. Activity records omit question and answer content. ## Model Used OpenAI Codex, GPT-5 family. The client does not expose the exact deployment ID or context window. Agentic reasoning, tool use, and code execution were enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes:` / `Closes:` / `Refs:` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal Paperclip ticket ID or instance-derived details - [x] I have run the affected tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have documented the new contracts and compatibility boundary - [x] I have considered and documented compatibility and security 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 |