From c0a8f383dbbca9455eac3d4f7dd99790e9509dc0 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Fri, 3 Jul 2026 01:00:09 -0400 Subject: [PATCH] test(#1970): scope HOME/USERPROFILE in folded bug-130/bug-410 blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adversarial review (Codex) surfaced a latent cross-suite leak: the folded bug-130 and bug-410 install.test.cjs blocks set process.env.HOME/USERPROFILE to a temp home at collection time and never restored — harmless when each ran as its own process, but after consolidation it leaked into sibling folded suites in the same process. Scope both mutations to before()/after() hooks that restore the prior values, matching the save/restore pattern used elsewhere in the file. Assertions unchanged. Co-Authored-By: Claude Opus 4.8 --- tests/install.test.cjs | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/tests/install.test.cjs b/tests/install.test.cjs index 8572724f7..c81ab05f7 100644 --- a/tests/install.test.cjs +++ b/tests/install.test.cjs @@ -4094,8 +4094,21 @@ const ROOT = path.join(__dirname, '..'); // Point HOME at a temp dir so configureOpencodePermissions can't write to // the real ~/.config/opencode/ even if the guard is missing. const FAKE_HOME = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-130-test-')); -process.env.HOME = FAKE_HOME; -process.env.USERPROFILE = FAKE_HOME; +// Consolidation #1969: scope the HOME/USERPROFILE mutation to before/after so it +// does not leak into sibling folded suites (was process-isolated when standalone). +const { before: __foldBefore, after: __foldAfter } = require('node:test'); +const __savedHome = process.env.HOME; +const __savedUserProfile = process.env.USERPROFILE; +__foldBefore(() => { + process.env.HOME = FAKE_HOME; + process.env.USERPROFILE = FAKE_HOME; +}); +__foldAfter(() => { + if (__savedHome === undefined) delete process.env.HOME; + else process.env.HOME = __savedHome; + if (__savedUserProfile === undefined) delete process.env.USERPROFILE; + else process.env.USERPROFILE = __savedUserProfile; +}); // The opencode config dir that configureOpencodePermissions would use for a // global install when configDir=null: /.config/opencode/ @@ -4183,8 +4196,21 @@ const ROOT = path.join(__dirname, '..'); // finishInstall's path.join(os.homedir(), '.gsd') resolves into FAKE_HOME // on every platform. Node docs: https://nodejs.org/docs/latest-v22.x/api/os.html#oshomedir const FAKE_HOME = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-410-test-')); -process.env.HOME = FAKE_HOME; -process.env.USERPROFILE = FAKE_HOME; +// Consolidation #1969: scope the HOME/USERPROFILE mutation to before/after so it +// does not leak into sibling folded suites (was process-isolated when standalone). +const { before: __foldBefore, after: __foldAfter } = require('node:test'); +const __savedHome = process.env.HOME; +const __savedUserProfile = process.env.USERPROFILE; +__foldBefore(() => { + process.env.HOME = FAKE_HOME; + process.env.USERPROFILE = FAKE_HOME; +}); +__foldAfter(() => { + if (__savedHome === undefined) delete process.env.HOME; + else process.env.HOME = __savedHome; + if (__savedUserProfile === undefined) delete process.env.USERPROFILE; + else process.env.USERPROFILE = __savedUserProfile; +}); // The path that finishInstall would write to for a non-Claude runtime. const GSD_DIR = path.join(FAKE_HOME, '.gsd');