From 6fa2399392e68cafb915967ff682a7927325b043 Mon Sep 17 00:00:00 2001 From: Dotta Date: Wed, 30 Sep 2026 02:15:08 -0500 Subject: [PATCH] test(runner): isolate the qualified OpenCode Node fixture Co-Authored-By: Paperclip --- .../src/live/runnerd-codex-transport.test.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/paperclip-runner/src/live/runnerd-codex-transport.test.ts b/packages/paperclip-runner/src/live/runnerd-codex-transport.test.ts index b73754b8851..f085543cc30 100644 --- a/packages/paperclip-runner/src/live/runnerd-codex-transport.test.ts +++ b/packages/paperclip-runner/src/live/runnerd-codex-transport.test.ts @@ -7571,13 +7571,18 @@ it.each([true, false])("preserves prepared OpenCode cleanup errors (primary fail it("preserves prepared input through runnerd and the real OpenCode proxy boundary", async () => { const root = await mkdtemp(join(tmpdir(), "runnerd-prepared-opencode-")); + // The CI toolcache Node can be group-writable. Qualify an owned copy without + // changing shared host permissions or weakening the production launch check. + const nodeCommand = join(root, "node"); + await cp(process.execPath, nodeCommand); + await chmod(nodeCommand, 0o755); // The qualified launch boundary unlinks its executable after exec. Use a // native wrapper, like the real OpenCode binary; a shebang script would need // to reopen the now-unlinked path in its interpreter. const executable = join(root, "fake-opencode"); const fixture = resolve("test/fixtures/fake-opencode-server.mjs"); execFileSync("cc", ["-x", "c", "-o", executable, "-"], { - input: `#include \n#include \nint main(int argc, char **argv) { char **args = calloc(argc + 2, sizeof(char *)); args[0] = ${JSON.stringify(process.execPath)}; args[1] = ${JSON.stringify(fixture)}; for (int i = 1; i < argc; i++) args[i + 1] = argv[i]; execv(args[0], args); return 127; }`, + input: `#include \n#include \nint main(int argc, char **argv) { char **args = calloc(argc + 2, sizeof(char *)); args[0] = ${JSON.stringify(nodeCommand)}; args[1] = ${JSON.stringify(fixture)}; for (int i = 1; i < argc; i++) args[i + 1] = argv[i]; execv(args[0], args); return 127; }`, }); // CI may use umask 0002; qualified executables cannot be group-writable. await chmod(executable, 0o755); @@ -7602,8 +7607,8 @@ it("preserves prepared input through runnerd and the real OpenCode proxy boundar opencodeCommandSha256: digest(executable), opencodeProxyPath: proxy, opencodeProxySha256: digest(proxy), - providerNodeCommand: process.execPath, - providerNodeCommandSha256: digest(process.execPath), + providerNodeCommand: nodeCommand, + providerNodeCommandSha256: digest(nodeCommand), environment: { PATH: process.env.PATH, OPENROUTER_API_KEY: "fixture-key" }, }); const task = createCodexTaskEnvelope({