mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-10 01:50:13 +01:00
c66b4a55efdc5675b5a5146197078b94de6407da
4
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
612d9931a6 |
Support per-turn Runner sessions on ephemeral web servers (#18932)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The web server controls native Runner sessions in remote sandboxes. > - An ephemeral web server must recover without its previous local filesystem. > - The existing admission rule accepts warm sessions. Managed Claude, Grok, and OpenCode sessions resolve to per-turn execution. > - Per-turn execution also needs durable provider-session bytes after the sandbox is retired. > - This pull request adds encrypted backup publication and removes the warm-only admission rule. > - Both lifecycle modes can use the existing native ownership and checkpoint contracts during a web deployment. ## Linked Issues or Issue Description Refs: #18518, #18529, #18826, #18835, #18841, #18864, #18887. **What existing behavior does this improve?** Native Runner execution on web servers with `PAPERCLIP_EPHEMERAL_SERVER=true`. **Current behavior** The admission rule requires a warm Runner lifecycle. Managed provider credentials can resolve an agent to per-turn execution, so enabling the ephemeral deployment profile blocks those turns. A database controller checkpoint does not preserve provider files after the old web home and per-turn sandbox are removed. **Proposed behavior** Admit native execution in either resolved lifecycle. Keep provider and credential choices unchanged. Publish encrypted provider state to shared storage before sandbox cleanup. Restore it from a fresh web home for the next turn. Use the existing controller lease and generation checks for active takeover. **Reason and benefit** Operators can remove the web server volume without excluding per-turn providers or forcing managed accounts into warm sessions. New native Daytona profiles automatically enter both rolling-deployment qualification lanes. **Breaking changes** The additive migration creates a backup publication ledger. Existing volume-backed local-disk installations retain their local backup path. S3 installations publish encrypted backups and require a stable secrets master key. Existing-volume enrollment must import surviving session data before detaching the volume. ## What Changed - Admit native Runner execution independently of its warm or per-turn lifecycle. Keep host-owned legacy execution excluded from ephemeral deployments. - Store private provider state as encrypted objects. Journal uploads before I/O, read them back, and fence publication against the current native owner. Keep the previous published backup when storage or ownership checks fail. - Restore exact provider bytes into a private cache. Require an exact durable backup before sandbox cleanup. Extend the existing bounded retention pass to retire stored objects without adding idle polling. - Import selected legacy controller and provider state in the existing offline maintenance process. Preserve queued work, task pointers, pending recovery, and original files. Prefer canonical database checkpoints. - Preserve already-failed legacy controllers with missing original artifact proof as encrypted archives. These archives do not become execution authority. Successful retained sessions still require proof. Report archival and executable imports separately. - Verify unmanaged Grok API keys through the existing xAI account validator. The live test exposed a readiness gap that kept remote Grok agents paused after platform checks. Preserve failed credentials and the separate runtime warning. - Ingest Grok whole-prompt usage at the owning ACP boundary. Bind the receipt to the exact outbound request/session; reject replay, conflicts, and incomplete authority. Separate turn cost from cumulative session cost in the sidecar schema and Rust normalization. Preserve managed billing identity and identify direct xAI API credentials. - Preserve published workspace directory names across cold allocations, including destroyed-allocation cleanup. Keep unpublished epoch/lease directories isolated and refuse to overwrite an occupied preparation. This fixes the cold-session identity regression exposed by #18922. - Increase bounded checkpoint-header inspection to 1 MiB. Retain the aggregate inspection limit. - Register all nine native Daytona profiles in per-turn and warm rolling-deployment suites. Delete the entire departing server home, exercise ordinary reads and writes, require active ownership transfer, then check a later turn on another fresh server. Permit only exact notification replay after reconnect. Ownership stays with the existing modules: Runner validates its protocol state; Core validates run scope and controller ownership; storage owns object I/O; the maintenance process owns offline conversion; the E2E wrapper owns process replacement and probes. No provider protocol is added to the shared admission rule. Grok receipt parsing stays in its provider module. The shared sidecar gains an explicit cost basis because its existing price field means session-cumulative spend, while Grok reports prompt totals. Existing consumers retain cumulative behavior when the new field is absent. ## Verification - Focused native admission, archive validation, publication fencing, cleanup, readiness, legacy import, and E2E observer tests pass. Real PostgreSQL cases verify that queued intent and historical recovery rows stay unchanged. - Full typecheck and build pass on the rebased branch. The review follow-up passes server typecheck, 29 focused PostgreSQL/archive/readiness tests, and module-boundary checks. Revision fb8d39a7a1 reached 55 successful CI checks and Greptile 5/5 with no unresolved threads. The Grok follow-up passes Runner/server typechecks, 238 ACP runtime/projection/usage tests, 16 sidecar-schema tests, the Rust cost regression, and Core billing regression. The |
||
|
|
59da15066a |
feat(runner): deliver native Kimi Code (#18391)
Deliver native Kimi Code setup, exact models, scoped credentials, verified packages and runtime packs. Preserve current upstream release attestations and restore verified same-run remote retry dispatch without weakening process ownership. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
abc270ee4c |
fix(runner): attest upstream releases and bind ACPX uniformly for every harness (#18325)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Native ACPX runs admit a provider only when its saved profile and `commandDigest` match the current profile exactly. > - For Copilot, Grok and Pi, `commandDigest` hashed dozens of Paperclip source files. Claude, Codex, Cursor and Antigravity hash only their upstream release. > - Any change to a bound source therefore advanced these profiles. #18212 alone moved Copilot from v88 to v91 and Grok from v15 to v19. Each bump reset in-flight sessions and added immutable identity fixtures (about 160 on master). > - #18237 added the provider pack `contractDigest`, which now guards Runner source compatibility at the pack boundary. > - This pull request changes the Copilot, Grok and Pi digests to upstream release attestations, as the other providers already use. > - It also binds the shared ACPX layer the same way for every ACPX harness: the profile's `acpxVersion` and the pack `contractDigest`, which now covers the Runner's ACPX patch. > - The benefit is that Runner source changes no longer reset these sessions or need new profile versions and fixtures. ## Linked Issues or Issue Description Refs #18237, #18212, #17972. **What happened?** A Runner change that touched a bound source file changed the Copilot, Grok or Pi `commandDigest`. The author had to advance the profile version, regenerate an identity fixture and keep every old fixture. On deploy, saved sessions for that provider failed the exact admission check and started fresh. **Expected behavior** A provider's `commandDigest` changes only when its upstream release changes: an upstream version, a platform closure, the ACPX patch or the Grok launcher. Runner source compatibility is the job of the pack `contractDigest`. **Steps to reproduce** 1. On master, change a comment in `src/drivers/acpx/runtime-host.ts`. 2. Run `node packages/paperclip-runner/scripts/grok-profile-identity.mjs --check`. 3. The check fails. The Grok profile must advance, and the next deploy resets Grok sessions. ## What Changed - Add `packages/paperclip-runner/scripts/acpx-release-attestations.mjs`. It computes the release attestation for each provider: - Copilot and Pi: a canonical-JSON hash of the profile version, upstream package versions and the platform closure pins (Pi also binds its Node version). - Grok: the SHA-256 of `launcher.cjs`. Admission already hashes these bytes. - The attestation binds no Paperclip source, shared ACPX layer, absolute path, pack manifest digest or install layout. - Bind the shared ACPX layer once for every ACPX harness (Claude, Codex, Copilot, Cursor, Grok, Pi, Antigravity): - Add the Runner's ACPX patch (`patches/acpx@<runner acpx version>.patch`) to the pack `contractDigest`. A patch change now retires older image packs for every harness. Other packages' ACPX patches are not read. A build context without the Runner's patch fails. - Remove the ACPX patch hash from Cursor's release declaration (`cursor-contract.json`) and advance Cursor once to profile 17. Copilot, Pi and Cursor no longer bind ACPX in their own digests, like Claude, Codex, Grok and Antigravity. - Saved inputs for every harness already must match the current `acpxVersion`. - Claude and Codex digests do not change. - `generate-acpx-profiles.mjs` writes these digests to `acpx-profiles.json`. `check:acpx-profiles` refuses a stale digest. - Move the Copilot closure pins to `copilot-closure-pins.ts`, so that the generator can import them. `copilot-installation.ts` re-exports them. - Advance each profile once and then freeze it: Copilot 92, Grok 20, Pi 37. A version change at the switch keeps the rollout on the same path as every earlier profile bump. - Replace the historical version lists in `profile-compatibility.ts` with a range. Every revision from 1 through the current one decodes. Claude and Codex still decode revisions 1 through 5. Launch and recovery admission still require the exact current profile and digest. - Delete: - `scripts/copilot-profile-identity.mjs`, `scripts/grok-profile-identity.mjs` and its test - the Grok launcher source stamp - 159 Copilot, Grok and Pi identity fixtures, including three unreferenced `copilot-mainline-v*` fixtures. The Cursor fixtures stay. - Rewrite the affected tests as behaviour checks: - Each provider admits only the exact current profile. Every earlier version decodes and is refused at admission. - The last source-bound digests, and a changed digest at the current version, are refused by recovery and by the backend factory. - The Rust Pi descriptor test uses the generated profile instead of fixtures. - New `acpx-release-attestations.test.mjs`: a relocated copy of the inputs gives the same digests, each upstream input changes only its own providers, and the generator refreshes and checks the manifest. - Remove the fixture exceptions from `.dockerignore`. Add the attestation script and the generator to the Daytona image content inputs. - Update the Pi install probe and the Rust integration constant for the new Pi digest. - Update the docs to describe the current attestation model: `doc/grok-native-runner.md`, `doc/RUNNER-INTEGRATION-PLAYBOOK.md`, `doc/observability.md`, `packages/paperclip-runner/docs/durable-recovery.md`, and the Copilot, Pi and rich ACP architecture reports. Each report now opens with the current profile identity; earlier source-bound profiles remain as dated chronology. No doc references a deleted file. ## Verification - In `packages/paperclip-runner`: - `node --test scripts/acpx-release-attestations.test.mjs scripts/contracts/contract-fingerprints.test.mjs`: 19 tests pass, including a Runner ACPX patch edit that changes the contract digest, other patch edits (including `acpx@0.12.0` for `adapter-utils`) that do not, and a build context without the patch that fails. - `node scripts/generate-acpx-profiles.mjs --check` passes. - `vitest run src/drivers/acpx src/backends src/contracts`: 1647 tests pass, 9 skipped. - `tsc -p tsconfig.json --noEmit` passes. - From the repository root, `vitest run --config tests/runner-e2e/vitest.config.ts tests/runner-e2e/daytona-image.test.ts`: 11 tests pass. - In `server`, the 8 test files that use ACPX profiles, pack digests or `contractDigest`: 1617 tests pass. - Not run locally: the Rust tests and `cargo fmt`, because this machine has no Rust toolchain. CI runs them. - Before this change, a synthetic upgrade check built two Runner revisions that differ only in shared source. A Claude checkpoint saved under the first revision rebinds under the second, and a changed Claude `commandDigest` starts fresh. This confirms that the provider JSON has no other build-dependent field. ## Risks - **One reset at rollout.** The Copilot, Grok, Pi and Cursor digests and versions change once. Saved sessions for these providers start fresh on their next run, as after any earlier profile bump. After this change, Runner source changes no longer cause this reset. - **Lost "source changed, so requalify" signal.** The old digest forced a new profile version when bound source changed. Nothing enforced requalification: Copilot was last qualified at v47. Pack-boundary contract changes are now caught by the pack `contractDigest`. - **Image packs are retired once for every provider.** Adding the ACPX patch changes the pack `contractDigest`, so the controller uploads its bundled pack (about 16 s per remote start) until images are refreshed. Claude and Codex sessions are not reset: their digests and versions do not change. - **Grok launcher and closure pins.** The Grok digest covers only the launcher bytes. Grok's runtime version is still checked separately at admission, as before. - **Grok digest equals early Grok profiles.** The launcher bytes have not changed since profile 1, so the new Grok digest equals the published profile 1 digest. The profile version still separates them: launch, recovery and the backend factory require profile 20. An image pack from that period has no `contractDigest`, so the pack gate refuses it. `remote-provider-pack-verification.test.ts` now covers this case. - **Docker context checks** run `generate-acpx-profiles.mjs --check`, which now imports `.ts` pin files through Node type stripping. `materialize-pi-distribution.mjs` already relies on this on Node 24. ## Model Used - Claude Opus 5.5 (`claude-opus-5-5`) in Claude Code, with tool use (shell, file edits, local test runs). ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
56e09cd19f |
docs: add native Runner integration playbook (#16846)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Native Runner connects those agents to harnesses through provider drivers. > - Adding a harness crosses protocol, setup, lifecycle, packaging, and product boundaries. > - Existing guidance does not provide one complete procedure for this work. > - This pull request adds a native Runner skill, detailed playbook, and working templates. > - Contributors can use them to define a release, implement the integration, and verify the delivered result. ## Linked Issues or Issue Description **Issue type** Missing documentation. **Where is the issue?** Native Runner contribution guidance in `doc/DEVELOPING.md` and `packages/paperclip-runner/README.md`. **What's wrong?** Contributors must reconstruct the requirements, protocol mapping, normal setup, lifecycle rules, packaging, and acceptance process when they add a harness. The legacy direct-adapter recipe covers a different execution path. **Suggested fix** Add a self-contained native Runner procedure. Include capability research, a finite release contract, implementation boundaries, reproducible tests, normal installation, and release evidence. State each lesson directly so contributors need no private chats, tasks, or evidence archives. The duplicate search found no existing playbook PR. ## What Changed - Add `create-runner-adapter` for new native Runner harness integrations. - Add a detailed playbook based on the Pi, Cursor, and Copilot integration lessons. - Cover model and instruction admission, connection setup, rich events, durable interactions, recovery, cancellation, packaging, and Product E2E acceptance. - Add templates for scope, capabilities, attempts, failures, jobs, and release handoff. - Link the procedure from the development guide and Runner README. - Keep legacy adapters as a compatibility boundary. ## Verification - `git diff origin/master --check` passed. - `node scripts/validate-doc-links.mjs` passed from `packages/paperclip-runner` and checked 53 documentation files. - All 71 Markdown links in the new reusable files resolve to repository paths or public provider documentation. - Skill YAML, naming, description, and scaffold checks passed. - A private-reference audit passed for the reusable skill, playbook, and templates. - The legacy direct-adapter skill matches the base version. - Full local runtime checks were attempted with pnpm 9.15.4. `pnpm -r typecheck` stopped because Node type definitions are missing. `pnpm test:run` and `pnpm build` stopped because `cli/node_modules/tsx` is missing. This checkout has no installed dependencies. These commands did not establish runtime test or build results. - Full remote CI passed on commit `88b4fc4832d95807da1f5e48029a183b3dc62b6c`: build, typecheck, general and serialized server tests, Runner checks, browser tests, and the canary dry run. [CI run](https://github.com/paperclipai/paperclip/actions/runs/39262297681). - All 55 applicable checks passed. The two Storybook checks were skipped for this change. - Greptile gave the current commit 5/5. There are no review comments or unresolved threads. ## Risks Low risk. The procedure can drift as the Runner contracts and test entry points change. It records its source baseline and tells contributors to inspect current declarations. Historical lessons describe failure patterns; they do not certify current binaries. ## Model Used OpenAI Codex with `gpt-6-astra` and `gpt-6.1-sol`, both using xhigh reasoning. Context-window sizes were not exposed. The models used repository search, terminal tools, and file edits. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used, including available version and capability details - [x] I have checked ROADMAP.md and confirmed this documentation does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs - [x] I have described the issue in this PR using the documentation issue template fields - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal ticket or instance details - [x] I have run the relevant local documentation checks; they pass. Blocked runtime checks are recorded above - [x] I have considered tests for this documentation-only change and validated its links and skill metadata - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented the 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 merge Co-authored-by: Paperclip <noreply@paperclip.ing> |