fix: preserve saved setup and match sandbox runner targets

Share actual-target artifact selection across remote Codex setup and execution. Keep unchanged saved setup choices outside new-selection rules while retaining runtime and authentication validation. Update the served platform guide.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-12 14:12:14 -05:00
1 parent 665c155472
commit e79254b2fa
10 files changed
+182 -30

No files matched your search

@@ -12,7 +12,7 @@ import {
resolveRemotePaperclipRunnerBinary,
} from "./native-codex-runner.js";
afterEach(() => vi.restoreAllMocks());
afterEach(() => { vi.restoreAllMocks(); vi.unstubAllGlobals(); });
describe("installed runner selection", () => {
it("uses the runner's platform-aware packaged selection", async () => {
@@ -46,7 +46,7 @@ describe("installed runner selection", () => {
});
});
describe("selected SSH daemon target", () => {
describe("selected remote daemon target", () => {
function header(target: string) {
const bytes = Buffer.alloc(64);
if (target.startsWith("darwin")) {
@@ -72,6 +72,21 @@ describe("selected SSH daemon target", () => {
expect(target.execute).toHaveBeenCalledExactlyOnceWith({ command: "sh", args: ["-c", "uname -s; uname -m"], cwd: "/selected-workspace", bypassSession: true, timeoutMs: 10_000 });
} finally { await rm(root, { recursive: true, force: true }); }
});
it.each(["arm64", "x64"].flatMap(controllerArch => ["arm64", "x64"].map(targetArch => ({ controllerArch, targetArch }))))(
"selects the actual Linux $targetArch sandbox bytes on a Mac $controllerArch controller", async ({ controllerArch, targetArch }) => {
const root = await mkdtemp(join(tmpdir(), "paperclip-sandbox-daemon-"));
const binary = join(root, "paperclip-runnerd");
try {
vi.stubGlobal("process", { ...process, platform: "darwin", arch: controllerArch });
await writeFile(binary, header(`linux-${targetArch}`));
const select = vi.spyOn(runner, "defaultCapabilityRunnerdBinary").mockReturnValue(binary);
const target = remote(`Linux\n${targetArch === "arm64" ? "aarch64" : "x86_64"}\n`);
expect(await resolveRemotePaperclipRunnerBinary({ runner: target, remoteCwd: "/sandbox-workspace" })).toBe(binary);
expect(select).toHaveBeenCalledExactlyOnceWith("linux", targetArch);
expect(target.execute).toHaveBeenCalledExactlyOnceWith({ command: "sh", args: ["-c", "uname -s; uname -m"], cwd: "/sandbox-workspace", bypassSession: true, timeoutMs: 10_000 });
} finally { await rm(root, { recursive: true, force: true }); }
},
);
it.each(["matching", "wrong-architecture", "malformed", "missing"])("verifies an explicit controller-owned remote artifact (%s)", async scenario => {
const root = await mkdtemp(join(tmpdir(), "paperclip-ssh-daemon-"));
const binary = join(root, "configured-runnerd");
@@ -208,7 +208,7 @@ export function resolvePaperclipRunnerBinary(
);
}
/** Select controller-owned bytes for the selected SSH host, never its controller. */
/** Select controller-owned bytes for the actual remote host, never its controller. */
export async function resolveRemotePaperclipRunnerBinary(input: {
runner: CommandManagedRuntimeRunner;
remoteCwd: string;
@@ -220,7 +220,7 @@ export async function resolveRemotePaperclipRunnerBinary(input: {
const platform = os === "Linux" ? "linux" : os === "Darwin" ? "darwin" : null;
const architecture = arch === "x86_64" ? "x64" : arch === "aarch64" || arch === "arm64" ? "arm64" : null;
if (probe.exitCode !== 0 || probe.timedOut || !platform || !architecture) {
throw new Error("runner_remote_artifact_platform_mismatch: could not identify a supported remote OS and architecture; check the SSH host and retry");
throw new Error("runner_remote_artifact_platform_mismatch: could not identify a supported remote OS and architecture; check the selected execution environment and retry");
}
const configured = input.configuredPath?.trim();
if (configured && !isAbsolute(configured)) throw new Error("PAPERCLIP_RUNNER_REMOTE_BINARY_PATH must be an absolute path");
@@ -12218,10 +12218,8 @@ describe("runnerd provider runtime wiring", () => {
// The mocked remote executes metadata probes; artifact staging only needs bytes.
// Keep this regression independent of a locally compiled Rust runner binary.
const controllerArtifact = join(isolatedStateDirectory, "paperclip-runnerd");
if (needsReplacement || retained || image === "preinstalled-exact") {
await writeFile(controllerArtifact, "fixture runner artifact");
state.resolveRunnerBinary.mockReturnValueOnce(controllerArtifact);
}
await writeFile(controllerArtifact, "fixture runner artifact");
state.resolveRemoteRunnerBinary.mockResolvedValue(controllerArtifact);
const onLog = vi.fn(async () => undefined);
const syncIn = vi.fn(async () => undefined);
const remoteExecute = vi.fn(
@@ -12430,21 +12428,27 @@ describe("runnerd provider runtime wiring", () => {
});
it.each(["explicit", "linux-arm64", "linux-x64"])("binds an SSH launch to the selected controller-owned runner artifact (%s)", async mode => {
it.each(["ssh", "sandbox"].flatMap(transport => ["explicit", "linux-arm64", "linux-x64", "missing", "mismatch"].map(mode => ({ transport, mode }))))
("binds a $transport launch to the selected controller-owned runner artifact ($mode)", async ({ transport, mode }) => {
const remoteCwd = "/home/daytona/paperclip-workspace";
const controllerArtifact = `/controller/artifacts/${mode}/paperclip-runnerd`;
state.resolveRemoteRunnerBinary.mockResolvedValue(controllerArtifact);
const explicit = mode === "explicit" || mode === "missing" || mode === "mismatch";
const error = mode === "missing" ? "runner_remote_artifact_unavailable" : mode === "mismatch" ? "runner_remote_artifact_platform_mismatch" : null;
if (error) state.resolveRemoteRunnerBinary.mockRejectedValue(new Error(error));
else state.resolveRemoteRunnerBinary.mockResolvedValue(controllerArtifact);
const remoteExecution = {
...execution,
binding: { ...execution.binding, runId: "run-remote-runner-artifact" },
workspace: { ...execution.workspace, cwd: "/host/paperclip-workspace" },
} as NativeExecutionInputV1;
await createRunnerdBackend({
const backend = createRunnerdBackend({
db: leaseDb(remoteExecution),
execution: remoteExecution,
runnerInstanceId: "runner",
runnerExecutionTarget: {
runnerExecutionTarget: transport === "sandbox" ? {
kind: "remote", transport: "sandbox", providerKey: "test", remoteCwd, runner: { execute: vi.fn() },
} : {
kind: "remote",
transport: "ssh",
remoteCwd,
@@ -12459,15 +12463,25 @@ describe("runnerd provider runtime wiring", () => {
strictHostKeyChecking: true,
},
},
...(mode === "explicit" ? { runnerRemoteBinaryPath: controllerArtifact } : {}),
...(explicit ? { runnerRemoteBinaryPath: controllerArtifact } : {}),
});
if (error) {
await expect(backend).rejects.toThrow(error);
expect(state.resolveRemoteRunnerBinary).toHaveBeenCalledWith(expect.objectContaining({ remoteCwd, configuredPath: controllerArtifact }));
expect(state.resolveRunnerBinary).not.toHaveBeenCalled();
expect(state.createBackend).not.toHaveBeenCalled();
expect(state.createTransport).not.toHaveBeenCalled();
return;
}
await backend;
state.createTransport.mockClear();
state.createBackend.mock.calls.at(-1)![1].codexTransportFactory!();
expect(state.createTransport).toHaveBeenCalledWith(
expect.objectContaining({ runnerBinary: controllerArtifact }),
);
expect(state.resolveRemoteRunnerBinary).toHaveBeenCalledWith(expect.objectContaining({ remoteCwd, configuredPath: mode === "explicit" ? controllerArtifact : undefined }));
expect(state.resolveRemoteRunnerBinary).toHaveBeenCalledWith(expect.objectContaining({ remoteCwd, configuredPath: explicit ? controllerArtifact : undefined }));
expect(state.resolveRunnerBinary).not.toHaveBeenCalled();
});
@@ -11551,7 +11551,7 @@ async function createRunnerdBackendWithinSessionClaim(
// filesystem; the remote launcher separately owns the sandbox command path.
// When an explicit remote artifact is configured, prepareRemoteRunner stages
// these exact bytes at remoteBinary before launch.
const targetMatchedCodexArtifact = remoteTarget?.transport === "ssh" && input.execution.provider.kind === "codex";
const targetMatchedCodexArtifact = remoteTarget !== null && input.execution.provider.kind === "codex";
const controllerRunnerBinary = targetMatchedCodexArtifact
? await resolveRemotePaperclipRunnerBinary({ runner: remoteCommandRunner!, remoteCwd: remoteTarget.remoteCwd, configuredPath: input.runnerRemoteBinaryPath })
: remoteTarget
@@ -35,6 +35,7 @@ describe("Codex selected native account verification", () => {
vi.stubEnv("PAPERCLIP_RUNNER_REMOTE_BINARY_PATH", "");
});
afterEach(async () => {
vi.unstubAllGlobals();
vi.unstubAllEnvs();
for (const [input] of nativeProbe.mock.calls) if (input.runtimeDirectory) await rm(input.runtimeDirectory, { recursive: true, force: true });
});
@@ -238,7 +239,12 @@ describe("Codex selected native account verification", () => {
if (confirmed) await expect(stat(root)).rejects.toThrow();
else expect((await stat(root)).isDirectory()).toBe(true);
});
it("uses the same preparation and controller PRP for a sandbox, without a guest provider pack", async () => {
it.each(["arm64", "x64"].flatMap(controllerArch => ["arm64", "x64"].flatMap(targetArch => [false, true].map(explicit => ({ controllerArch, targetArch, explicit })))))
("uses target $targetArch artifacts and controller PRP from Mac $controllerArch for sandbox setup (override=$explicit)", async ({ controllerArch, targetArch, explicit }) => {
vi.stubGlobal("process", { ...process, platform: "darwin", arch: controllerArch });
const selectedBinary = `/controller/artifacts/linux-${targetArch}/paperclip-runnerd`;
selectedRemoteRunner.mockResolvedValue(selectedBinary);
if (explicit) vi.stubEnv("PAPERCLIP_RUNNER_REMOTE_BINARY_PATH", selectedBinary);
nativeProbe.mockImplementation(async input => {
const registration = await input.transportOptions.controlPlaneRegistration({});
expect(registration.connection.mode).toBe("connect");
@@ -248,10 +254,23 @@ describe("Codex selected native account verification", () => {
const target = { ...context.executionTarget, runner: { execute: sshExecute } };
expect((await testNativeRunnerAuthentication({ ...context, executionTarget: target }, "codex", "gpt-6.1-sol")).status).toBe("pass");
expect(sshRunner).not.toHaveBeenCalled();
expect(nativeArtifacts).toHaveBeenCalledWith(expect.objectContaining({ target, runner: target.runner }));
expect(selectedRemoteRunner).toHaveBeenCalledExactlyOnceWith({ runner: target.runner, remoteCwd: target.remoteCwd, configuredPath: explicit ? selectedBinary : null });
expect(selectedRunner).not.toHaveBeenCalled();
expect(nativeArtifacts).toHaveBeenCalledWith(expect.objectContaining({ target, runner: target.runner, controllerRunnerBinary: selectedBinary, targetPlatformArtifactVerified: true }));
expect(nativeProbe.mock.calls[0][0].transportOptions.runnerBinary).toBe(selectedBinary);
expect(nativeArtifacts.mock.results[0].value.prepare).toHaveBeenCalledWith("dial_wss");
expect(execute).not.toHaveBeenCalled();
});
it.each(["runner_remote_artifact_unavailable", "runner_remote_artifact_platform_mismatch"])("fails sandbox %s before setup or a controller fallback", async code => {
selectedRemoteRunner.mockRejectedValue(new Error(code));
const target = { ...context.executionTarget, runner: { execute: sshExecute } };
const result = await testNativeRunnerAuthentication({ ...context, executionTarget: target }, "codex", "gpt-6.1-sol");
expect(result.status).toBe("fail");
expect(result.checks[0].message).toContain(code);
expect(selectedRunner).not.toHaveBeenCalled(); expect(nativeArtifacts).not.toHaveBeenCalled();
expect(nativeProbe).not.toHaveBeenCalled(); expect(sshExecute).not.toHaveBeenCalled();
expect(execute).not.toHaveBeenCalled();
});
it("prepares listener artifacts before acquiring sandbox ingress and owns its release", async () => {
const order: string[] = [];
const close = vi.fn();
@@ -63,11 +63,9 @@ async function probeRemoteNativeCodex(options: {
const remoteCodexNpmSpec = process.env.PAPERCLIP_RUNNER_REMOTE_CODEX_NPM_SPEC?.trim() || null;
const remoteCodexBinary = remoteCodexNpmSpec ? posix.join(remoteRoot, "harnesses", "codex", "node_modules", ".bin", "codex") : posix.join(remoteRoot, "bin", "codex");
const explicitRunner = process.env.PAPERCLIP_RUNNER_REMOTE_BINARY_PATH?.trim() || null;
const controllerRunnerBinary = target.transport === "ssh"
? await resolveRemotePaperclipRunnerBinary({ runner, remoteCwd: target.remoteCwd, configuredPath: explicitRunner })
: explicitRunner || resolvePaperclipRunnerBinary();
const controllerRunnerBinary = await resolveRemotePaperclipRunnerBinary({ runner, remoteCwd: target.remoteCwd, configuredPath: explicitRunner });
const artifacts = createRemoteNativeArtifactPreparation({ target, runner, remoteBinary, controllerRunnerBinary, remoteRuntimeRoot: remoteRoot, remoteCodexBinary,
targetPlatformArtifactVerified: target.transport === "ssh",
targetPlatformArtifactVerified: true,
runnerRemoteBinaryPath: explicitRunner, runnerRemoteCodexPath: process.env.PAPERCLIP_RUNNER_REMOTE_CODEX_PATH?.trim(), runnerRemoteCodexNpmSpec: remoteCodexNpmSpec, model: options.model });
const requireSuccess = (result: { timedOut: boolean; exitCode: number | null }, message: string) => {
if (result.timedOut || result.exitCode !== 0) throw new Error(message);