From 874883c72807d4286d0318abb9d7509fd8d7a276 Mon Sep 17 00:00:00 2001 From: haelyra <49814733+haelyra@users.noreply.github.com> Date: Sun, 27 Sep 2026 17:03:28 -0400 Subject: [PATCH] fix(profiles): make evaluator permissions and Windows checks portable --- docker/context-profiles/ai-eval-lib.js | 6 ++++-- tests/lib/context-profile-launch.test.js | 4 +++- tests/lib/context-profile-native.test.js | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/docker/context-profiles/ai-eval-lib.js b/docker/context-profiles/ai-eval-lib.js index e4083f6db..4b38c9b78 100644 --- a/docker/context-profiles/ai-eval-lib.js +++ b/docker/context-profiles/ai-eval-lib.js @@ -489,9 +489,11 @@ function syntheticEnvironments(root) { function checkArguments(cwd, file = CHECK_FILE, writable = false) { const major = Number(process.versions.node.split('.')[0]); const flag = major >= 22 ? '--permission' : major >= 20 ? '--experimental-permission' : null; - return flag ? [flag, `--allow-fs-read=${cwd}`, `--allow-fs-read=${path.join(cwd, '*')}`, + // A directory grant covers its children. Node 20.20.2 can abort in its native + // permission radix tree when the same directory is also granted as "cwd/*". + return flag ? [flag, `--allow-fs-read=${cwd}`, // Stepped graders exercise stateful apps (persistence); single-step graders stay read-only. - ...(writable ? [`--allow-fs-write=${cwd}`, `--allow-fs-write=${path.join(cwd, '*')}`] : []), file] : [file]; + ...(writable ? [`--allow-fs-write=${cwd}`] : []), file] : [file]; } // The hidden grader enters the workspace only after the agent exits, and runs read-only where Node supports it. diff --git a/tests/lib/context-profile-launch.test.js b/tests/lib/context-profile-launch.test.js index 0632f7de9..59d03ecdc 100644 --- a/tests/lib/context-profile-launch.test.js +++ b/tests/lib/context-profile-launch.test.js @@ -64,6 +64,8 @@ test('provider failure is distinct from successful task completion', () => withF test('isolated native launches replace every provider home without mutating the parent environment', () => withFixture(repoRoot => { const nativeEnvironment = nativeFixture(repoRoot); const before = { ...process.env }; + // Windows may expose the inherited key as Path while process.env resolves PATH case-insensitively. + const inheritedPath = process.env.PATH; let called = false; const result = launchTaskContext({ repoRoot, task: input, nativeEnvironment, execute(command, args, options) { called = true; @@ -73,7 +75,7 @@ test('isolated native launches replace every provider home without mutating the assert.equal(options.env.HOME, nativeEnvironment.home); assert.equal(options.env.USERPROFILE, nativeEnvironment.home); assert.equal(options.env.CODEX_HOME, nativeEnvironment.codexHome); - assert.equal(options.env.PATH, before.PATH); + assert.equal(options.env.PATH, inheritedPath); for (const key of ['AWS_ACCESS_KEY_ID', 'OPENAI_API_KEY', 'ANTHROPIC_API_KEY', 'HTTP_PROXY', 'NODE_OPTIONS']) { assert.equal(options.env[key], undefined); } diff --git a/tests/lib/context-profile-native.test.js b/tests/lib/context-profile-native.test.js index 8b14e8c9c..0f6a8d15c 100644 --- a/tests/lib/context-profile-native.test.js +++ b/tests/lib/context-profile-native.test.js @@ -67,8 +67,8 @@ test('native prepare verifies exact installed bytes and returns isolated session assert.equal(result.active, false); assert.equal(result.storeRevision, 1); assert.equal(result.providerVersion, '0.154.0'); - assert.ok(result.home.startsWith(`${options.nativeRoot}/`)); - assert.ok(result.codexHome.startsWith(`${result.home}/`)); + assert.equal(path.dirname(path.dirname(result.home)), path.join(options.nativeRoot, 'generations')); + assert.equal(path.dirname(result.codexHome), result.home); assert.equal(result.discovery, 'verified'); assert.equal(result.selectedIds.length, 3); assert.equal(dependency.calls.filter(call => call.args[1] === 'add').length, 1);