From da31d69f2e3e73466c98bc1203bc30bae60733f7 Mon Sep 17 00:00:00 2001 From: Dotta Date: Sat, 19 Sep 2026 10:54:01 -0500 Subject: [PATCH] Fix remote runner staging from deployed server artifacts Reuse the controller-resolved binary when replacing an incompatible sandbox runner. The package development lookup does not match the deployed server vendor layout. Cover the controller and uploaded artifact identity in the remote runner regression. Co-Authored-By: Paperclip --- .../native-runtime/native-session-executor.test.ts | 5 ++--- .../src/services/native-runtime/native-session-executor.ts | 7 ++++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/server/src/services/native-runtime/native-session-executor.test.ts b/server/src/services/native-runtime/native-session-executor.test.ts index 90b849c2ee4..62712c6a608 100644 --- a/server/src/services/native-runtime/native-session-executor.test.ts +++ b/server/src/services/native-runtime/native-session-executor.test.ts @@ -40,7 +40,6 @@ import { NativeSessionCleanupQuarantinedError, NativeProviderTerminalFailure, NativeSessionProtocolIntegrityError, - defaultCapabilityRunnerdBinary, } from "../../vendor/paperclip-runner/index.js"; import * as issueServiceModule from "../issues.js"; import { @@ -174,7 +173,6 @@ vi.mock("../../vendor/paperclip-runner/index.js", async (importOriginal) => { >(); return { ...original, - defaultCapabilityRunnerdBinary: vi.fn(original.defaultCapabilityRunnerdBinary), createNativeSessionBackend: state.createBackend, createRunnerdCodexTransport: state.createTransport, executeNativeSession: state.execute, @@ -9650,7 +9648,7 @@ describe("runnerd provider runtime wiring", () => { const controllerArtifact = join(isolatedStateDirectory, "paperclip-runnerd"); if (staleRunner) { await writeFile(controllerArtifact, "fixture runner artifact"); - vi.mocked(defaultCapabilityRunnerdBinary).mockReturnValueOnce(controllerArtifact); + state.resolveRunnerBinary.mockReturnValueOnce(controllerArtifact); } const syncIn = vi.fn(async () => undefined); const remoteExecute = vi.fn( @@ -9726,6 +9724,7 @@ describe("runnerd provider runtime wiring", () => { "reached-preinstalled-codex-verification", ); if (staleRunner) { + expect(transport.runnerBinary).toBe(controllerArtifact); expect(syncIn).toHaveBeenCalledTimes(1); expect(syncIn).toHaveBeenCalledWith([expect.objectContaining({ files: [expect.objectContaining({ diff --git a/server/src/services/native-runtime/native-session-executor.ts b/server/src/services/native-runtime/native-session-executor.ts index a0b3c1fab36..148a62a5f72 100644 --- a/server/src/services/native-runtime/native-session-executor.ts +++ b/server/src/services/native-runtime/native-session-executor.ts @@ -62,7 +62,6 @@ import { acpxRuntimeSessionDirectoryName, createNativeSessionBackend, createRunnerdCodexTransport, - defaultCapabilityRunnerdBinary, executeNativeSession, applyNativeSessionGoalControl, inspectWarmRunTransition, @@ -10432,8 +10431,10 @@ async function createRunnerdBackendWithinSessionClaim( } } if (!usedPreinstalledRunner) { - const sourceBinary = - explicitRemoteBinary ?? defaultCapabilityRunnerdBinary(); + // Upload the same artifact used for the controller identity. The server + // vendors the runner under vendor/paperclip-runner/bin, so the package + // development fallback cannot locate it in a deployed server. + const sourceBinary = controllerRunnerBinary; if (!existsSync(sourceBinary)) { throw new Error("runner_remote_artifact_unavailable"); }