From c7731dc7dc5daafafc3e03444954a4159b698836 Mon Sep 17 00:00:00 2001 From: Dotta Date: Thu, 3 Sep 2026 02:20:11 -0500 Subject: [PATCH] fix(runner): align Codex ACPX admission digest --- .../runner-core/src/acpx_provider_backend.rs | 4 +- .../tests/native_provider_backend.rs | 2 +- .../scripts/build-provider-pack.mjs | 2 +- .../test/acpx-codex-package-contract.test.mjs | 43 +++++++++++++++++++ 4 files changed, 47 insertions(+), 4 deletions(-) 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 1492ab9206..6784672a5c 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 @@ -98,7 +98,7 @@ impl AcpxProviderDescriptor { "1.6.2", Some("@openai/codex"), Some("0.148.0"), - "sha256:94049b3e3c3aee87de62703786e4fa81d031d7bd979f99bdf516d84f28791a79", + "sha256:7a923b3829884d3cabcc9659d22cace3f86813e7bfffc90974b10140a45bc400", ), "pi" => return Err(DurableRunnerError::invalid( "ACPX agent pi is not executable through the verified runnerd provider boundary", @@ -1337,7 +1337,7 @@ mod tests { "1.6.2", json!("@openai/codex"), json!("0.148.0"), - "sha256:94049b3e3c3aee87de62703786e4fa81d031d7bd979f99bdf516d84f28791a79", + "sha256:7a923b3829884d3cabcc9659d22cace3f86813e7bfffc90974b10140a45bc400", ) }; json!({ diff --git a/packages/paperclip-runner/runner/crates/runner-core/tests/native_provider_backend.rs b/packages/paperclip-runner/runner/crates/runner-core/tests/native_provider_backend.rs index f9ea97cc9d..2a2db7a20b 100644 --- a/packages/paperclip-runner/runner/crates/runner-core/tests/native_provider_backend.rs +++ b/packages/paperclip-runner/runner/crates/runner-core/tests/native_provider_backend.rs @@ -15,7 +15,7 @@ use serde_json::{json, Value}; use sha2::{Digest, Sha256}; const CODEX_ACPX_DIGEST: &str = - "sha256:94049b3e3c3aee87de62703786e4fa81d031d7bd979f99bdf516d84f28791a79"; + "sha256:7a923b3829884d3cabcc9659d22cace3f86813e7bfffc90974b10140a45bc400"; fn temporary_directory(label: &str) -> PathBuf { let nonce = SystemTime::now() diff --git a/packages/paperclip-runner/scripts/build-provider-pack.mjs b/packages/paperclip-runner/scripts/build-provider-pack.mjs index b4703dbaf3..5409aeb05e 100644 --- a/packages/paperclip-runner/scripts/build-provider-pack.mjs +++ b/packages/paperclip-runner/scripts/build-provider-pack.mjs @@ -253,7 +253,7 @@ try { claude: "sha256:9d73d1f0f121fb96cc8badb28c22d5bff02d8582eb2e40360a81c189e1b9422a", codex: - "sha256:94049b3e3c3aee87de62703786e4fa81d031d7bd979f99bdf516d84f28791a79", + "sha256:7a923b3829884d3cabcc9659d22cace3f86813e7bfffc90974b10140a45bc400", }, artifacts: { nodeCommand: { diff --git a/packages/paperclip-runner/test/acpx-codex-package-contract.test.mjs b/packages/paperclip-runner/test/acpx-codex-package-contract.test.mjs index 189d4ffa06..422649955c 100644 --- a/packages/paperclip-runner/test/acpx-codex-package-contract.test.mjs +++ b/packages/paperclip-runner/test/acpx-codex-package-contract.test.mjs @@ -34,6 +34,28 @@ const nodePatch = await readFile( new URL("../../../patches/node@24.11.0.patch", import.meta.url), "utf8", ); +const qualifiedProfiles = await readFile( + new URL("../src/drivers/acpx/qualified-profiles.ts", import.meta.url), + "utf8", +); +const runnerdAcpxBackend = await readFile( + new URL( + "../runner/crates/runner-core/src/acpx_provider_backend.rs", + import.meta.url, + ), + "utf8", +); +const providerPackBuilder = await readFile( + new URL("../scripts/build-provider-pack.mjs", import.meta.url), + "utf8", +); +const nativeSessionExecutor = await readFile( + new URL( + "../../../server/src/services/native-runtime/native-session-executor.ts", + import.meta.url, + ), + "utf8", +); test("the runner pins every qualified ACPX production dependency", () => { assert.equal(runnerPackage.dependencies.node, "24.11.0"); @@ -53,6 +75,27 @@ test("the runner pins every qualified ACPX production dependency", () => { ); }); +test("the patched Codex ACP command digest stays aligned across launch boundaries", () => { + const profileMatch = /agent: "codex"[\s\S]*?commandDigest:\s*"(sha256:[a-f0-9]{64})"/.exec( + qualifiedProfiles, + ); + assert.ok(profileMatch, "qualified Codex ACPX profile digest"); + const digest = profileMatch[1]; + + assert.match( + runnerdAcpxBackend, + new RegExp(`"codex"[\\s\\S]*?${digest}`), + ); + assert.match( + providerPackBuilder, + new RegExp(`acpxProfileDigests:[\\s\\S]*?codex:[\\s\\S]*?${digest}`), + ); + assert.match( + nativeSessionExecutor, + new RegExp(`REMOTE_PROVIDER_PACK_PROFILE_DIGESTS[\\s\\S]*?codex:[\\s\\S]*?${digest}`), + ); +}); + test("the package exposes only the reviewed runner CLI binaries", () => { assert.deepEqual(runnerPackage.bin, { "paperclip-runner-eval-session": "./dist/cli/eval-session.js",