mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-25 17:45:53 +01:00
## Thinking Path - Paperclip Runner needs its runtime preinstalled for fast sandbox startup. - Native and local adapters should launch one current CLI installation per provider. - An older global copy can shadow that installation, and exact native compatibility pins must match it. - Update the qualified releases and binary digests, expose shared CLI entrypoints from the provider pack, and prefer the image-owned bin directory. - Keep dependency installation in the image build; task startup only discovers, links, and verifies artifacts. ## Linked Issues or Issue Description **What happened?** Remote native startup rejected a stale global Codex, while CLI-only images lacked runnerd entirely. **Expected behavior** An image-baked runtime starts without uploading binaries or installing packages. All adapters share the same current provider CLI. **Steps to reproduce** Start a native remote task with the old global Codex and the updated runtime available only under `/opt/paperclip-runner/bin`. **Paperclip version or commit** Discovery behavior at `54a99d884`. **Deployment mode** Docker with a remote sandbox. ## What Changed - Prefer `/opt/paperclip-runner/bin`, then the user's local bin directory, then PATH. Existing metadata and version validation remains in force. - Qualify Codex 0.153.4, OpenCode 1.18.29, and Claude SDK 0.3.263 / CLI 2.1.263. Update binary digests, TypeScript/Rust checks, registry defaults, and the displayed OpenCode version together. - Share Codex and Claude's native executable with the ACP bridges through exact dependency overrides. Preserve the separately qualified ACP bridge implementations and their security patches. - Expose shared provider-pack CLI launchers; fail the pack build if Codex ACP resolves a separate Codex installation. Update the eval image's other agent CLIs to current stable releases and remove duplicate global provider installs. - Document the single-current-CLI policy in source comments and development guidance. Latest stable releases are resolved at review/build preparation and pinned; task startup never auto-updates. ## Verification - Native-session and adapter-registry suites: 158 tests passed. - Provider suites: 88 tests passed, 7 Linux-only checks skipped on macOS. One existing macOS temporary-path alias assertion passed when rerun with canonical `TMPDIR=/private/tmp`. - Package-contract and OpenCode materialization tests: 11 passed. - Full typecheck, build, and token gates passed. Rust native-provider/recovery tests: 19 passed. - Broad local suite: 5,974 passed, 23 failed, 41 skipped. Failures are in unchanged macOS workspace/path/port and connection suites; focused runtime tests pass. All latest-head Linux PR checks passed, including the full test shards, typecheck, build, runner verification, browser suites, and canary dry run. - The standalone fleet image built with one current provider CLI each and passed native Codex/Claude binary-integrity checks. A disposable Daytona sandbox reported ready in 798 ms; its baked runner completed an API-key `gpt-5.6-luna` turn in 2,430 ms and returned the expected marker with a usage receipt. No runtime artifacts were uploaded or installed. - The normal shared `codex exec` entrypoint also completed an API-key `gpt-5.6-luna` turn in 2,321 ms. - Both image builds verify the complete generated lockfile against a reviewed SHA-256 before package installation or lifecycle execution. Root lockfile changes remain CI-owned. Merge and rollout remain on hold for operator review. ## Risks - Updating provider CLIs changes their behavior for all adapters; version probes and live native smoke testing are required before image promotion. - The image-owned directory takes precedence. Its entries must launch the same shared CLI as the global PATH, not a private older/newer copy. - Application qualification pins and the deployed image must move together. No startup fallback installation is added. - No schema or authentication-policy changes. ## Model Used OpenAI GPT-6 (Codex). The session does not expose a more specific model ID or context-window size. Used reasoning, repository inspection, code execution, and browser verification. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
80 lines
3.8 KiB
Markdown
80 lines
3.8 KiB
Markdown
# Paperclip Daytona runner image
|
|
|
|
This image is the Paperclip Cloud fleet sandbox image plus a source-built
|
|
`paperclip-runnerd` and immutable provider pack. The pack contains Node 24.11,
|
|
OpenCode 1.18.29, the compiled OpenCode proxy, ACPX 0.13.1 sidecar, qualified ACP
|
|
agents, and the production lockfile. Its manifest digests each executable bridge
|
|
and binds the pack to the runner source revision, avoiding artifact upload and
|
|
npm installation on every fresh lease.
|
|
|
|
The fleet pins are intentionally copied from
|
|
[`paperclip-cloud/fleet-sandbox-image/Dockerfile`](https://github.com/paperclipai/paperclip-cloud/blob/master/fleet-sandbox-image/Dockerfile).
|
|
Update both definitions together until the fleet base is published as a stable
|
|
image that this Dockerfile can extend directly.
|
|
|
|
## Build and verify
|
|
|
|
The fleet image is currently amd64-only because the pinned Cursor and GitHub CLI
|
|
checksums cover amd64.
|
|
|
|
```bash
|
|
content_id="$(pnpm --silent test:e2e:runner:image-id)"
|
|
docker buildx build \
|
|
--platform linux/amd64 \
|
|
--build-arg PAPERCLIP_RUNNER_CONTENT_ID="${content_id}" \
|
|
--build-arg PAPERCLIP_RUNNER_SOURCE_REVISION="$(git rev-parse HEAD)" \
|
|
--tag "paperclip-daytona-runner:e2e-content-${content_id}" \
|
|
--load \
|
|
--file docker/daytona-runner/Dockerfile \
|
|
.
|
|
|
|
docker run --rm --platform linux/amd64 \
|
|
--entrypoint paperclip-runnerd \
|
|
"paperclip-daytona-runner:e2e-content-${content_id}" \
|
|
--build-metadata
|
|
```
|
|
|
|
The metadata must advertise `dial_ws_loopback`, `dial_wss`, and `listen_ws`.
|
|
The explicit entrypoint is needed only for this local probe because Daytona's
|
|
base image uses its own long-running sandbox entrypoint.
|
|
|
|
`test:e2e:runner:image-id` hashes the audited Docker build dependency closure,
|
|
target platform, the immutable Dockerfile syntax-frontend digest, and every
|
|
immutable `FROM` reference. It fails before the paid workflow can build when
|
|
the frontend or a base is not pinned to a sha256 digest. When updating the
|
|
syntax version, resolve and review its registry digest and update both values in
|
|
the first Dockerfile line. Git commits that do not change those inputs reuse the
|
|
same content tag.
|
|
|
|
`PAPERCLIP_RUNNER_SOURCE_REVISION` remains the full Git SHA that built the first
|
|
published copy and is retained as provenance rather than cache identity.
|
|
|
|
## Use in Paperclip
|
|
|
|
Publish the image to a registry Daytona can pull, or use the environment
|
|
editor's **Configure image** flow to produce a Daytona snapshot. Set the
|
|
environment image to that immutable tag or snapshot. Paperclip probes the
|
|
sandbox user's `PATH` for `paperclip-runnerd` and `codex` and checks
|
|
`/opt/paperclip-runner/provider-pack` for OpenCode and ACPX. It uses the pack
|
|
only when its complete manifest matches the controller's build-owned pack;
|
|
otherwise it stages the pack configured by
|
|
`PAPERCLIP_RUNNER_REMOTE_PROVIDER_PACK_PATH`. Remote OpenCode and ACPX never
|
|
fall back to host-local processes.
|
|
|
|
Do not promote `paperclip-runner-e2e-20260826-v2` for OpenCode or ACPX. Build a
|
|
new immutable image or snapshot from a clean committed revision and pass that
|
|
full Git SHA as `PAPERCLIP_RUNNER_SOURCE_REVISION`.
|
|
|
|
Do not bake provider credentials, Paperclip bootstrap tickets, or Daytona
|
|
preview tokens into this image. They remain per-run secret material.
|
|
|
|
Provider CLI updates are manifest-only changes: repository CI owns the root
|
|
lockfile. The image build resolves the complete workspace manifest graph before
|
|
its frozen install, matching CI when a source commit precedes the lockfile bot.
|
|
The complete resolved lockfile must match `PAPERCLIP_RUNNER_LOCK_SHA256` before
|
|
package installation or lifecycle execution. Review and refresh that digest
|
|
with source dependency changes; registry-time resolution drift fails closed.
|
|
Keep one latest stable CLI installation per provider; refresh exact runtime
|
|
versions and qualification digests together, never install a private older copy
|
|
or download dependencies when a task starts.
|