mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-26 02:00:52 +01:00
fix/postgres-null-socket-write-guard
31
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
0f94521017 |
fix(runner): restore local session and task integrity (#12721)
## Thinking Path > - Paperclip is the control plane for agents that perform work. > - Paperclip Runner connects durable provider sessions to individual task runs through PRP. > - Provider continuity and per-run authority are different lifetimes. > - The existing implementation mixed those lifetimes and lost event metadata between provider frames, runnerd, persistence, API sanitization, and the task thread. > - That caused failed continuation, missing progress and Plans, duplicate replies, hidden failures, and unsafe recovery. > - This repair gives every heartbeat fresh authority, preserves qualified provider-session continuity, and restores one lossless presentation path without changing direct adapters. ## Linked Issues or Issue Description **What happened?** A second native heartbeat could reuse tickets, leases, command receipts, sequence state, and run identity from the first heartbeat. Provider phase and item identity could be lost before the UI read them. Redaction could corrupt protocol discriminators while still missing malformed credential tails. The task thread could fold progress into the final response, hide failures, or show more than one final answer. Native Codex also exposed approval modes that do not yet have a durable approval bridge. **Expected behavior** Each heartbeat uses a new PRP authority epoch. Codex and OpenCode preserve exact qualified provider sessions; ACPX emits an explicit continuity event when its qualified process-replacement policy is used. Every accepted provider event is presented, classified as internal, or surfaced as unsupported. The task page shows chronological progress, reasoning summaries, activity, Plans, interactions, terminal failures, and exactly one final reply. Direct adapters retain their existing path. **Steps to reproduce** 1. Enable the unified experimental Paperclip Runner setting. 2. Create a local native Codex, OpenCode, ACPX Claude, or ACPX Codex agent. 3. Run response, Plan, structured-question/resume, restart, cancellation, and failure scenarios. 4. Reload the task while active, waiting, failed, and settled. 5. On the old implementation, observe stale run authority, missing classifications, incomplete output, or duplicated/folded replies. **Paperclip version or commit** The repair is based directly on `master` at `87d05e194b643810d16d20612115acd01d735d43`. **Deployment mode** Local development with the embedded database. Related work: Refs #12616, #12646, #12666, #12685, and #12700. ## What Changed - Rotates PRP control-plane, outbox, ticket, lease, command, receipt, and sequence authority for each heartbeat while carrying forward only a validated provider-session identity. - Reads `control-plane-state.json`, validates both durable schemas and lifecycle values, resumes coherent current runs, archives qualified settled authority, and quarantines malformed or mismatched scoped state without moving ambiguous live legacy state. - Preserves Codex provider phase and stable item identities so commentary remains progress and only `final_answer` becomes final. - Adds raw OpenCode HTTP/SSE boundary coverage and canonical reasoning lifecycle mapping. - Makes ACPX normalization lossless for visible reasoning, tool lifecycle metadata, stable bounded identities, Plan revisions, structured requests, failures, and qualified process replacement. Only the compatible terminal assistant message is promoted as final. - Applies schema-aware redaction before generic JWT-shaped detection and scans every diagnostic string leaf. Malformed raw/escaped quoted credential tails are redacted in both server and durable Rust state. - Restores snapshot-style chronological task presentation, expandable tool activity, inline Plan cards, visible waiting/resume/cancel/failure states, and exactly one final answer. - Makes `never` the only qualified native Codex permission mode and rejects unsupported persisted native modes with remediation. OpenCode and ACPX policies remain intact. - Keeps the unified experimental Runner setting as the only enablement flag. Onboarding and direct Codex, Claude, and OpenCode stay on their legacy execution/finalization paths. - Adds cross-language goldens, authority/recovery/fault coverage, exact response/count assertions, and native plus legacy acceptance scenarios. ## Verification - Pull-request GitHub Actions run Rust formatting/tests, TypeScript checks, server/UI tests, builds, protocol drift checks, browser E2E, and security scans. - A separate workflow-only validation ref is pinned directly on this PR head and runs the 35-cell paid local matrix: three core scenarios plus structured-question resume and restart/resume for native Codex, native OpenCode, ACPX Claude, ACPX Codex, and direct Codex/Claude/OpenCode. Run: https://github.com/paperclipai/paperclip/actions/runs/33682434315 - Acceptance requires exact single visible replies, monotonic sequences, matching envelope discriminators, one semantic terminal, one run terminal, no unresolved interaction, no duplicate mutation, no secret leakage, provider continuity, and zero native rows for direct adapters. - Per maintainer direction, tests are running in GitHub Actions rather than on the slower local host. Only formatters and static diff checks were run locally. ## Risks - Recovery from old or partial filesystem state is sensitive. The repair fails closed, preserves active or unverifiable authority, and quarantines only state whose scoped ownership is safe to move. - Provider event formats can change. Closed validators and boundary goldens turn new or malformed events into visible diagnostics instead of silent drops. - Shared task presentation could affect direct adapters. Runtime-fact gating plus the direct-adapter matrix protect the existing path. - Managed and remote providers are not qualified here. Shared code continues to compile and fail safely, but live qualification is deferred. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI Codex based on GPT-5. The exact deployed snapshot and context-window size are not exposed to this task. It used agentic reasoning, repository inspection, code editing, Git, parallel subagents, and GitHub Actions. ## 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 - [ ] I have run tests locally and they pass (intentionally deferred to GitHub Actions) - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented risks above - [ ] All Paperclip CI gates are green - [ ] The paid local-provider matrix is 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 |
||
|
|
5716fe907e |
test(runner): add full-stack acceptance and eval gates (#12700)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The runner subsystem executes agent work across local and managed provider backends. > - The lower pull requests restore the task runtime, provider backends, and managed-provider control plane. > - The restored system needs repeatable full-stack checks before it can ship safely. > - Paid live checks also need clear access, cost, and secret controls. > - This pull request adds acceptance, live evaluation, chaos, and release gates for the restored runner stack. > - The benefit is measurable runner parity with safer release decisions. ## Linked Issues or Issue Description **Subsystem affected** Cross-cutting. This change covers runner tests, release workflows, server contracts, and evaluation tools. **Problem or motivation** The runner stack did not have one complete acceptance surface for native Codex, ACPX, Claude Managed, and AWS AgentCore. Release checks could miss provider drift, task-view regressions, cost-policy errors, and destructive cleanup errors. **Proposed solution** Add a 57-cell full-stack catalog, a Daytona image, and opt-in paid workflows. Add live evaluation, chaos, cost-limit, redaction, and release contract checks. Add AWS AgentCore infrastructure and guarded provisioning tools. Keep the native runner experimental flag off by default. **Alternatives considered** We considered manual smoke tests only. They do not give repeatable evidence and they do not protect release branches. We also considered one large pull request. The stacked pull requests keep each review below the Greptile file limit. **Roadmap alignment** This work supports the shipped Cloud / Sandbox agents milestone and the shipped Agent evals & feedback milestone in `ROADMAP.md`. Related stack: - #12699 adds managed provider backends and lifecycle support. - #12691 adds qualified OpenCode and ACPX provider backends. - #12685 restores task runtime rendering and steering. ## What Changed - Add the runner full-stack harness with 57 catalog cells and 60 unit tests. - Add a Daytona runner image with digest-pinned base images and base-aware image-content checks. - Add guarded live evaluation and chaos workflows with a fixed 40-execution matrix; live and full-stack paid schedules now run only on Sundays or by manual dispatch. - Add in-flight reported-usage cost stops, post-turn cost caps, exact-threshold failure classification, secret redaction, retry classification, and actor authorization. - Reattach stream and hard-budget listeners before restart-recovery continuations so restored paid sessions cannot bypass in-flight interruption. - Preserve OpenCode usage and cost across tool-loop messages and turns while exposing an explicit current-run delta to durable accounting. - Keep PNG/WebM evidence in access-controlled artifacts only, reject SVG, and publish only pruned inert structured per-attempt evidence. - Add AWS AgentCore infrastructure, provisioning checks, and smoke tools; reject unsafe model identifiers, require exact stack ownership markers, and make failed-stack replacement explicit. - Add evaluation-session contracts and capability reports. - Add release workflow checks for immutable action pins, frozen dependency installs, exact weekly cron shape, paid-run guards, provider-secret isolation, and chaos test paths. - Reauthorize the original and triggering numeric actor IDs as the first step of every provider-secret job, including partial reruns, before checkout or provider access. - Give each full-stack matrix cell only its matching provider credential, expose Daytona only to Daytona cells, and disable shared dependency caches anywhere paid credentials or OIDC write access are present. - Protect the legacy manual E2E workflow with the same default-branch, allowlist, environment, and per-job authorization boundary. - Rotate live-eval candidates by week and retain 120 days of compatible history so the seven-week trend window remains viable. - Restore the root runner-acceptance commands and reconcile reported snapshots, raw receipts, and terminal usage without double counting or losing late usage. - Mark ACPX token deltas exact only when every budget field is present, keep cumulative cost/request authority separate, reject non-USD cost labeling, and include thought tokens in output-token budgets. - Keep `enableNativeRunner` off by default. The acceptance harness enables it only in its isolated test instance. ## Verification Passed locally: - `pnpm --filter @paperclipai/paperclip-runner typecheck` - `pnpm test:runner-acceptance:typecheck` - `pnpm test:runner-acceptance` (19 tests) - focused OpenCode proxy, driver, runnerd transport, live-session, and turn-stream tests (106 tests) - `pnpm --filter @paperclipai/paperclip-runner exec vitest run src/live/clean-room-server.test.ts` (22 tests) - `pnpm test:e2e:runner:typecheck` - `pnpm test:e2e:runner:unit` (62 tests) - `node --test scripts/__tests__/release-verify-workflow.test.mjs` - `pnpm --filter @paperclipai/paperclip-runner test:runner-workflow-evals` (22 tests) - `pnpm -r typecheck` - `pnpm build` - `node --test packages/paperclip-runner/scripts/aws-agentcore-provisioning.test.mjs` (6 tests) - `git diff --check` - `cargo test --manifest-path packages/paperclip-runner/runner/Cargo.toml -p paperclip-runner-core --lib --locked` (161 tests) - focused ACPX provider-event tests (10 tests) - The rebased PR changes 92 files. `pnpm-lock.yaml` is unchanged. I did not run paid live provider jobs or provision AWS resources. Those checks need credentials and can create cost. ## Risks The paid workflows can create provider cost. They require an allowlisted original and triggering actor, the protected `runner-e2e-paid` environment, explicit opt-in variables, and cost limits. The four provider credentials exist only in that master-only environment, which requires allowlisted reviewer approval and disables administrator bypass; repository and organization Actions scopes contain no copies. Provider usage arrives after a billable request, so the live guard cannot prevent one request from crossing a threshold. It interrupts immediately on the first reported threshold hit and permits no continuation. Visual evidence can contain secrets rendered as pixels. PNG/WebM remain only in access-controlled workflow artifacts; SVG and per-attempt XML are excluded, and S3/Pages receive a pruned structured dashboard. The AWS scripts can create cloud resources. They use explicit commands, least-privilege roles, KMS encryption, saved nonsecret metadata, and explicit teardown. This pull request does not enable the experimental native runner for existing instances. > 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 with GPT-5. The model used extended reasoning, tool use, code execution, and parallel subagents. ## 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 |
||
|
|
fdf8c8464d |
feat(runner): add managed provider backends (#12699)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The Paperclip Runner provides durable, provider-neutral agent execution. > - The current stack supports qualified local providers but omits the managed provider paths from the integration branch. > - Claude Managed Agents and AWS AgentCore need explicit profile qualification, durable recovery, usage accounting, and cleanup controls. > - This pull request adds those managed backends as the third part of the Runner parity stack. > - The benefit is managed execution without weakening the default-off Runner rollout gate. ## Linked Issues or Issue Description **Subsystem affected** Cross-cutting: Runner, server orchestration, database profiles, CLI, and adapter configuration UI. **Problem or motivation** The current Runner stack cannot select or execute the managed Claude Agents API or AWS Bedrock AgentCore Harness backends. It also lacks qualified profile storage and recovery checks for those remote resources. **Proposed solution** Add qualified managed and remote profiles, API and CLI management, exact provider selection, durable lifecycle handling, cumulative usage accounting, bounded cleanup, and retention acknowledgement. Keep `enableNativeRunner` default-off. **Alternatives considered** A direct copy of the old integration branch was rejected because its provider contracts, model values, credential flow, and migration history no longer match the current base. A single large parity pull request was also rejected because stacked review keeps each subsystem bounded. **Roadmap alignment** This continues the existing Runner architecture and rollout work. It does not introduce a separate execution system. **Additional context** This pull request is based on the merged #12691 and #12685 stack. It also closes the delayed security-review findings reported on #12691 by binding qualified ACPX and OpenCode launch artifacts to the bytes actually executed. A GitHub search for managed agent, AgentCore, and Claude managed work found no duplicate public issue or pull request. ## What Changed - Add Claude Managed Agents and AWS AgentCore provider executors to runnerd. - Add qualified managed and remote profile storage, routes, OpenAPI contracts, CLI commands, and migration 0237. - Validate profile ownership, enabled state, exact qualified revision, model, agent version, and secret binding before persistence and recovery. - Persist durable provider session and owned skill state for restart-safe cleanup. - Reconcile uncertain create responses and delete remote sessions before owned skills. - Track cumulative provider usage and enforce positive session spend caps. - Recover interrupted AgentCore usage at the next turn boundary by charging the prior invocation ceiling exactly once; keep the session gated until an explicit monotonic budget raise. - Isolate AgentCore AWS configuration from host profiles and credential-process/SSO configuration while preserving workload identity. - Require OpenCode 1.18.17 and fixed build-owned provider-pack artifact paths; remove the ambient executable override. - Snapshot and content-verify ACPX and OpenCode commands, scripts, and provider executables before launch. Linux executes sealed inherited descriptors; macOS uses authenticated private snapshots with retry-safe rematerialization at the spawn boundary. - Persist canonical ACPX and OpenCode launch-profile digests, reject drift across fresh recovery, and make recovery failures sticky. - Close and journal unsafe ACPX active-turn recovery before any provider bootstrap or reconnect. - Add managed provider fields to the Runner configuration UI and permission projection. - Preserve the default-off `enableNativeRunner` experimental flag. ## Verification - `pnpm -r typecheck` - `pnpm build` - Focused managed server, database, CLI, Runner TypeScript, Rust, Claude, AgentCore, ACPX, OpenCode, process-supervisor, and durable-recovery tests passed. - `cargo test -p paperclip-runner-core --lib --locked` (160 tests) - `cargo check --workspace --all-targets --locked` - Native Codex integration tests passed (60 tests); native provider tests passed (7 tests); server native-runtime tests passed (87 tests). - Verified-launch replacement, nested-spawn retry, exact-version, profile-drift, sticky-failure, and no-bootstrap active-recovery tests passed. - `git diff --check` - The PR changes 91 files. `pnpm-lock.yaml` is unchanged. The Rust workspace lockfile adds the approved `rustix` dependency used for safe descriptor handling while `#![forbid(unsafe_code)]` remains enabled. ## Risks - The provider APIs can change while they are in beta. Exact qualification and fail-closed recovery checks limit drift. - Remote cleanup can fail after a partial create. Durable ownership inventories and retry-safe deletion preserve recovery state. - Migration 0237 adds profile tables. The generated migration and snapshot pass the repository migration checks. - Managed execution can incur provider cost. Positive default spend caps and explicit retention acknowledgement limit accidental use. - An interrupted AgentCore invocation without final metadata is conservatively charged to its active session ceiling. This can overstate cost, but cannot undercount it; later work requires an explicit budget increase. - Linux qualified launches use sealed memory descriptors. macOS lacks executable-descriptor APIs, so the runner uses owner-only private snapshots and minimizes linked-path lifetime; hostile same-UID processes remain outside the documented local-host trust boundary. - The global Runner feature remains default-off. > 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 tool use, code execution, and subagent review. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change 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 |
||
|
|
84bedd4ca1 |
feat(runner): activate qualified OpenCode and ACPX providers (#12691)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Paperclip Runner is the experimental native runtime for governed agent work. > - The runtime contracts already describe Codex, OpenCode, and ACPX providers. > - The merged control plane still rejected OpenCode and ACPX for new runner agents. > - Runnerd also selected only the Codex provider implementation. > - This pull request activates the qualified OpenCode and ACPX paths from the form to runnerd. > - The benefit is one durable runner path with provider-specific permissions and recovery. ## Linked Issues or Issue Description Refs #12685 **Subsystem affected** This change affects the runner package, server orchestration, adapter configuration, and UI configuration. **Problem or motivation** Paperclip Runner stores provider contracts for OpenCode and ACPX. New agents cannot select those providers. Runnerd cannot execute those stored provider descriptors. The UI also shows only Codex. **Proposed solution** Accept the qualified OpenCode 1.18.17 profile and the fixed ACPX Claude and Codex profiles. Route them through runnerd. Keep provider selection, model selection, permissions, credentials, events, and recovery inside closed provider-specific boundaries. **Alternatives considered** One option was to keep the contracts dormant. That option leaves stored configuration and runtime behavior out of sync. Another option was to enable every ACPX agent. That option is not safe because Pi does not yet have the same verified launch path. **Roadmap alignment** This change supports the completed cloud and sandbox agent milestone. It also supports self-healing runs and governed agent execution. It does not add a new roadmap surface. ## What Changed - Add one server profile resolver for Codex, OpenCode, and qualified ACPX descriptors. - Keep `adapterConfig` as the provider and permission authority for fresh runs. - Add Paperclip Runner provider, ACPX agent, and provider-specific permission controls to the UI. - Reset the model to a compatible qualified value when the provider changes. - Route Codex, OpenCode, and ACPX through the durable runnerd provider selector. - Add a durable ACPX executor with bounded state, recovery, events, tool receipts, and identity checks. - Remove Codex labels from OpenCode events, results, evidence, and recovery diagnostics. - Pass only provider-specific credential names to child processes. - Keep ACPX Pi unavailable and reject it before process launch. - Keep the existing Paperclip Runner experimental flag unchanged. ## Verification - `pnpm exec vitest run packages/paperclip-runner/src/backends/native-backend-factory.test.ts packages/paperclip-runner/src/live/runnerd-codex-transport.test.ts packages/adapters/codex-local/src/ui/build-config.test.ts ui/src/adapters/codex-local/config-fields.test.tsx server/src/__tests__/adapter-registry.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-adapter-validation-routes.test.ts server/src/__tests__/company-portability.test.ts server/src/services/native-runtime/runtime-mode.test.ts server/src/services/native-runtime/native-session-executor.test.ts server/src/services/heartbeat-runner-provider-config.test.ts` - The focused TypeScript, server, and UI suites passed 274 tests. - `cargo test -p paperclip-runner-core --test native_provider_backend` - The executable native provider integration suite passed 4 tests. - `cargo test -p paperclip-runner-core --lib` - The Rust unit suite passed 91 tests. - `pnpm -r typecheck` - `pnpm check:token-gates` - `pnpm build` - `git diff --check codex/runner-parity-task-runtime...HEAD` ## Risks - This changes provider process selection and durable recovery. The experimental flag still gates every fresh Paperclip Runner run. - OpenCode requires a model in `provider/model` form and stays pinned to version 1.18.17. - ACPX accepts only exact Claude and Codex profile versions and models. Pi stays unavailable. - ACPX steering stays unavailable and reports that limit through the driver capabilities. - Child processes receive explicit environment allowlists. They do not inherit the full server environment. - This pull request has no database migration. ## Model Used OpenAI Codex, GPT-5, with tool use, code execution, and subagent review. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] 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 |
||
|
|
584031af66 |
test(runner): bound codex provider exit polls by wall clock (#12596)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The runner subsystem drives a Codex provider process and reads its events with `CodexProvider::poll` > - The Codex provider integration tests wait for those events in poll loops > - Two of those loops count iterations instead of measuring time, so they stop waiting too early > - This makes `cargo test` fail at random on branches that change no Rust code > - This pull request bounds the two loops by wall clock, like every other wait in the same file > - The benefit is that a red CI job now means a real defect ## Linked Issues or Issue Description **What happened?** `packages/paperclip-runner/runner/crates/runner-core/tests/codex_provider.rs` fails `cargo test` at random. The failure appears in the `ci / Build` job with exit code 101. It appears on branches that change no Rust code. Two tests fail: - `ambiguous_or_dead_replacement_start_preserves_result_not_exit_authority` at line 1274 - `ambiguous_replacement_turn_adopts_one_later_completion_identity` at line 1443 Both assertions report `left: None`. The value is not wrong. The loop never saw the `CodexProviderEvent::Exited` event at all. **Expected behavior** The tests must wait for the provider process to exit. A test must fail only when the provider gives a wrong result. **Steps to reproduce** 1. Build the integration test: `cargo test --test codex_provider --no-run`. 2. Run one of the two named tests 25 times in a row. 3. About 8 of the 25 runs fail with `left: None`. **Paperclip version or commit** Reproduced on `master` at `2e5a24e17`. **Related pull requests** Refs #12241. That pull request also edits `packages/paperclip-runner/runner/crates/runner-core/tests/codex_provider.rs`. It does not fix these two loops. The two changes may need a merge if both land. **Root cause** `CodexProvider::poll` (`crates/runner-core/src/codex_provider.rs:824`) reads with a 1 ms timeout. That timeout does not apply on every path. `ProcessSupervisor::receive_stdout_line` (`crates/runner-core/src/process_supervisor.rs:293`) returns at once, and uses none of the 1 ms budget, in two cases: `StdoutClosed` at line 309 and `RecvTimeoutError::Disconnected` at line 315. A child process closes its pipes before its exit status is ready to reap. In that window every `poll()` call returns `Ok(None)` in nanoseconds. A loop of 64 or 128 iterations then ends in microseconds, before the exit status is available. The failing run above ends in 0.06 s. ## What Changed - `tests/codex_provider.rs`: bound the exit wait at line 1256 by a 5 second deadline instead of 64 iterations. - `tests/codex_provider.rs`: bound the exit wait at line 1397 by a 5 second deadline instead of 128 iterations. - Both loops now sleep 1 ms when `poll()` returns no event. This copies the pattern that the same file already uses at line 1511 and in every `wait_for_*` helper. - No production code changes. The change is test-only. ## Verification Measured before and after the change. Each test ran 25 times in sequence, on an idle machine, with `--test-threads=1`. | test | before | after | |---|---|---| | `ambiguous_or_dead_replacement_start_preserves_result_not_exit_authority` | 8 / 25 failed | 0 / 25 failed | | `ambiguous_replacement_turn_adopts_one_later_completion_identity` | 9 / 25 failed | 0 / 25 failed | The full `codex_provider` suite also ran 12 times with `--test-threads=4` after the change. Every run passed. Commands: ``` cargo test --test codex_provider --no-run cargo test --test codex_provider ``` ## Risks Low risk. The change touches test code only. It makes two waits longer in the failure case: a genuinely broken provider now takes up to 5 seconds to fail these two tests instead of microseconds. Every other wait in this file already uses the same 5 second deadline. ## Model Used Claude Opus 5 (`claude-opus-5`), extended thinking, with tool use and code execution. Depends-on: none — this is a self-contained test-only change with no prerequisite pull request. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [ ] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes — none apply. This change is test-only and alters no public interface, so no docs page and no end-to-end test change is needed. - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: zannis <1011451+zannis@users.noreply.github.com> |
||
|
|
0bdbf61564 |
feat(runner): add secure remote transport (#12639)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Paperclip Runner gives native runs a durable and governed execution path. > - The lower stack PR adds authenticated remote execution targets and provider ingress. > - The Rust daemon currently accepts only loopback plaintext WebSocket connections. > - Remote Codex needs authenticated WSS dialing and provider-ingress listener mode. > - This pull request adds the bounded Rust transport contract. > - The benefit is a secure transport layer for the Codex remote vertical slice. ## Linked Issues or Issue Description Refs #12638. Refs #12616. Refs #12352. **Subsystem affected** Paperclip Runner Rust transport and remote runner networking. **Problem or motivation** The runner daemon cannot connect to a public control plane with TLS. It also cannot accept a provider preview connection on the run-bound ingress path. **Proposed solution** Add WSS with native trust roots and an optional private CA bundle. Add a fixed authenticated listener mode for provider ingress. Advertise the exact transport contract through build metadata. **Alternatives considered** Plaintext public WebSocket connections would weaken the transport boundary. A general listener would expose more network surface than the run-bound provider ingress requires. **Roadmap alignment** This work supports the Cloud and Sandbox agents milestone. It also supports self-healing native runs. ## Stack - Lower merged PR: #12638. - This PR contains only its 13-file delta against `master`. - Later stack PRs add the task workspace and administrator UI. ## What Changed - Added WSS dialing with rustls and native certificate roots. - Added an optional bounded private CA bundle that augments native roots. - Kept plaintext WebSocket dialing restricted to loopback addresses. - Pinned resolved dial addresses for the process lifetime. - Added a fixed `0.0.0.0:43127` listener with an exact run-bound path. - Rejected listener queries, ambiguous paths, and WebSocket extensions. - Kept frame and message size bounds. - Added bounded reconnect grace and exponential jitter. - Retried bootstrap failures only before authentication proof transmission begins. - Kept post-proof failures fail-closed and bounded the welcome exchange at two seconds. - Added runnerd build metadata for the versioned transport contract. - Updated Rust dependencies and `Cargo.lock` only for TLS and certificate handling. - Did not add provider dispatch, Pi, AWS, `pnpm-lock.yaml`, migrations, or workflows. ## Verification - GitHub Actions will run Cargo formatting, Rust tests, repository tests, typecheck, build, security, and policy gates. - Rust tests cover URL validation, listener path validation, build metadata, durable recovery, and the existing Codex provider path. - Local tests were not run. The requested verification policy uses GitHub Actions for this series. - `git diff --check master...HEAD` passes. - The delta contains 13 files. ## Risks - TLS and listener changes affect the runner trust boundary. - Public plaintext transport remains rejected. - The listener uses one fixed port and one exact run-bound path. - PRP authentication remains required after the WebSocket upgrade. - The optional CA file uses the existing private-file checks and a 4 MiB limit. - This PR does not enable another provider or change direct adapters. > 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 with GPT-5.6. The work used high-reasoning agent mode, repository tools, GitHub tools, and parallel code-audit agents. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with Fixes: / Closes / Refs OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal Paperclip ticket id - [ ] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented 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 |
||
|
|
560e7e48b5 |
feat(runner): add SDK and developer tooling (#12608)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The runner package already provides the production protocol and execution spine. > - Contributors still need stable SDK surfaces, deterministic test tools, and local inspection tools. > - Those surfaces share generated contracts and must change as one package boundary. > - This pull request adds the package-local SDK, labs, examples, and drift checks. > - The benefit is a reviewable developer platform that does not change application execution selection. ## Linked Issues or Issue Description **Subsystem affected** `packages/paperclip-runner` — runner SDK, conformance tools, and developer tooling. **Problem or motivation** The production runner spine is present, but package consumers cannot build deterministic integrations, inspect sessions, or verify provider-neutral behavior through supported surfaces. **Proposed solution** Add browser, React, standalone, live-session, scenario, conformance, and evaluation surfaces. Add generated contract inventories and package-local verification scripts. Keep production application routing unchanged. **Alternatives considered** We considered splitting each generated catalog, SDK surface, and demo into separate pull requests. Those changes share exports, fixtures, and drift gates. Splitting them would create intermediate package states that do not build. **Roadmap alignment** No overlapping item appears in `ROADMAP.md`. This work extends the runner package that is already on `master`. ## What Changed - Add browser, React, standalone, live-session, and issue-thread SDK surfaces. - Add deterministic mock control-plane, scenario, conformance, replay, and evaluation tools. - Add bounded Codex, OpenCode, and ACPX development transports and fixtures. - Keep deferred managed-provider execution fail-closed. Persisted compatibility data remains readable. - Add generated capability inventories with their source files and drift checks. - Add examples, package documentation, browser checks, and clean-consumer checks. - Preserve the reviewed protocol bounds, replay compatibility aliases, process environment isolation, and semantic redaction limits. - Update the ACPX package patch that the existing workspace patch registry already tracks. - Do not change `pnpm-lock.yaml`, repository workflows, server runtime selection, or the application UI. ## Verification GitHub Actions is the verification authority for this pull request. The repository CI, package TypeScript and Rust checks, package tests, generated-output drift checks, browser checks, security scans, and Greptile review must pass on the exact head. Local test suites were not run because this series uses parallel GitHub Actions for verification. ## Risks This is a large greenfield package change. The main risks are public export drift, generated-output drift, and optional React consumer compatibility. Package boundary checks, clean-consumer checks, and browser tests cover those risks. Production adapter selection and server execution are outside this pull request. ## Stack 1. **This PR:** runner SDK and developer tooling. 2. [Codex production server integration](https://github.com/paperclipai/paperclip/pull/12616). 3. [Provider-neutral task-thread UI](https://github.com/paperclipai/paperclip/pull/12617). ## Model Used OpenAI Codex, GPT-5, high-reasoning mode, with 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 described the issue in-PR following the feature request 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 - [ ] 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 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 |
||
|
|
ad0ad43cf4 |
feat(runner): activate qualified Claude ACPX runtime (#12590)
## Thinking Path > - Paperclip Runner already has a hardened ACPX path for Codex. > - Claude can reuse that protocol only with an exact package/model profile and provider-lifetime fencing. > - Pi needs a separately spawned runtime whose executable does not yet have the descriptor-confined verified launch used by the ACP server. > - This pull request therefore activates Claude only and keeps Pi unavailable before installation or process launch. ## Linked Issues or Issue Description **Subsystem affected** Paperclip Runner ACPX driver, runtime host, sidecar, backend factory, package dependency, and provider conformance tests. **Problem or motivation** The production ACPX backend was Codex-only. Claude needs the same fail-closed model, authorization, cancellation, cleanup, and recovery boundaries without exposing an unsafe secondary runtime path. **Proposed solution** Generalize the hardened ACPX runtime for the exact qualified `claude` profile, add the pinned Claude ACP package and reviewed isolation patch, and reject Pi before installation, backend construction, sidecar initialization, Rust session admission, or process creation. **Alternatives considered** Activating Pi in this PR was rejected after security review because its secondary runtime executable was pathname-based and lacked the verified descriptor/snapshot boundary. Pi is deferred to a dedicated follow-up. Replaying the older generic ACPX implementation was rejected because it predates current hardening. **Roadmap alignment** ROADMAP.md does not list a conflicting ACPX-provider project. This extends the existing Runner provider architecture. ## What Changed - Generalized the ACPX backend, driver, runtime adapter, host, and sidecar for the qualified Claude profile. - Added Claude ACPX activation through its exact pinned package/model pair and isolated-settings patch. - Added provider-lifetime fencing for non-Codex qualified ACPX sessions. - Kept Pi dependencies and its patch out of the package and build configuration. - Added fail-closed Pi rejection at driver validation, backend construction, runtime-host admission, sidecar initialization, and Rust session validation. - Added focused tests for Claude selection, model enforcement, lifecycle fencing, cancellation, recovery, and Pi rejection. - Did not change or commit `pnpm-lock.yaml`; CI regenerates the PR lockfile under the existing repository policy. ## Verification - GitHub Actions is the authoritative verification environment for this PR. - CI runs dependency policy, runner package checks, protocol parity, typecheck, build, security, and stack policy. - Local tests were not run because this checkout is resource constrained, per the requested workflow. ## Risks - Claude package behavior can drift from the qualified protocol; the package and patch are pinned and admission verifies the exact profile. - Unsupported providers and models fail closed. - Pi remains unavailable until descriptor-confined verified launch exists for its separate runtime. - Existing Codex ACPX behavior remains covered by shared conformance tests. > 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. ## Model Used OpenAI Codex, GPT-5.6, with repository tools, code execution, and parallel agent review. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs - [x] I have described the issue in the PR - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name contains no internal task identifier - [ ] I have run tests locally and they pass — GitHub Actions is authoritative for this resource-constrained checkout - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation - [x] I have considered and documented risks - [ ] All applicable Paperclip CI gates are green - [ ] Greptile is 5/5 with no actionable findings ## Stack - Position: lowest unmerged PR - Base: `master` - Previous: [#12588](https://github.com/paperclipai/paperclip/pull/12588), merged qualified OpenCode runtime - Next: [#12591](https://github.com/paperclipai/paperclip/pull/12591), native application integration |
||
|
|
8478ddbcee |
feat(runner): persist ACPX suspension checkpoints (#12425)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The Rust ACPX session can now suspend only at a safe idle boundary and its events have a durable projection > - A later runner process cannot safely resume from an unbound or partially written identity record > - The recovery anchor must bind the exact provider identity, run, normalized session, catalog revision, and catalog digest > - The record must be bounded, private, strict about schema drift, and atomically replaceable > - Recovery must re-admit the entire prospective session configuration before releasing the stored identity > - This pull request adds only that package-local checkpoint store without selecting ACPX in runnerd ## Linked Issues or Issue Description Refs #12424 Refs #12422 ## What Changed - Add a versioned ACPX safe-suspension checkpoint contract with unknown fields rejected at every persisted level. - Bind each checkpoint to the run, normalized session, catalog revision, catalog digest, and exact provider identity. - Persist a checkpoint-specific strict identity that requires the pinned permission mode without narrowing the additive live sidecar identity wire shape. - Construct checkpoints only from a session configuration whose model, permission policy, tool catalog, and expected identity validate. - Admit recovery only when reconstructing the checkpoint from the prospective configuration produces an exact match. - Reject run, session, catalog revision, catalog digest, model, permission, expected-identity, profile, and workspace drift fail closed. - Require persisted run/session IDs to satisfy the same stable-ID boundary as fresh session admission. - Store the checkpoint under a dedicated private runner-state subdirectory. - Bound checkpoint files to 1 MiB before reading or decoding. - Refuse symlinked state directories and non-private or non-regular checkpoint files. - Replace checkpoints atomically through a private temporary file and directory sync. - Make repeated saves of the same checkpoint idempotent. - Add integration coverage for private round trips, complete recovery admission, malformed/oversized files, nested schema drift, missing permission binding, invalid stable IDs, and symlink denial. - Document the package-local suspension recovery boundary. - Do not change dependencies, lockfiles, workflows, runnerd selection, server behavior, UI, or migrations. ## Verification - Replay base: `1ee738cf487defe88043b241c4e2dc34a1a8a7bc` (`master` after #12424 merged). - Exact replay head: `89cfea5495428be890810d2b8a27673943234ca3`. - Stable patch ID: `dbaeb0bbe773f1ca5ef1f9bdc0fa61f4a08ca451`. - The exact delta is 4 files and 591 additions, all in `packages/paperclip-runner`; it contains no lockfile, workflow, server, UI, dependency, or migration change. - `git diff --check` and the Cargo formatting check pass on the replayed delta. - Exact-head GitHub Actions run `33374006661` (attempt 2): **PASSED** with 23/23 jobs passed. - Greptile reviewed exact head `89cfea5495428be890810d2b8a27673943234ca3`: **5/5**, with zero unresolved review threads. - Superagent, contributor trust, Socket, and Snyk security checks: **PASSED**. - No local test result is claimed. GitHub Actions is the authoritative verification environment for this replayed revision. ## Risks - A checkpoint is valid only after the sidecar has confirmed safe suspension. The constructor therefore accepts the exact identity returned by that operation and revalidates it against local authority. - Loading proves only that the file is structurally valid; `admit_recovery` is the boundary that proves the file belongs to the prospective run, catalog, model, permission policy, and expected provider identity. - The checkpoint intentionally contains no credentials, bootstrap ticket, provider output, or pending request payload. - Strict checkpoint schema and identity validation rejects incompatible or tampered recovery records rather than attempting partial migration. This strictness is checkpoint-local and does not narrow existing PRP or sidecar wire compatibility. - Atomic replacement uses the platform `rename` primitive; Unix additionally syncs the private parent directory before reporting success. - No production path loads this checkpoint in this pull request. Runnerd execution and durable recovery wiring remain a later slice. > 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 with GPT-5.6, 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 linked the preceding public PRs 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 - [ ] 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 |
||
|
|
1ee738cf48 |
feat(runner): project durable ACPX events (#12424)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The Rust runner now owns validated, scoped ACPX reducer events and safe session suspension > - Durable PRP transport must receive provider-neutral events rather than sidecar-native envelopes > - Semantic calls and questions must retain the exact run, session, turn, item, and provider-request authority used by the durable command stream > - Terminal, result, assistant, process, and diagnostic events also need one reviewed projection boundary > - Permission requests remain impossible under the pinned Codex policy and must fail closed if they reach projection > - This pull request adds only that package-local projection without selecting ACPX in runnerd ## Linked Issues or Issue Description Refs #12422 ## What Changed - Add a validated durable ACPX event projection context bound to one run, normalized session, turn, and item. - Pass already normalized activity events through without reintroducing provider-native envelopes. - Project authorized tool calls into canonical semantic input receipts with exact correlation and content digests. - Project structured questions into provider-neutral `paperclip.runtime_request.v2` events. - Preserve both the public projected request identity and the original provider request identity so responses resolve the exact sidecar request. - Project dynamic semantic operation results as `semantic_tool.result`; only reserved finish/block operations may propose the run result. - Project semantic completion results into `run.result.proposed`. - Project terminal-flushed assistant messages on the final channel and turn terminal states into existing provider-neutral event families. - Project sanitized process metadata and diagnostics into bounded harness diagnostics. - Validate runtime-request origins against their strict durable shape and fall back from empty optional titles to a valid question prompt. - Reject invalid identities, projected-identity collisions, unstable semantic receipt identities, permission requests, and cross-turn projection fail closed. - Add integration coverage across reducer event families, correlation, identity validation, projected question resolution, and pinned-policy denial. - Document the durable projection boundary. - Do not change dependencies, lockfiles, workflows, runnerd selection, server behavior, UI, or migrations. ## Verification - Replay base: `80639f4f69c8938eb74bdc0833df93e0ed91dab3` (`master` after #12422 merged). - Exact replay head: `3cb29581d2bcbc4b47f8069baffd721c6ce4e444`. - Stable patch ID: `92910b56575e67ae83960177d467a565019ba282`. - The exact delta is 22 files, 1,206 additions, and 59 deletions, all in `packages/paperclip-runner`; it contains no lockfile, workflow, server, UI, dependency, or migration change. - `git diff --check` and the Cargo formatting check pass on the replayed delta. - Exact-head GitHub Actions run `33372209037` (attempt 2): **PASSED** with 23/23 jobs passed. - Greptile reviewed exact head `3cb29581d2bcbc4b47f8069baffd721c6ce4e444`: **5/5**, with zero unresolved review threads. - Superagent, contributor trust, Socket, and Snyk security checks: **PASSED**. - No local test result is claimed. GitHub Actions is the authoritative verification environment for this replayed revision. ## Risks - This function accepts reducer output, not raw sidecar frames. Callers must preserve the existing scope-first decode and reduction order. - Semantic input includes the already sanitized provider input while its content receipt uses the same canonical digest. - Structured input preserves the validated provider-neutral question set and sanitized origin. - Noncanonical provider request identities are deterministically projected for PRP while the original identity remains authoritative for the sidecar resolution command. - Existing PRP v1 identifiers remain schema-compatible; the only public ID-schema change widens turn/item limits from 160 to 240 characters. The internal ACPX sidecar wire schema now mirrors the stable IDs its Rust transport already enforced. - The projector verifies event-carried terminal and assistant turn identifiers against the durable context. - No production path invokes this projector in this pull request. Durable command execution remains the next slice. > 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 with GPT-5.6, 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 linked the preceding public PR 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 - [ ] 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 |
||
|
|
80639f4f69 |
feat(runner): suspend safe ACPX sessions (#12422)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The Rust runner now owns exact ACPX request resolution and fail-closed session state > - A recoverable provider session needs an explicit suspension boundary before runnerd can safely hand work across process lifetimes > - Suspension is unsafe while a turn or provider request is active because remote effects may still be in flight > - A successful acknowledgement must preserve the exact immutable session identity > - This pull request adds only that guarded package-local lifecycle operation without selecting ACPX in runnerd > - The benefit is a small recovery primitive whose safety rules are independently reviewable ## Linked Issues or Issue Description Refs #12421 ## What Changed - Add a provider-state query for active pending tool, input, or permission requests. - Permit session suspension only when no turn or provider request is active. - Send a bounded `session.suspend` command with an operator-safe reason. - Require an affirmative suspension acknowledgement and the exact existing session identity. - Treat transport failure, rejection, omitted or malformed identity, and identity drift as fail-closed terminal errors. - Mark a successfully suspended session closed and terminate the local sidecar process while retaining cleanup ownership if termination must be retried. - Preserve a valid session after purely local unsafe-state rejection so it can settle before retry. - Extend the fake sidecar with deterministic suspension success, acknowledgement mismatch, identity mismatch, and missing-identity modes. - Add integration coverage for safe suspension, active-turn rejection, fail-closed remote mismatches, and retained cleanup. - Document the package-local suspension boundary. - Do not change dependencies, lockfiles, workflows, runnerd selection, server behavior, UI, or migrations. ## Verification - Replay base: `91d861ff69d415a3b105ae2eaad9cc56c66a9231` (`master` after #12421 merged). - Exact replay head: `085667e10c51c6c0360732f63c8fef83e806dd88`. - Stable patch ID: `b18d6b7efd1de569d3068b0a782f8aac2fbc9322`; this is the prepared suspension delta plus the focused fake-sidecar fix that consolidates mismatch modes into the existing command arm. - The exact delta is 5 files, 136 additions, and 5 deletions, all in `packages/paperclip-runner`; it contains no lockfile, workflow, server, UI, or migration change. - Exact-head GitHub Actions run `33369571343` (attempt 1): **PASSED** with 23 jobs passed and zero failures. - Greptile reviewed exact head `085667e10c51c6c0360732f63c8fef83e806dd88`: **5/5**, with zero unresolved review threads. - Superagent, contributor trust, Socket, and Snyk security checks: **PASSED**. - No local test result is claimed. GitHub Actions is the authoritative verification environment for this replayed revision. ## Risks - The sidecar may apply suspension before a transport failure is observed. The local session closes rather than retrying an ambiguous effect. - Local active-work rejection happens before transport and leaves the valid session open so the caller can settle it safely. - Identity equality is checked across provider, driver, session, thread, run, and company fields before accepting suspension. - No production path invokes suspension in this pull request. Runnerd execution and durable recovery wiring remain later slices. > 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 with GPT-5.6, 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 existing issues with `Refs #` 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 - [ ] 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 |
||
|
|
91d861ff69 |
feat(runner): resolve ACPX provider requests (#12421)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The Rust runner now owns a scoped ACPX turn and validates provider requests before exposing them > - A live turn can pause for semantic tool results or structured input > - Local state and the sidecar can diverge if the runner clears a request before the sidecar accepts its resolution > - A mismatched or ambiguous remote acknowledgement must close the session, while a local validation error must preserve the request for a safe retry > - This pull request adds those two-phase resolution paths and rejects Codex permission events that bypass the pinned policy without selecting ACPX in runnerd > - The benefit is an atomic request boundary that can be wired into durable execution in a later slice ## Linked Issues or Issue Description Refs #12420 Refs #12419 ## What Changed - Resolve authorized semantic tool calls only for the active turn and exact pending operation. - Validate semantic results against the authorized response schema before transport. - Send a bounded generic provider error when a semantic operation fails without exposing internal error text or payloads. - Resolve structured input only after validating the exact persisted question set. - Support explicit submit, decline, and cancel input outcomes. - Reject any Codex permission event that bypasses the pinned sidecar policy. - Build candidate provider and authorization state before each request. - Commit candidate state only after the sidecar returns an affirmative resolution acknowledgement. - Preserve pending work after local validation errors so the caller can retry safely. - Terminate the session after transport failure or an invalid remote acknowledgement because the remote effect is ambiguous. - Bind every resolution to the exact active turn and request or call identity. - Extend the fake sidecar and add integration coverage for successful commits, safe local retries, pinned-policy enforcement, redaction, and fail-closed acknowledgement mismatch. - Document the package-local resolution boundary. - Do not change dependencies, lockfiles, workflows, runnerd selection, server behavior, UI, or migrations. ## Verification - Replay base: `3aa2065d084d6a29492aaa15e822b5d17c3a4266` (`master` after #12420 merged). - Exact replay head: `9507024f70c6f434c2c322385d3a9e240250b03c`. - Stable patch ID: `a4f27d2fae606596f70b5b1c2b29dd7f250541d8`, identical to the prepared two-commit delta. - The exact delta is 5 files, 463 additions, and 7 deletions, all in `packages/paperclip-runner`; it contains no lockfile, workflow, server, UI, or migration change. - GitHub Actions run `33368135190`, attempt 2: **PASSED** on the exact replay head (23/23 jobs passed; a failed-job-only retry cleared one unrelated server test environment failure where `npm` was unavailable). - Greptile: **5/5** on the exact replay head with zero unresolved review threads; Superagent, Socket, Snyk, and contributor-trust checks also passed. - No local test result is claimed. GitHub Actions is the authoritative verification environment for this replayed revision. ## Risks - A transport failure can happen after the sidecar applied a resolution. The session closes instead of retrying an ambiguous effect. - Local validation happens before transport and preserves pending state, so a corrected answer or result can be retried. - The sidecar transport already correlates each command response to its request identifier. This slice also requires `resolved: true` before local commit. - The initial Codex sidecar owns its pinned permission policy and does not delegate permission resolution. Any permission event therefore terminates the session fail closed. - No production path invokes these methods in this pull request. Durable ACPX execution wiring remains a later slice. > 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 with GPT-5.6, 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 or instance-derived details - [ ] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge |
||
|
|
3aa2065d08 |
feat(runner): validate structured question responses (#12420)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The Rust runner now owns a bounded ACPX session and a fail-closed turn lifecycle > - Provider questions pause a turn and must return structured answers to the same persisted question set > - JSON Schema validates the wire shape, but it cannot validate identifiers and constraints across two documents > - Unknown questions, invalid choices, and malformed custom answers must fail before any provider receives them > - This pull request adds only the package-local response validator and tests > - The benefit is a small trust boundary that later request-resolution code can use without changing production selection ## Linked Issues or Issue Description Refs #12419 ## What Changed - Validate `paperclip.question_response.v1` against its versioned JSON Schema. - Bound serialized responses to 768 KiB before validation. - Require answer identifiers to match the exact persisted question set. - Require answers for required questions and reject unknown question identifiers. - Enforce text, single-select, and multi-select answer modes. - Match the existing TypeScript numeric syntax, including decimal, exponent, hexadecimal, octal, and binary input. - Match ECMAScript trimming exactly, including BOM whitespace while rejecting Unicode NEL rather than inheriting Rust-specific whitespace behavior. - Enforce known options, custom-answer policy, text length, pattern, and numeric constraints. - Validate duplicate option IDs, inverted bounds, and dynamic patterns before answer lookup so malformed optional questions fail closed even when unanswered. - Match JavaScript UTF-16 code-unit length semantics for text constraints and the 100,000-unit response-field bound. - Preserve the public optional `recommended` question-option field in the versioned schema, generated schema bundle, and Rust validation path. - Return typed validation errors for malformed inputs without panics. - Export the validator from the Rust runner core. - Add table-driven tests for valid, mismatched, malformed, oversized, and numeric-boundary responses. - Document the package-local structured-response boundary. - Add `num-bigint` 0.4 and `num-traits` 0.2 as direct runner-core dependencies for exact arbitrary-length radix parsing and one-step JavaScript Number rounding; update only the package-local runner Cargo lockfile. - Do not change the repository PNPM lockfile, workflows, runnerd selection, server behavior, UI, or migrations. ## Verification - Replay base: `9a9fdf06ee4142f77427db30efccc4c43056f64b` (`master` after #12419 merged). - Exact replay head: `fad92b3fb348b66ddb10dde44b7b060e55c4fe96`. - Stable patch ID: `4d6ffbd519dd081f7ea530977cd965bd4569fc75`; this is the prepared two-commit delta plus the focused cross-language parity fix found during replay review. - The exact delta is 10 files, 712 additions, and 2 deletions, all in `packages/paperclip-runner`. - The package-local `packages/paperclip-runner/runner/Cargo.lock` records the two direct runner-core dependencies; their already-resolved versions and checksums are unchanged. - The question-set schema source, generated TypeScript schema bundle, and protocol manifest hash are updated together; the schema SHA-256 is `42b5441a3d388851dacb6e4500dfd4a17d878eded2e724228078b647e7440d3f`. - GitHub Actions run `33366812025`, attempt 2: **PASSED** on the exact replay head (23/23 jobs passed; a failed-job-only retry cleared one unrelated ACPX runtime-host timeout). - Greptile: **5/5** on the exact replay head with zero unresolved review threads; Superagent, Socket, Snyk, and contributor-trust checks also passed. - No local test result is claimed. GitHub Actions is the authoritative verification environment for this replayed revision. ## Risks - The validator compiles the embedded response schema for each submission. Responses are user-paced and bounded, so this keeps the slice simple without affecting a hot event path. - The persisted question set is the source of truth for identifiers and constraints. A malformed persisted set fails closed. - Numeric input follows the existing structured-question contract, including JavaScript-prefixed syntax. Optional whitespace-only answers are rejected instead of being treated as an omitted value. - Error messages identify the invalid field but do not include answer text. - No production path invokes this validator in this pull request. Request resolution remains the next slice. > 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 with GPT-5.6, 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 or instance-derived details - [ ] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge |
||
|
|
9a9fdf06ee |
feat(runner): drive ACPX provider turns (#12419)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The Rust runner now validates and opens an exact Codex ACPX session and attaches one run/catalog identity > - A live session must start one turn, preserve immutable workspace authority, accept interruption, and consume provider events > - Command acknowledgements and event scope are trust boundaries; disagreement must terminate the session rather than permit divergent state > - The existing reducer already owns bounded state, ordering, correlation, and terminal cleanup > - This pull request connects turn commands and polling only to that reviewed reducer without selecting ACPX in runnerd > - The benefit is a fail-closed execution loop before semantic request resolution and production selection are added ## Linked Issues or Issue Description Refs #12418 Refs #12417 ## What Changed - Start one ACPX turn only after validating a bounded turn identifier, bounded message, and the session's immutable working directory. - Require `turn.start` to acknowledge the exact requested turn before mutating provider state. - Request interruption only for the active turn and require an affirmative cancellation acknowledgement. - Keep the turn active until the authoritative terminal event is polled and reduced. - Poll bounded sidecar events and route every event through the existing scope-first payload/state boundary. - Terminate the sidecar fail closed after a rejected or mismatched turn command, transport failure, or invalid scoped event. - Preserve ordinary local validation failures without mutating or closing an otherwise valid session. - Admit semantic tool calls through the run-scoped authorized tool bridge before returning them to runnerd. - Reduce events and authorize tool calls on candidate clones, then commit both together only after every check passes. - Rotate and scope tool receipts by run and turn; reserve pending, completed, and settled call IDs across both tool bridges so cross-bridge duplicates cannot be re-admitted. - Preserve exact turn correlation through payload, scope, provider state, fake sidecar, and integration fixtures. - Extend the package-local fake sidecar with deterministic turn activity, terminal, acknowledgement-mismatch, and scope-violation modes. - Add integration coverage for happy-path activity/interruption/settlement, local validation, turn mismatch, cancellation mismatch, cross-run denial, receipt rotation, and cross-bridge call-ID reuse. - Document the turn lifecycle boundary. - Do not change dependencies, lockfiles, workflows, runnerd selection, server behavior, UI, or migrations. ## Verification - Replay base: `10cf68295d5457ccf1010db20a06e2951e47162a` (`master` after #12418 merged). - Exact replay head: `1ec18368bdacafafa58720b9e2b982e1b0d11163`. - Stable patch ID: `4b43a5ef2a428850a05b0741d06e7cf4f48ec334`, identical to the prepared four-commit delta plus the focused cross-bridge call-ID reservation fix. - The exact delta is 13 files, 1,855 additions, and 37 deletions, all in `packages/paperclip-runner`; it contains no lockfile, workflow, server, UI, or migration change. - GitHub Actions run `33364033038`, attempt 2: **PASSED** on the exact replay head (23/23 jobs passed; the failed-job-only retry cleared one unrelated flaky server heartbeat test). - Greptile: **5/5** on the exact replay head with zero unresolved review threads; Superagent, Socket, and Snyk checks also passed. - No local test result is claimed. GitHub Actions is the authoritative verification environment for this replayed revision. ## Risks - A sidecar may emit events while a command response is in flight. The transport buffers them, then the session binds the acknowledged turn before polling and reducing those events. - A turn-start rejection can leave provider-native state ambiguous, so command rejection or acknowledgement mismatch terminates the session instead of attempting unsafe reuse. - Interruption does not settle local state; only the validated terminal event clears the active turn. - Any transport or event validation failure terminates the child process so a compromised stream cannot continue. - Call identifiers are authorization identities and remain reserved across pending, completed, and settled states in both bridges. - The package exposes new Rust methods, but no production path invokes them in this pull request. - Tool authorization is atomic with reducer state, but tool results, structured input, and permission resolution remain later slices. > 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 with GPT-5.6, 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 - [ ] 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 |
||
|
|
10cf68295d |
feat(runner): bootstrap ACPX provider sessions (#12418)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The Rust runner now has bounded ACPX transport, scope, payload, normalization, and state-reduction layers > - A live provider needs a lifecycle owner that starts the sidecar and proves it opened the exact requested session > - The initial production slice is Codex-only and must fail closed on capability, model, identity, policy, or catalog drift > - Failed bootstraps must not leak a child process, and ordinary shutdown must preserve resumable provider state > - This pull request adds that package-local lifecycle without selecting ACPX in runnerd > - The benefit is a reviewable bootstrap/recovery boundary before turn commands and production selection are connected ## Linked Issues or Issue Description Refs #12417 Refs #12416 ## What Changed - Add a package-local ACPX provider session configuration and lifecycle owner. - Reject non-UTF-8 runtime and working directories before spawning so JSON path serialization cannot panic. - Validate the sidecar launch contract, Codex-only agent, model, run and session identifiers, absolute directories, positive JSON-safe catalog revision, pinned permission mode, bounded instructions, and canonical authorized tool catalog before spawning. - Verify the initialization protocol version, child PID, persistent-session support, exact-model support, runner-owned permission policy, semantic-tool bridge, and structured-input contract. - Open an identity-bound session and require the requested and effective models, permission mode, session identifier, digests, and optional recovery identity to match exactly. - Attach the run and require the sidecar to confirm the exact run identifier and catalog revision. - Retry failed transport cleanup while retaining lifecycle ownership; terminate the sidecar after every failed bootstrap and on an unclosed session drop. - Close sessions without discarding persistent state and make explicit shutdown idempotent. - Extend the package-local fake sidecar with deterministic bootstrap, wrong-model, and wrong-run responses. - Add five integration tests covering successful bootstrap/shutdown, pre-spawn policy validation, model mismatch, run mismatch, and recovery identity matching. - Document the session bootstrap boundary. - Do not change dependencies, lockfiles, workflows, runnerd selection, server behavior, UI, or migrations. ## Verification - Replay base: `f038633bf5b04163ff985ef0542876bd9f455379` (`master` after #12417 merged). - Exact replay head: `a6d9ad62f20fdb47a1dbc76aa4baa9d8fa6dae53`. - Stable patch ID: `82b6f2551749598a688c3f44a1a3714516030429`, identical to the reviewed `e6e550f9..d51a8855` delta. - The exact delta is 5 files and 609 additions, all in `packages/paperclip-runner`; it contains no lockfile, workflow, server, UI, or migration change. - Focused Rust lifecycle, package, repository, security, and Greptile checks: **PASSED** on the replayed exact head. Full CI run `33362799786` is green; its failed-job retry passed one unrelated flaky server shard without a patch change. Greptile is exact-head 5/5, all security checks pass, and no review threads remain unresolved. - No local test result is claimed. GitHub Actions is the authoritative verification environment for this replayed revision. ## Risks - This lifecycle owns a child process and session identity. Configuration is fully validated before spawning, every bootstrap response is checked against the child PID and requested identity, and failed bootstrap always terminates the process. - Recovery identity matching is exact so a persisted native record cannot silently attach to another session, model, workspace, profile, or permission policy. - Explicit shutdown preserves persistent provider state; a dropped unclosed session still terminates its process group as a safety fallback. - The package exports a new Rust module, but no production path constructs it in this pull request. - Turn commands, event polling, request resolution, and runnerd selection remain later slices. > 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 with GPT-5.6, 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 - [ ] 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 |
||
|
|
f038633bf5 |
feat(runner): reduce ACPX provider state (#12417)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The Rust runner now has bounded ACPX transport, scope, payload, and provider-neutral normalization layers > - A live provider still needs state across events to correlate requests and preserve turn ordering > - That state must not mutate before scope and payload validation succeeds > - It must bound retained text and pending values, suppress repeated reasoning boundaries, and make one semantic result authoritative > - This pull request adds that reducer without issuing process commands or selecting ACPX in runnerd > - The benefit is a separately reviewable state machine before transport commands and production selection are connected ## Linked Issues or Issue Description Refs #12416 Refs #12415 ## What Changed - Add a package-local ACPX provider state reducer with one run binding and one active turn. - Decode every sidecar event through the existing scope-first payload boundary before state mutation. - Bound retained assistant text, pending semantic tool inputs, and pending runtime request values. - Correlate semantic tool calls, structured input requests, and permission requests by stable IDs. - Keep pending tool resolution two-phase so callers remove state only after a later sidecar command succeeds. - Carry authoritative tool classification from validated payloads into retained state. - Suppress repeated reasoning-start activity within one turn. - Accept one semantic result idempotently and fail closed on a conflicting result. - Flush the final assistant message before the authoritative terminal event. - Clear unresolved turn-scoped requests at terminal state and reject late events for the settled turn. - Admit redacted global process and diagnostic events without requiring an active turn. - Add seven integration tests for turn ordering, correlation, conflicts, scope-before-mutation, redaction, and terminal cleanup. - Document the state boundary. - Do not change dependencies, lockfiles, workflows, runnerd selection, server behavior, UI, or migrations. ## Verification - Replay base: `7bb6cebeae727a16c205bb80b5c2b9e92ea6b5fa` (`master` after #12416 merged). - Exact replay head: `da82e7f67ecd6f0f2184f303b1b703721099cd86`. - Stable patch ID: `3027df409450d08b2c32383585597a39e06c6f53`, identical to the reviewed `f9cb4e54..e6e550f9` delta. - The exact delta is 4 files and 720 additions, all in `packages/paperclip-runner`; it contains no lockfile, workflow, server, UI, or migration change. - Focused Rust state, package, repository, security, and Greptile checks: **PASSED** on the replayed exact head. Full CI run `33362166929` completed successfully, Greptile is exact-head 5/5, all security checks pass, and no review threads remain unresolved. - No local test result is claimed. GitHub Actions is the authoritative verification environment for this replayed revision. ## Risks - This reducer owns security-sensitive correlation and terminal ordering, so its only raw-event entry point always invokes scope-first decoding. - Pending resolution methods must be called only after the corresponding sidecar transport command succeeds; the later process adapter owns that sequencing. - Terminal events intentionally clear unresolved turn-scoped requests so late tool or input results fail closed. - One semantic result remains readable after terminal state for later durable finalization and is cleared only when a new turn begins. - The package exports a new Rust module, but no production path constructs it in this pull request. > 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 with GPT-5.6, 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 - [ ] 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 |
||
|
|
7bb6cebeae |
feat(runner): normalize ACPX provider events (#12416)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The Rust runner now admits ACPX sidecar frames only after transport, scope, and payload validation > - Valid payloads still contain provider-native runtime event shapes > - Provider-native shapes must not cross the PRP boundary or diverge from direct Codex task activity > - This pull request maps the display-safe runtime subset into existing provider-neutral event families > - Stateful semantic-result, terminal, and reasoning-deduplication behavior remains reserved for the later provider adapter > - The benefit is a reviewable normalization boundary without selecting ACPX in production ## Linked Issues or Issue Description Refs #12415 Refs #12414 ## What Changed - Normalize validated ACPX text, reasoning, plan, status, tool, notice, and error updates into existing PRP activity families. - Keep reasoning contents private while preserving a reasoning activity boundary. - Map plan entries, usage, review-mode status, and tool lifecycle into bounded canonical payloads. - Generate one shared ACPX sidecar event/classification contract for TypeScript and Rust, with ASCII-only classification parity and bounded kind/title fields. - Preserve authoritative tool-call identity and classification even when the aggregate native event exceeds the generic frame budget. - Resolve display-only tool targets within the workspace under the provider host's path semantics; reject raw, unmarked, absolute, parent-traversing, URL-shaped, and unsafe drive-shaped values. - Redact and digest retained tool output with the existing durable policy. - Ignore provider inventory status updates that have no user-facing activity. - Leave semantic results and `done` updates to the stateful adapter so durable receipts and terminal events are not duplicated. - Add cross-language and Rust coverage for every mapping family, classifier parity, privacy, unsafe paths, redaction, bounded titles/kinds, and oversized tool-call preservation. - Document the normalization and display-path authorization boundary. - Do not change dependencies, lockfiles, workflows, runnerd selection, server behavior, UI, or migrations. ## Verification - Replay base: `fe2ddfad2b5cb604b3244492257db0e6aec11d47` (`master` after #12415 merged). - Exact replay head: `b7f5588bf6e8e0f946ffa8869a3204c344808418`. - Stable patch ID: `fda62c7c20afc5ef9c75d07f163a466db82efabd`, identical to the prepared six-commit delta plus the focused oversized-tool-call review fix. - The exact delta is 14 files, 1,714 additions, and 60 deletions, all in `packages/paperclip-runner`; it contains no lockfile, workflow, server, UI, or migration change. - Focused protocol-generation, TypeScript sidecar, Rust normalization, package, repository, security, and Greptile checks: **PASSED** on the replayed exact head. Full CI run `33361437835` completed 23/23 jobs successfully, Greptile is exact-head 5/5, all security checks pass, and no review threads remain unresolved. - No local test result is claimed. GitHub Actions is the authoritative verification environment for this replayed revision. ## Risks - This code controls what provider activity is retained and displayed, so malformed native values must not bypass the earlier decoder. - The function contract requires an already scope-checked and payload-validated runtime event; the future adapter must preserve that order. - Tool classification and identity are security-relevant authorization inputs and remain explicit even when optional aggregate display data is dropped for bounds. - Repeated reasoning chunks require stateful suppression. This mapper exposes a privacy-safe start boundary and the later adapter owns per-turn deduplication. - Semantic results and terminal authority intentionally produce no activity here; the later adapter must commit them through the durable operational paths. - The package exports new generated and Rust normalization surfaces, but no production path invokes them in this pull request. > 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 with GPT-5.6, 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 - [ ] 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 |
||
|
|
fe2ddfad2b |
feat(runner): validate ACPX event payloads (#12415)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The runner needs a bounded process boundary for each qualified provider runtime > - The ACPX transport now verifies frame shape, sequence, run scope, and turn scope > - The sidecar schema keeps event payloads open so each event family needs a second validation boundary > - A later provider adapter must not retain or act on malformed payload fields > - This pull request validates and redacts package-local payloads and keeps the provider unselected > - The benefit is a typed fail-closed boundary before provider state or semantic tools can consume an event ## Linked Issues or Issue Description Refs #12414 Refs #12412 ## What Changed - Decode sidecar payloads only after run and turn scope validation passes. - Limit each decoded payload to 256 KiB. - Add typed payload variants for runtime events, permission requests, input requests, semantic tool calls, terminal events, process events, and diagnostics. - Admit only the nine runtime event shapes emitted by the reviewed Codex ACPX sidecar. - Validate runtime text, plan entries, tool locations, semantic result identities, notices, errors, and terminal status values. - Validate input requests against `paperclip.question_set.v1`. - Reject duplicate question IDs and duplicate option IDs within one question. - Require bounded control identities and object-shaped operational values. - Redact diagnostic, error, process, permission, tool, and retained runtime values before they can enter provider state. - Add six integration tests for every admitted shape, malformed values, scope-before-decode ordering, size limits, question ambiguity, and secret redaction. - Document the payload boundary. - Do not change dependencies, lockfiles, workflows, runnerd selection, server behavior, UI, or migrations. ## Verification - Replay base: `3db24d9366831559b1219782475e760ec041b639` (`master` after #12414 merged). - Exact replay head: `de045b42b5b52cca6c3021380747c56693ccd179`. - Stable patch ID: `90a6f0ed68b2ca7fa5397a8bf93e5e95df5bb58c`, identical to the reviewed `972a3b38..9bb85e93` delta. - The exact delta is 4 files and 806 additions, all in `packages/paperclip-runner`; it contains no lockfile, workflow, server, UI, or migration change. - Focused Rust payload, package, repository, security, and Greptile checks: **PASSED** on the replayed exact head. Full CI run `33360832792` completed 23/23 jobs successfully, Greptile is exact-head 5/5, all security checks pass, and no review threads remain unresolved. - No local test result is claimed. GitHub Actions is the authoritative verification environment for this replayed revision. ## Risks - This decoder is a security boundary because later code can act on decoded semantic tool calls and input requests. - It validates event authority before it inspects a payload. - It fails closed on unknown runtime event types, malformed fields, ambiguous question identifiers, unsupported terminal states, and oversized payloads. - It applies the existing durable redaction policy to retained values. - The package exports a new Rust module, but no production path constructs it in this pull request. - A later provider adapter must preserve this validation order and must not consume raw sidecar payloads directly. > 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 with GPT-5.6, 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 - [ ] 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 |
||
|
|
3db24d9366 |
feat(runner): bind ACPX event scope (#12414)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The runner needs a bounded process boundary for each qualified provider runtime > - The package now has a fail-closed transport for the Codex ACPX sidecar > - A valid sidecar frame can still name the wrong run or turn > - A later provider adapter must reject those events before it maps or persists them > - This pull request adds package-local run and turn scope validation and keeps it unselected > - The benefit is an explicit authorization boundary without a production behavior change ## Linked Issues or Issue Description Refs #12412 Refs #12410 ## What Changed - Add an `AcpxEventScope` for one run and at most one active turn. - Validate run and turn identifiers before they enter scope state. - Make repeated binding of the same turn safe. - Reject a second active turn and a stale turn clear. - Require exact run and active turn bindings for operational, tool, input, permission, and terminal events. - Permit process and diagnostic events without a scope because they can describe the sidecar process itself. - Validate every optional run or turn binding on process and diagnostic events. - Add an integration-test file for all seven event families, missing scope, cross-run scope, cross-turn scope, inactive turns, turn lifecycle, and invalid identifiers. - Document the event authorization boundary. - Do not change dependencies, lockfiles, workflows, runnerd selection, server behavior, UI, or migrations. ## Verification - Replay base: `75708fec6d421a247ba2fc832997de24ed10a085` (`master` after #12412 merged). - Exact replay head: `88bb248442b8f628c20e977d2c2dbc21d85fb6dd`. - Stable patch ID: `0b6443b1bc32ed244f650936026367dd84bcfd65`, identical to the reviewed `c5654218..972a3b38` delta. - The exact delta is 4 files and 280 additions, all in `packages/paperclip-runner`; it contains no lockfile, workflow, server, UI, or migration change. - Focused Rust scope, package, repository, security, and Greptile checks: **PASSED** on the replayed exact head. Full CI run `33360199404` completed successfully, Greptile is exact-head 5/5, all security checks pass, and no review threads remain unresolved. - No local test result is claimed. GitHub Actions is the authoritative verification environment for this replayed revision. ## Risks - Event scope is a security boundary because it rejects data from another run or turn. - The validator fails closed on missing, malformed, stale, or cross-scope identifiers. - Process and diagnostic events can remain global, but any scope they provide must be valid. - The package exports a new Rust module, but no production path constructs it in this pull request. - A later provider adapter must bind and clear the exact turn around each sidecar turn. > 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 with GPT-5.6, 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 - [ ] 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 |
||
|
|
75708fec6d |
feat(runner): add ACPX sidecar transport (#12412)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The runner needs a bounded process boundary for each qualified provider runtime > - The package now provides a reviewed Codex-only ACPX sidecar executable > - Runnerd does not yet have a strict client for that sidecar protocol > - A later provider adapter must not mix process transport defects with provider mapping > - This pull request adds the package-local Rust transport and keeps it unselected > - The benefit is a tested fail-closed boundary for the later Codex provider adapter without a production behavior change ## Linked Issues or Issue Description Refs #12410 Refs #12386 ## What Changed - Add a Rust client for the generated ACPX sidecar v2 contract. - Validate the executable path, launch arguments, request timeout, and shutdown grace before process start. - Require exact request identities and contiguous event sequence numbers. - Reject replayed events, sequence gaps, wrong response identities, malformed frames, unknown fields, and unsupported protocol versions. - Bound stdout frames to 1 MiB and buffered events to 512 entries. - Bound event poll timeouts to 120 seconds before any `Instant` arithmetic. - Buffer valid events that arrive while a command waits for its response. - Treat an empty event poll as a normal timeout without poisoning the transport. - Discard retained events and reject all polling after a terminal transport failure. - Terminate the process group after a timeout, transport failure, or protocol failure. - Keep a valid sidecar command rejection separate from a transport failure so the next command can run. - Redact and bound stderr diagnostics before they enter an error. - Add a deterministic fake sidecar and twelve integration tests for success, polling, timeout bounds, poisoned queues, replay, gaps, identity mismatch, rejection, event floods, oversized frames, and secret redaction. - Document that the transport remains package-local and does not change runnerd provider selection. - Do not change dependencies, lockfiles, workflows, runnerd selection, server behavior, UI, or migrations. ## Verification - Replay base: `9ad8dbffa0a4759dcda2769042d6e8f02adcdf8d` (`master` after #12410 merged). - Exact replay head: `5c41111c4f9564405a6e87a02b6cf253a4424e5f`. - Stable patch ID: `60aca2620fdbb73fbbc203e928d39dcd450e085b`; this preserves the reviewed `1334a7f5..c5654218` six-file delta and keeps trusted bounded-reader failures distinct from fully redacted child stderr. - The exact delta is 6 files and 896 additions, all in `packages/paperclip-runner`; it contains no lockfile, workflow, server, UI, or migration change. - Focused Rust transport, package, repository, security, and Greptile checks: **PASSED** on the replayed exact head. Full CI run `33359202433` is green; its failed-job retry passed the two unrelated flaky jobs without a patch change. Greptile is exact-head 5/5, all security checks pass, and no review threads remain unresolved. - No local test result is claimed. GitHub Actions is the authoritative verification environment for this replayed revision. ## Risks - The transport crosses an untrusted process boundary and is security-sensitive. - It fails closed on malformed frames, identity drift, event replay, sequence gaps, queue overflow, frame overflow, timeout, process exit, and channel failure. - A terminal failure clears retained events before it marks the transport unavailable. - It redacts and bounds retained diagnostics before it returns them to a caller. - A valid remote command rejection does not corrupt the transport state. - The package exports a new Rust module, but no production path constructs it in this pull request. - The later provider adapter must validate run, turn, session, model, and tool bindings before it selects this transport. > 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 with GPT-5.6, 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 - [ ] 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 |
||
|
|
0834a0c1f7 |
feat(runner): bind ACPX profile boundary (#12387)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The Paperclip runner needs a safe boundary before it can launch ACP-compatible agents. > - A caller-controlled command, model, environment, or frame could bypass that boundary. > - The ACPX transport contract in #12386 defines the allowed messages but does not bind a runtime profile. > - This pull request defines closed, versioned profiles and validates the launch inputs around that contract. > - The benefit is a small and reviewable trust boundary before any ACPX process can become available. ## Linked Issues or Issue Description **Agent or provider** ACPX sidecar support for the qualified Pi, Claude, and Codex ACP servers. **Why this adapter is useful** The runner needs one bounded process boundary for ACP-compatible providers. A closed profile prevents an untrusted run from selecting an arbitrary executable, package version, or model. **How the agent is invoked** A later pull request will launch an internal sidecar from an exact profile. This pull request only validates profiles, environment values, and protocol frames. It does not add an executable dependency or enable an adapter. **Additional context** This pull request is stacked on #12386. It keeps the existing direct adapters and the Codex runner path unchanged. ## What Changed - Add a closed profile table for the qualified Pi, Claude, and Codex ACP servers. - Require the exact qualified model and return an isolated profile value to callers. - Add an agent-specific environment allowlist with entry and aggregate size limits. - Add strict parsing for bounded sidecar requests and structured plan values. - Reject unknown fields, unsupported protocol versions, invalid identifiers, null bytes, cyclic values, and oversized input. ## Verification - Runner TypeScript typecheck — passed. - Runner TypeScript tests — 40 files and 362 Vitest tests passed; 11 Node contract tests passed. - `pnpm -r typecheck` — passed for all applicable workspaces. - `pnpm build` — passed, including runner binary, server, UI, and workspace packages. - Prettier and `git diff --check` — passed. - The diff contains 6 files and does not change `pnpm-lock.yaml`, a workflow, a package dependency, or a public export. ## Risks The main risk is accepting more launch state than the sidecar needs. The implementation uses an agent-specific allowlist, rejects null bytes, and enforces per-entry and aggregate bounds. This pull request does not launch a process or expose a new adapter, so production and direct-adapter behavior remain unchanged. ## 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 linked an existing public item or described the issue in this PR - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal task identifier - [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 compatibility and security boundary - [ ] All applicable GitHub Actions are green - [ ] Greptile is 5/5 with every actionable comment resolved - [x] I will address all review findings before requesting merge |
||
|
|
e13856eb37 |
feat(runner): define ACPX sidecar contract (#12386)
## Thinking Path > - Paperclip Runner now has a complete guarded Codex vertical slice. > - The next provider series must not start by importing a provider implementation or dependency bundle. > - ACPX needs one bounded, versioned process boundary shared by TypeScript and Rust. > - A schema is the authority; checked-in generated inventories keep both languages in lockstep. > - Unknown versions, commands, event types, and properties must fail closed. > - This pull request therefore lands only the sidecar wire contract and its drift gate. > - No ACPX runtime, dependency, executable, package export, or production selection is added. ## Linked Issues or Issue Description This is the first package-local unit in the post-Codex provider series. **What happened?** The integration branch contains an ACPX provider, but its TypeScript sidecar and Rust client need a small shared authority before either implementation can be reviewed safely. Importing the final integration implementation directly would mix the protocol, runtime, third-party dependencies, and production wiring. **Expected behavior** The schema defines every ACPX sidecar request, response, event, command, event type, and protocol version. Generated TypeScript and Rust inventories must drift-check against that schema. No runtime can select or execute ACPX yet. **Steps to reproduce** 1. Change the protocol version, command inventory, or event inventory in the schema. 2. Run the runner protocol type check without regenerating the language inventories. 3. Observe the drift gate fail. **Paperclip version or commit** Stacked on `runner-server-semantic-codex` at `ebd7f9df7`. ## What Changed - Add the internal ACPX sidecar v2 JSON Schema outside the public PRP v1 schema catalog. - Generate one TypeScript inventory and one Rust inventory from that schema. - Add generate and check hooks to the existing runner protocol-type workflow. - Add fail-closed AJV tests for all three message families, version drift, unknown commands, and extra properties. - Keep the generated Rust module unregistered until the Rust ACPX transport exists. ## Compatibility Boundary - Codex remains the only production runner provider. - `paperclip_runner` selection and the default-off rollout flag are unchanged. - No ACPX package, patch, lockfile, binary entry point, root export, server file, UI file, workflow, or dependency is added. - The schema is shipped with the existing `protocol` directory but is not added to the public PRP manifest. - Existing direct adapters continue through their current paths. - Diff against the actual stacked base: 6 files. ## Verification - Runner TypeScript typecheck and both generated-contract drift gates — passed. - Runner TypeScript tests — 37 files and 355 Vitest tests passed; 11 Node contract tests passed. - Rust provider-bridge regression suite after restacking — 14/14 passed. - `pnpm -r typecheck` — passed for all applicable workspaces. - `pnpm build` — passed, including runner binary, server, UI, and workspace packages. - `pnpm test:run` — attempted; the local host reproduced unrelated workspace/Postgres and port-exposure failures in unchanged server suites. The changed runner contract suites pass, and the repository's serialized/sharded GitHub checks remain authoritative for those host-sensitive suites. - Prettier, rustfmt, generated-source drift checks, and `git diff --check` — passed. - `pnpm-lock.yaml` is unchanged. ## Risks The main risk is allowing schema and generated language inventories to diverge. Build and typecheck now fail on any drift. The sidecar implementation and third-party ACPX packages are deliberately absent, so this PR cannot alter runtime behavior or expand the production attack surface. ## 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 - [x] I have described the issue and expected behavior in this PR - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal task identifier - [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 compatibility and security boundary - [ ] All applicable GitHub Actions are green - [ ] Greptile is 5/5 with every actionable comment resolved - [x] I will address all review findings before requesting merge |
||
|
|
7a3abb88a0 |
feat(runner): authorize server Codex tools (#12385)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The hidden native coordinator already computes a run-scoped semantic tool projection. > - The durable Codex backend now accepts and enforces that projection. > - The server did not include the projection in its `run.prepare` command. > - Codex therefore received no production semantic tools even when the server authorized them. > - This pull request adds the deterministic wire projection and sends it to runnerd. > - The benefit is one fail-closed authorization catalog from the server through Codex. ## Linked Issues or Issue Description Refs #12384 **What existing behavior does this improve?** This improves the existing flagged Paperclip Runner Codex path. **Current behavior** The server creates a run-scoped list of authorized read tools. It does not pass that list to runnerd, so the production Codex session starts with no tools. **Proposed behavior** The server maps the authorized definitions to the versioned runner contract. It computes a cross-language catalog digest. It includes that immutable contract in `run.prepare`. **Reason and benefit** Runnerd and the server now enforce the same catalog identity. Unknown, duplicate, changed, or malformed tool contracts fail before Codex can use them. **Breaking changes** None. Direct adapters are unchanged. A native run with an empty server projection still starts with no dynamic tools. ## What Changed - Add a deterministic semantic-definition to runner-authorization projection. - Match the Rust canonical digest with a shared test vector. - Include the server coordinator projection in the native Codex `run.prepare` command. - Extend the native Codex vertical slice to require and execute a semantic tool. - Verify the production prepare payload in a host-independent server test. ## Verification - `pnpm --filter @paperclipai/paperclip-runner test:typescript` (354 tests pass) - `pnpm --filter @paperclipai/server exec vitest run src/services/native-runtime/native-codex-runner.test.ts` - `pnpm --filter @paperclipai/server typecheck` - `pnpm -r typecheck` - `pnpm build` - The embedded-Postgres vertical slice is present for CI. This local host reports that embedded Postgres is unavailable, so Vitest skips that host-dependent test locally. - Confirmed that the PR changes 7 files against `runner-codex-durable-tools`. - Confirmed that `pnpm-lock.yaml` is unchanged. ## Risks The main risk is a catalog digest mismatch between TypeScript and Rust. Both implementations use canonical JSON. They share the same fixed digest vector. Runnerd also recomputes the digest and rejects a mismatch. The rollout flag and the existing native runtime selection rules remain unchanged. ## 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 |
||
|
|
6c85fa060e |
feat(runner): durably reconcile Codex tools (#12384)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The Paperclip Runner gives an agent a durable execution boundary. > - The Codex transport can now advertise a run-scoped semantic tool catalog. > - The durable backend did not yet persist tool calls or correlate their results. > - A restart could therefore lose the boundary between a provider call and a Paperclip action. > - This pull request binds authorized calls, durable events, results, replay, and cancellation. > - The benefit is safe semantic tool recovery without duplicate Paperclip actions. ## Linked Issues or Issue Description Refs #12382 **What existing behavior does this improve?** This improves the durable Codex provider backend in `@paperclipai/paperclip-runner`. **Current behavior** The Codex transport can project authorized dynamic tools. The durable backend rejects their calls because it cannot persist and recover their identities. **Proposed behavior** The durable backend records each authorized call before it emits the semantic input event. It records each result before it sends the result to Codex. It reconciles exact provider replays without another Paperclip action. **Reason and benefit** This order prevents duplicate semantic actions after a process restart. It also keeps unauthorized, changed, oversized, and late calls closed. **Breaking changes** None. A run without an authorized tool catalog still starts Codex with no dynamic tools. ## What Changed - Persist the authorized tool catalog with the Codex provider state. - Emit correlated and redacted semantic input, reconciliation, and result events. - Reconcile exact pending and completed calls after a provider restart. - Reject catalog drift, changed replay input, malformed results, and unauthorized operations. - Complete pending tool calls with a durable failure when a turn stops. - Bound retained tool values and validate recovered state before provider startup. - Bind production runner events to the active run, session, turn, and item identities. ## Verification - `cargo fmt --all -- --check` - `cargo test --workspace` - `pnpm -r typecheck` - `pnpm build` - Confirmed that the PR changes 9 files against `runner-codex-dynamic-tools`. - Confirmed that dependency installation did not change `pnpm-lock.yaml`. ## Risks The main risk is a mismatch between recovered provider state and the controller tool catalog. Recovery validates the complete catalog and its digest before Codex starts. The backend persists a call before it emits work and persists a result before it returns the result to Codex. This PR does not enable the server adapter or change any direct adapter path. ## 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 |
||
|
|
cf6db7b523 |
feat(runner): bridge Codex dynamic tools (#12382)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The native runner keeps provider execution separate from Paperclip tool authority. > - The Rust authorization bridge can now validate a run-scoped semantic tool catalog. > - Codex still needs a bounded protocol adapter for that validated catalog. > - The adapter must advertise the same catalog after provider recovery. > - The adapter must reject unadvertised calls and mismatched results. > - This pull request adds that Codex-only transport boundary. > - The benefit is a fail-closed provider bridge that remains inactive until durable wiring supplies tools. ## Linked Issues or Issue Description **Subsystem affected** `packages/paperclip-runner` and its Rust Codex app-server provider. **Problem or motivation** The native runner has a validated semantic tool catalog, but the Rust Codex provider cannot project that catalog or correlate Codex tool calls with Paperclip results. A resumed Codex thread also needs the same run-scoped catalog. **Proposed solution** Add an explicit Codex start path that accepts validated tools. Send those tools through `dynamicTools` for both thread start and thread resume. Validate thread, turn, call, operation, result identity, and size before data crosses the provider boundary. **Roadmap alignment** This work supports the shipped governed MCP Tool Gateway and self-healing run milestones. It does not add a user-facing adapter or enable the experimental runner. ## What Changed - Add a Codex dynamic-tool projection for explicit authorized tool sets. - Advertise the same tool set on new and resumed provider threads. - Correlate bounded Codex tool calls and Paperclip semantic results. - Reject calls outside the active thread or turn, unadvertised tools, reused request identities, mismatched results, and oversized values. - Keep the current durable backend on the zero-tool path until the next wiring change. - Extend the fake Codex app server and integration tests for success, recovery, denial, and correlation behavior. ## Verification - `cargo test --manifest-path packages/paperclip-runner/runner/Cargo.toml --workspace` - `cargo clippy --manifest-path packages/paperclip-runner/runner/Cargo.toml --workspace --all-targets -- -D warnings -A clippy::manual_is_multiple_of -A clippy::filter_map_bool_then` - `pnpm -r typecheck` - `pnpm build` - The PR changes 4 files relative to `runner-rust-semantic-tool-bridge`. ## Risks Low activation risk. The existing `CodexProvider::start` path still supplies an empty tool set. The durable backend treats a tool event as an error until a later PR attaches the durable authorization bridge. The new transport rejects unknown tools and invalid provider bindings. > 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 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 |
||
|
|
3ba0e7f64f |
feat(runner): add durable semantic tool bridge (#12378)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The runner package has a reviewed semantic action catalog and dispatcher > - The Rust runner process needs the same fail-closed authorization boundary > - Provider calls must remain correlated and idempotent across durable recovery > - Input and result values must satisfy the authorized operation schemas > - This pull request adds a package-local durable semantic tool bridge > - It does not advertise tools to Codex or enable the Paperclip Runner adapter ## Linked Issues or Issue Description **Subsystem affected** `packages/paperclip-runner/runner` semantic tool authorization and correlation. **Problem or motivation** The Rust runner needs a durable representation of the run-scoped tools that the control plane authorizes. It must reject unknown operations, catalog drift, invalid values, and conflicting duplicate calls or results before a provider integration can use those tools. **Proposed solution** Add a serialized provider tool bridge. Validate the authorized catalog and its JSON Schemas. Validate each call and result. Keep pending and completed identities so retries are idempotent and conflicts fail closed. **Alternatives considered** Trusting provider arguments would bypass the run-scoped catalog. Validating only in TypeScript would leave the Rust process without a recovery-safe authorization boundary. Adding provider behavior in this pull request would make the review unit too broad. **Roadmap alignment** This adds a package-local safety boundary for the Codex-first runner path. It does not enable a new adapter or change an existing direct adapter path. ## What Changed - Added the versioned authorized-tool, pending-call, and result contracts. - Added canonical SHA-256 catalog binding and drift rejection. - Added JSON Schema compilation and input and response validation. - Added duplicate-call and duplicate-result idempotency with conflict rejection. - Added bounds for catalogs, schemas, values, and retained call identities. - Added the Rust `jsonschema` dependency and its Cargo lock entries. - Added focused tests for authorization, recovery, envelopes, bounds, and conflicts. ## Verification - `cargo fmt --manifest-path packages/paperclip-runner/runner/Cargo.toml --all -- --check` - `cargo test --manifest-path packages/paperclip-runner/runner/Cargo.toml -p paperclip-runner-core` (64 tests) - `cargo clippy --manifest-path packages/paperclip-runner/runner/Cargo.toml -p paperclip-runner-core --all-targets -- -D warnings -A clippy::manual_is_multiple_of -A clippy::filter_map_bool_then` - `pnpm -r typecheck` - `pnpm build` - The repository test runner also reached unrelated server worktree suites. Those suites fail on the current macOS worktree with database deadlocks and filesystem fixture assumptions. This pull request does not change those files. The applicable GitHub checks remain the handoff authority. ## Risks The main risks are accepting a tool that the run did not authorize and replaying a conflicting provider result. The bridge validates the catalog, operation identity, JSON Schema, call identity, and result identity before it changes durable state. The new Cargo dependency is package-local. This pull request changes no GitHub workflow and no pnpm lockfile. ## 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 |
||
|
|
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 |
||
|
|
397de98193 |
feat(runner): add flagged Codex execution adapter (#12188)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The Paperclip Runner now has protocol, provider, tool, package, persistence, and hidden server boundaries. > - The server still cannot select that path for a real agent heartbeat. > - A new runtime must not change any existing direct adapter. > - An experimental runtime must fail closed when its rollout flag is off. > - This pull request adds one guarded Codex vertical slice through runnerd. > - The benefit is a production-built runner path that users cannot start by default. ## Linked Issues or Issue Description Refs #11962 Refs #12111 Refs #12169 Refs #12176 **Subsystem affected** Cross-cutting. The change affects the runner package, server orchestration, shared settings, and adapter configuration UI. **Problem or motivation** The hidden PRP coordinator cannot execute a real heartbeat. The application also needs an explicit rollout boundary before it can expose the experimental runner. Existing direct adapters must keep their current execution and finalization behavior. **Proposed solution** Add `paperclip_runner` as a Codex-only adapter behind the default-off `enableNativeRunner` instance flag. Select the native runtime only for that adapter. Persist the run binding before runnerd starts. Wait for the durable PRP result and terminal event. Resume the real Codex provider thread on later heartbeats. Keep persisted native runs readable and recoverable after the flag changes. **Alternatives considered** The server could route `codex_local` through runnerd. That option would change an existing adapter and weaken rollback safety. The server could expose all providers now. That option would add unreviewed provider behavior. The build could depend on a prebuilt runner binary. That option would make source builds architecture-dependent and difficult to verify. **Roadmap alignment** This work supports the shipped enforced-outcomes, governed-tool, and self-healing-run milestones. It does not add a new roadmap surface. It is the guarded execution step after the merged hidden runner boundaries. **Additional context** This is the next replacement for the closed large runner pull request. Task-thread presentation remains a separate follow-up so this change can preserve the current direct-adapter UI. ## What Changed - Add `paperclip_runner` as an explicit Codex-only adapter. - Add the default-off `enableNativeRunner` instance flag. - Reject fresh create, hire, import, switch, and execution requests while the flag is off. - Allow edits to persisted runner agents while the flag is off. - Recover an already persisted native run even after the flag is disabled. - Keep every built-in direct adapter on its existing runtime path. - Persist an immutable native run binding and revisioned completion contract before runnerd starts. - Execute server to PRP to runnerd to Codex to server through the hidden coordinator. - Validate the durable result against the terminal event and exact completion criteria before finalization. - Preserve the Codex provider thread ID and use `thread/resume` on the next heartbeat. - Strip unsupported Codex configuration fields from the experimental adapter. - Build a target-native release runner binary from source and vendor it into the server distribution. - Install Rust only in the Docker build stage. Do not add a workflow or lockfile change. - Stop the runner process group on completion, cancellation, and forced shutdown. ## Verification - Run `pnpm --filter @paperclipai/paperclip-runner check:all`. All 69 TypeScript tests and 58 Rust tests pass. Protocol, conformance, replay, formatting, and generated-file checks pass. - Run the 12 focused adapter, settings, runtime-selection, coordinator, direct-isolation, and real Codex integration test files. All 186 tests pass. - The real integration test uses PostgreSQL, HTTP, WebSocket, runnerd, and a fake Codex app server. It proves one `thread/start` followed by one `thread/resume`. - Run `pnpm -r typecheck`. - Run `pnpm build`. - Run `pnpm check:token-gates`. - Build the Docker `build` target from a clean context. Confirm that the server distribution contains an executable `paperclip-runnerd` built with Debian Rust 1.85. - Start the server through the source-mode tsx entry point with the package `dist` directory absent. Confirm the vendor shim resolves source exports and the server boots. - Run `pnpm test:run` twice. On this macOS host, 405 files pass and 1 file skips. Eight untouched workspace and loopback tests fail because macOS resolves `/tmp` and `/var` through `/private` and because PID-derived test ports exceed 65535. Linux CI must pass the full suite. - Confirm that the diff contains 52 files. Confirm that it contains no `.github` or `pnpm-lock.yaml` change. ## Risks - The feature flag is off by default. A fresh native start fails with a stable error while the flag is off. - A persisted native run remains recoverable after the flag changes. This prevents rollout changes from corrupting recorded work. - Only local Codex execution is accepted. Other providers and remote work modes fail closed. - Existing direct adapters do not start runnerd, create native rows, use native status arbitration, or enter native finalization. - The runner receives its one-use bootstrap ticket through the child environment. The server does not put the ticket in command arguments or logs. - The server validates the company, task, agent, run, runner, session, completion contract, result, and terminal binding before it accepts completion. - The build compiles a target-native Rust binary. Cross-platform release packaging remains a later concern. Source builds and Docker builds compile for their current target. - Docker needs enough build memory for the existing server TypeScript compile. The Docker build stage sets a 4 GB V8 heap limit. > 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 with GPT-5. The exact deployment ID and context-window size are not exposed. The model used agentic reasoning, repository tools, code execution, and test execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and applicable tests 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 |
||
|
|
4ffa8de4e2 |
Add Codex provider bridge to Paperclip Runner (#12111)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The package-local runner now has a durable PRP transport, but it cannot execute a real provider. > - The first provider must preserve PRP identities while using Codex native thread and turn identities. > - Recovery must resume the same Codex thread without starting a duplicate turn. > - Provider output must become bounded and provider-neutral before it crosses PRP. > - Semantic tools must remain unavailable until the catalog and authorization layers exist. > - This pull request adds the Codex provider bridge inside the runner package only. > - The benefit is a reviewable provider slice with no server or user-facing behavior change. ## Linked Issues or Issue Description **Subsystem affected** Cross-cutting. This pull request extends private provider infrastructure in `packages/paperclip-runner`. **Problem or motivation** The durable runner from #12100 has no production provider. It cannot start Codex app-server, map its events, cancel or steer a turn, deliver a structured question, or recover a native thread after process restart. **Proposed solution** Add a supervised Codex app-server transport and a normalized runner backend. Persist the Codex thread and active turn identities. Resume and inspect the exact thread after restart. Convert supported notifications into bounded PRP events. Keep the dynamic tool inventory empty. **Alternatives considered** The combined runner branch implements several providers, semantic tools, server coordination, and UI integration together. That change is too large for one review unit. Reusing the direct `codex_local` adapter would also couple this package layer to the existing server execution path. **Roadmap alignment** This work supports the governed tools and self-healing run direction in `ROADMAP.md`. It does not add a server endpoint, runtime adapter, rollout flag, or user-facing behavior. **Additional context** Refs #12100 and #11962. Pull request #12100 was squash-merged first. This branch starts at the resulting `master` commit. Its current delta is 16 files. ## What Changed - Added a Codex-only app-server process transport with bounded JSONL frames and buffered notifications. - Added strict provider descriptor validation for the Codex driver, working directory, launch arguments, model, instructions, and non-interactive approval policy. - Started new Codex threads with an empty dynamic tool inventory and the named workspace-only permission profile. - Added native turn start, steering, interruption, cancellation, thread reads, and structured question responses. - Added thread and active-turn binding checks for provider requests and notifications. - Added provider-neutral normalization for session, turn, item, plan, usage, tool execution, notice, and structured input events. - Bounded and redacted provider text and process output before durable persistence. - Added private atomic provider state for the descriptor, thread ID, account session ID, active turn ID, and unacknowledged normalized events. - Added exact-thread recovery through `thread/resume` and `thread/read`. Recovery does not issue another `turn/start` for an active turn. - Preserved active native turn identity across unexpected provider exit and reconciled it before later start, interrupt, or snapshot commands. - Added stable provider-event identities, per-event durable commit and acknowledgement, and a bounded fingerprint receipt journal that prevents duplicate delivery across outbox and provider-ack crash windows. - Extended the durable command executor with provider event polling and explicit process shutdown on stop, suspend, revocation, lease expiry, and runtime expiry. - Preserved completed shutdown behavior when the command result is replayed after a disconnect. - Added a fake Codex app-server and integration tests for response buffering, structured questions, interruption, provider exit, unacknowledged-event recovery, durable resume, and duplicate-turn prevention. - Added a focused `test:codex` package command for the provider integration suite. - Kept server code, UI code, other providers, semantic catalogs, tool authorization, and production runtime selection out of this pull request. ## Verification - `pnpm --filter @paperclipai/paperclip-runner check:all` passes. - TypeScript contract tests pass: 8 Node tests and 44 Vitest tests. - Rust tests pass: 43 unit tests, 5 Codex integration tests, 3 public durable-recovery tests, 2 local-runner tests, and 3 process-supervisor tests. - Rust conformance and replay parity checks pass against the shared PRP fixtures. - `cargo clippy --workspace --all-targets -- -A clippy::filter-map-bool-then -D warnings` passes. The narrow allow covers an unchanged replay implementation from the preceding contract pull request. - `pnpm -r typecheck` passes. - `pnpm build` passes. - `pnpm check:token-gates` passes. - `git diff --check` passes. - The delta against `master` is 16 files. The package lockfile is unchanged. The PR workflow generates its temporary lockfile artifact from the changed package manifest. - `pnpm test:run` completed locally with 4,690 passing tests, 19 skipped tests, and 26 failures in 8 unchanged server test files. The failures reproduce the established local macOS path-alias, listener, port-range, and workspace-runtime baseline. No changed-file test failed. Linux CI remains the repository handoff authority. - Browser and migration tests are not applicable because this pull request changes no server, UI, database, or migration file. - The full Linux PR workflow passes. One unchanged heartbeat recovery test timed out on the first pass and passed on the failed-only rerun; the aggregate `verify` gate is green. - Greptile is 5/5 on the final commit. All four review threads are resolved. ## Risks Production behavior is unchanged because no server code starts this provider. The main risks are a provider process escape, cross-thread event confusion, secret leakage, duplicated turns, duplicated or lost provider events, lost questions, and unsafe recovery. Process-group supervision, identity binding, private bounded state, redaction, durable command replay, retained event acknowledgements, bounded durable receipts, exact-thread reconciliation, and integration tests cover these risks. Semantic tools remain undiscoverable in this layer. I checked `ROADMAP.md`. This change is private provider infrastructure for planned control-plane work. It does not duplicate a shipped or public product surface. ## Model Used OpenAI Codex with GPT-5 was used. The exact serving model ID and context size were not exposed. The model used high reasoning, repository tools, GitHub tools, and local 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 - [ ] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
b76e36d6cf |
Add durable PRP transport and recovery (#12100)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The package-local runner can supervise a local process, but it cannot yet survive a broken controller connection. > - A production transport must authenticate both peers without putting the bootstrap secret on the wire. > - Commands and events must remain bounded, ordered, and recoverable across reconnects and crashes. > - Retrying an uncertain side effect is unsafe, so indeterminate outcomes must fail closed instead of running twice. > - This pull request adds those transport and recovery guarantees inside the runner package only. > - The benefit is a durable PRP boundary that can be reviewed before any provider or server integration exists. ## Linked Issues or Issue Description **Subsystem affected** Cross-cutting. This pull request extends private transport infrastructure in `packages/paperclip-runner`. **Problem or motivation** The local runner introduced by #12095 has no authenticated network handshake, durable outbox, reconnect lease, cumulative acknowledgement, or crash-safe command journal. A dropped connection could otherwise lose an event or tempt a controller to repeat a side effect whose outcome is unknown. **Proposed solution** Add an authenticated PRP v1 WebSocket transport, encrypted frames, lease-based reconnects, a bounded durable event outbox, cumulative acknowledgements, and an idempotent command journal. Preserve pending commands before execution and classify the crash window as indeterminate so an uncertain side effect is never repeated automatically. **Alternatives considered** The combined runner branch implements transport together with Codex, semantic tools, and server coordination. That change is too large for one review unit. Keeping transport in memory would make reconnect and crash recovery unverifiable. Re-running a pending command after restart would weaken the at-most-once side-effect boundary. **Roadmap alignment** This work supports the governed tools and self-healing run direction in `ROADMAP.md`. It does not add a production provider, server endpoint, adapter, feature flag, or user-facing behavior. **Additional context** Refs #12095 and #11962. Pull request #12095 was squash-merged first. This branch has been rebased onto the resulting `master` commit, and its current delta is 13 files. ## What Changed - Added a loopback-only WebSocket connection policy with one-time DNS resolution and pinned reconnect addresses. - Added an HMAC mutual-authentication handshake that never sends the bootstrap ticket over the socket. - Added AES-256-GCM secure frames with per-direction keys, monotonic counters, and session-bound authenticated data. - Added one-use bootstrap-ticket handling and lease-based reconnect validation with expiry, revocation, and epoch checks. - Added a private, symlink-resistant state directory with atomic, synchronized state replacement. - Added a bounded durable event outbox, priority-zero reserve, cumulative acknowledgements, and reconnect replay of only the unacknowledged suffix. - Added a bounded command journal with contiguous sequence enforcement, persistent results, and deterministic duplicate responses. Duplicate replay requires a SHA-256 match over the complete canonical command. - Persisted commands before their effects. A crash after persistence but before result storage returns an indeterminate terminal result and does not execute the command again. - Migrated pre-fingerprint command journals by compacting through their persisted controller cursor. Legacy redelivery fails closed instead of reconstructing an incomplete identity or repeating an uncertain effect. - Added strict limits and validation for frames, state, results, outbox entries, command history, and redacted diagnostics. - Added a transport-only `paperclip-runnerd --connect-url` mode. It handles lifecycle commands and rejects provider commands because no provider is present in this pull request. - Added a full disconnect-before-ack fault test that reconnects with the lease, replays identical command and event state, and proves the effect ran once. - Kept provider transports, semantic tools, server integration, and production runtime selection out of this pull request. ## Verification - `pnpm --filter @paperclipai/paperclip-runner check:all` passes. - TypeScript contract tests pass: 8 Node tests and 44 Vitest tests. - Rust tests pass: 33 unit tests, 3 public durable-recovery integration tests, plus the existing 2 local-runner and 3 process-supervisor tests. - The disconnect-before-ack, lease reconnect, duplicate command, malformed state, unknown command, bounds, and crash-window tests pass. - Rust conformance and replay parity checks pass against the shared PRP fixtures. - `cargo clippy --workspace --all-targets -- -A clippy::filter-map-bool-then -D warnings` passes. The narrow allow covers an unchanged replay implementation from the preceding contract pull request. - `pnpm -r typecheck` passes. - `pnpm build` passes. - `pnpm check:token-gates` passes. - `git diff --check` passes. - The delta against `master` is 13 files. The package lockfile is unchanged. - `pnpm test:run` completed locally with 4,686 passing tests, 19 skipped tests, and 30 failures in 8 unchanged server test files. The failures reproduce the established local macOS path-alias, listener, port-range, and workspace-runtime baseline. No changed-file test failed; Linux CI remains the repository handoff authority. - Storybook visual regression is not applicable because this pull request changes no UI or story files. ## Risks Production behavior is unchanged because no server code starts or connects to this transport. The main risks are secret disclosure, forged or replayed frames, state corruption, unbounded disk growth, duplicated side effects, and incorrect recovery. Mutual authentication, encrypted counter-bound frames, private atomic state, explicit bounds, cumulative acknowledgements, a durable command journal, fail-closed indeterminate recovery, and fault-injection tests cover these risks. I checked `ROADMAP.md`. This change is private transport infrastructure for planned control-plane work. It does not duplicate a shipped or public product surface. ## Model Used OpenAI Codex with GPT-5 was used. The exact serving model ID and context size were not exposed. The model used high reasoning, repository tools, GitHub tools, and local 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 - [ ] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
6b20cc97cc |
Add local fake runner supervision (#12095)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Paperclip Runner needs a small local process model before it can connect to a production provider or server. > - The TypeScript PRP contracts now define the expected replay behavior. > - A second language implementation must produce the same result from the same fixtures. > - Local child processes also need bounded input, bounded output, and complete descendant cleanup. > - This pull request adds a package-local Rust runner, a scripted fake harness, and deterministic parity checks. > - The benefit is a testable process boundary with no production Paperclip behavior change. ## Linked Issues or Issue Description **Subsystem affected** Cross-cutting. This pull request adds private test infrastructure to `packages/paperclip-runner`. **Problem or motivation** The PRP contracts have no second implementation on `master`. There is also no small harness that can prove process cleanup, command idempotency, terminal reconciliation, or bounded JSONL handling without a production provider. **Proposed solution** Add a minimal Rust workspace. Add a local runner process, a scripted fake harness, a bounded process supervisor, and Rust conformance and replay checks. Keep all binaries package-local. Do not connect them to the Paperclip server. **Alternatives considered** The combined runner branch includes provider transports, durable networking, SDKs, labs, and server behavior. That change is too large for this review unit. A TypeScript-only harness would not test cross-language contract parity. **Roadmap alignment** This work supports the governed tools and self-healing run direction in `ROADMAP.md`. It does not add a user-facing runtime, adapter, endpoint, or rollout flag. **Additional context** Refs #12091 and #11962. Pull request #12091 was merged before this branch opened. This branch is based on the current `master`. Its delta is 25 files. ## What Changed - Added a minimal locked Rust workspace with only `serde` and `serde_json` dependencies. - Added a package-local `paperclip-runnerd` local mode and a scripted fake harness. - Added bounded controller input, harness input, subprocess output queues, line sizes, log retention, script sizes, script steps, and command history. - Added contiguous controller and harness sequence checks and equivalent-command replay handling. - Added process-group supervision that cleans up child processes and remaining descendants after forced or natural harness exit. - Added runner-owned terminal reconciliation for success, failure, interruption, cancellation, controller closure, and protocol failure. - Added Rust conformance output and deterministic replay summaries for the shared PRP fixtures. - Added fake scripts for success, failure, interruption, interaction, duplicate terminal output, process cleanup, and oversized output. - Added package scripts and documentation for the Rust and cross-language checks. - Kept provider transport, server integration, semantic tools, and production runtime selection out of this pull request. ## Verification - `pnpm --filter @paperclipai/paperclip-runner check:all` passes. - TypeScript contract tests pass: 8 Node tests and 44 Vitest tests. - Rust tests pass: 20 unit tests, 2 local-runner tests, and 3 process-supervisor tests. - The Rust conformance and replay parity checks pass against the shared fixtures. - The natural-exit and forced-exit tests confirm that the harness and its worker process are stopped. - The oversized-frame test confirms that a harness frame above the configured limit is rejected. - `pnpm -r typecheck` passes after the final rebase to `master`. - `pnpm build` passes after the final rebase to `master`. - `pnpm check:token-gates` passes. - `git diff --check` passes. - The delta against `master` is 25 files. The package lockfile is unchanged. - `pnpm test:run` completed locally with 4,686 passing tests, 19 skipped tests, and 30 failures in 8 unchanged server test files. The failures are local macOS path-alias, listener, port-range, and workspace-runtime baseline failures. No changed-file test failed, and every applicable Linux CI shard passes. - Storybook visual regression skipped intentionally because this pull request changes no UI or story files. ## Risks Low production risk. No server code invokes the new binaries. The package remains private. The main risks are process leaks, unbounded local input, and cross-language drift. Bounded queues and sizes, process-group cleanup tests, fixture manifests, and parity checks cover these risks. I checked `ROADMAP.md`. This change is private test infrastructure for planned control-plane work. It does not duplicate a shipped or public product surface. ## Model Used OpenAI Codex with GPT-5 was used. The exact serving model ID and context size were not exposed. The model used high reasoning, repository tools, GitHub tools, and local 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 - [ ] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: Paperclip <noreply@paperclip.ing> |