From e65b828648f08d4577e12c6b4773ff5071cd992b Mon Sep 17 00:00:00 2001 From: Dotta Date: Mon, 28 Sep 2026 13:18:54 -0500 Subject: [PATCH] Satisfy Pi distribution policy and refresh candidate fixtures Co-Authored-By: Paperclip --- doc/architecture/runner-pi-capabilities.md | 2 +- .../crates/runner-core/src/acpx_provider_backend.rs | 4 ++-- .../scripts/pi-distribution/package-lock.json | 3 +++ .../scripts/pi-distribution/package.json | 3 +++ .../src/backends/native-backend-factory.test.ts | 13 +++++++++++-- .../src/drivers/acpx/pi-closure-pins.ts | 6 +++--- .../src/drivers/acpx/qualified-profiles.ts | 2 +- 7 files changed, 24 insertions(+), 9 deletions(-) diff --git a/doc/architecture/runner-pi-capabilities.md b/doc/architecture/runner-pi-capabilities.md index d95f6569998..772ddf682e9 100644 --- a/doc/architecture/runner-pi-capabilities.md +++ b/doc/architecture/runner-pi-capabilities.md @@ -224,7 +224,7 @@ initialization and the missing-credential admission path without a model call. The exact reported `currentModelId` and billable receipt still need credentialed local and Linux/Daytona qualification. -Profile version 2 declaration digest: `sha256:c577a771778febe24b920388da77f6143971b8eec29e1ba9a433dac5b76de3cd`. It hashes the versioned +Profile version 2 declaration digest: `sha256:0f687e38cb3c607a01fab80f03e19bbbf5cb53a8afb1fc40d71f9ab54551cff1`. It hashes the versioned profile domain, patched wrapper source and platform closure pins. Every native closure remains independently checked at launch. Version 1 warm sessions cannot be reused with this integration. diff --git a/packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_backend.rs b/packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_backend.rs index 724143fea40..b3306c89d60 100644 --- a/packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_backend.rs +++ b/packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_backend.rs @@ -170,7 +170,7 @@ impl AcpxProviderDescriptor { "0.0.33", Some("@earendil-works/pi-coding-agent"), Some("0.84.2"), - "sha256:c577a771778febe24b920388da77f6143971b8eec29e1ba9a433dac5b76de3cd", + "sha256:0f687e38cb3c607a01fab80f03e19bbbf5cb53a8afb1fc40d71f9ab54551cff1", ), "cursor" => ( self.model.as_str(), @@ -2461,7 +2461,7 @@ mod tests { "pi", "pi-acp", "0.0.33", - "sha256:c577a771778febe24b920388da77f6143971b8eec29e1ba9a433dac5b76de3cd", + "sha256:0f687e38cb3c607a01fab80f03e19bbbf5cb53a8afb1fc40d71f9ab54551cff1", Some("@earendil-works/pi-coding-agent"), Some("0.84.2"), "openrouter/deepseek/deepseek-v4-flash-0731", diff --git a/packages/paperclip-runner/scripts/pi-distribution/package-lock.json b/packages/paperclip-runner/scripts/pi-distribution/package-lock.json index 51e309b2b30..d93c77cf0d1 100644 --- a/packages/paperclip-runner/scripts/pi-distribution/package-lock.json +++ b/packages/paperclip-runner/scripts/pi-distribution/package-lock.json @@ -12,6 +12,9 @@ "@earendil-works/pi-coding-agent": "0.84.2", "pi-acp": "0.0.33", "zod": "3.25.76" + }, + "engines": { + "node": ">=24.11.0" } }, "node_modules/@agentclientprotocol/sdk": { diff --git a/packages/paperclip-runner/scripts/pi-distribution/package.json b/packages/paperclip-runner/scripts/pi-distribution/package.json index b8bde7567b4..8f019e049ff 100644 --- a/packages/paperclip-runner/scripts/pi-distribution/package.json +++ b/packages/paperclip-runner/scripts/pi-distribution/package.json @@ -8,5 +8,8 @@ "@earendil-works/pi-coding-agent": "0.84.2", "pi-acp": "0.0.33", "zod": "3.25.76" + }, + "engines": { + "node": ">=24.11.0" } } diff --git a/packages/paperclip-runner/src/backends/native-backend-factory.test.ts b/packages/paperclip-runner/src/backends/native-backend-factory.test.ts index 33b8db8c479..76058e51513 100644 --- a/packages/paperclip-runner/src/backends/native-backend-factory.test.ts +++ b/packages/paperclip-runner/src/backends/native-backend-factory.test.ts @@ -33,6 +33,7 @@ import { import { createNativeSessionBackend } from "../index.js"; import { createCodexNativeSessionBackend } from "./codex-native-backend.js"; import { createOpenCodeNativeSessionBackend } from "./opencode-native-backend.js"; +import { QUALIFIED_ACPX_PROFILES } from "../drivers/acpx/qualified-profiles.js"; function execution( provider: NativeExecutionInput["provider"] = { @@ -111,7 +112,7 @@ function acpxExecution( protocolVersion: 1, acpxVersion: "0.13.1", agent, - agentProfileVersion: 1, + agentProfileVersion: agent === "pi" ? QUALIFIED_ACPX_PROFILES.pi.agentProfileVersion : 1, agentServerPackage: agent === "codex" ? "@agentclientprotocol/codex-acp" @@ -132,7 +133,7 @@ function acpxExecution( agent === "codex" ? "sha256:c4538599d1ab767db5dff50934f13bb5ba313a59d9c4a83e993fac4617ea63d3" : agent === "pi" - ? "sha256:8c696f38296d53d0061fa11534570c5ddd951b63532aed30e0f1fcc676dc169f" + ? QUALIFIED_ACPX_PROFILES.pi.commandDigest : "sha256:9d73d1f0f121fb96cc8badb28c22d5bff02d8582eb2e40360a81c189e1b9422a", }, }, @@ -534,6 +535,14 @@ describe("native backend factory", () => { })).toThrow("ACPX candidate direct execution requires completed qualification"); }); + it("rejects a Pi version 1 warm snapshot after the rich ACP upgrade", () => { + const input = acpxExecution("pi"); + if (input.provider.kind !== "acpx") throw new Error("invalid fixture"); + input.provider.profile.agentProfileVersion = 1; + expect(() => createNativeSessionBackend(input, { acpxRuntimeDirectory: "/runtime" })) + .toThrow("does not match the qualified agentProfileVersion"); + }); + it("rejects a Codex ACPX snapshot that drifts from its qualified profile", () => { const input = acpxExecution(); if (input.provider.kind !== "acpx") throw new Error("invalid fixture"); diff --git a/packages/paperclip-runner/src/drivers/acpx/pi-closure-pins.ts b/packages/paperclip-runner/src/drivers/acpx/pi-closure-pins.ts index afa503deb8d..dca9ac67b3a 100644 --- a/packages/paperclip-runner/src/drivers/acpx/pi-closure-pins.ts +++ b/packages/paperclip-runner/src/drivers/acpx/pi-closure-pins.ts @@ -6,7 +6,7 @@ * three pins. Never accept a digest supplied only by an installed manifest. */ export const PI_DISTRIBUTION_CLOSURE_SHA256 = Object.freeze({ - "darwin-arm64": "a26e98fe3f4d3d93c13beffdb4e8b778d438dd1b3bca8a9b1610154342382681", - "darwin-x64": "9423812469c8aedba369c581b23a4302e4d86aac06e98e3d14d95d5e875597f0", - "linux-x64": "892085f1f22c0813e4d722c37ddaa343a01aecfeff360d8ca6d5b201dd3f01f5", + "darwin-arm64": "b30047dce9c4c25e1fbc88a1aa828690a6a11ebdc3f6fcc083875986eb2d9585", + "darwin-x64": "3bff53a334f7226bd14adb6a91e6e3603281bec7b93e7dd62aa5599483df8bba", + "linux-x64": "482e648e5b8890971fdf326a936fddc01ae89c335159d7133ddff70b49ed3d3d", }); diff --git a/packages/paperclip-runner/src/drivers/acpx/qualified-profiles.ts b/packages/paperclip-runner/src/drivers/acpx/qualified-profiles.ts index 2d3975cb358..10ac10e6096 100644 --- a/packages/paperclip-runner/src/drivers/acpx/qualified-profiles.ts +++ b/packages/paperclip-runner/src/drivers/acpx/qualified-profiles.ts @@ -54,7 +54,7 @@ export const QUALIFIED_ACPX_PROFILES: Readonly< agentRuntimePackage: "@earendil-works/pi-coding-agent", agentRuntimeVersion: "0.84.2", commandDigest: - "sha256:c577a771778febe24b920388da77f6143971b8eec29e1ba9a433dac5b76de3cd", + "sha256:0f687e38cb3c607a01fab80f03e19bbbf5cb53a8afb1fc40d71f9ab54551cff1", qualificationModel: "openrouter/deepseek/deepseek-v4-flash-0731", reportedModelId: "openrouter/deepseek/deepseek-v4-flash-0731", permissionPolicy: "interactive",