From 5bce5c46a6c59cdb59b0d807c1f9c92c9c5f1b1e Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Sun, 12 Jul 2026 15:49:16 -0400 Subject: [PATCH] test(#2152): sandbox HOME in readGsdEffectiveModelOverrides subtest The subtest asserted project-only model_overrides but called readGsdEffectiveModelOverrides without isolating HOME, so the real ~/.gsd/defaults.json global overrides bled into the deepEqual on any dev box or non-hermetic runner that has one. Pass a sandboxed homedir (mirroring the sibling warnIfStaleBake subtests that already inject homedir). --- tests/stale-bake-guard.test.cjs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/stale-bake-guard.test.cjs b/tests/stale-bake-guard.test.cjs index c8cbb2cb3..f03ded958 100644 --- a/tests/stale-bake-guard.test.cjs +++ b/tests/stale-bake-guard.test.cjs @@ -468,16 +468,21 @@ describe('stale-bake-guard parity with bin/install.js bake paths', () => { test('readGsdEffectiveModelOverrides resolves codex + opencode overrides from .planning/config.json', () => { const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-parity-')); + // #2152: sandbox HOME so the real ~/.gsd/defaults.json cannot bleed its global + // model_overrides into this project-only assertion (hermeticity). Mirrors the + // sibling subtests that pass a homedir option to warnIfStaleBake. + const sandboxHome = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-parity-home-')); try { fs.mkdirSync(path.join(tmp, '.planning'), { recursive: true }); fs.writeFileSync( path.join(tmp, '.planning', 'config.json'), JSON.stringify({ model_overrides: { 'gsd-executor': 'opencode-go/flash', 'gsd-planner': 'openai/gpt-5' } }), ); - const resolved = install.readGsdEffectiveModelOverrides(tmp); + const resolved = install.readGsdEffectiveModelOverrides(tmp, { homedir: () => sandboxHome }); assert.deepEqual(resolved, { 'gsd-executor': 'opencode-go/flash', 'gsd-planner': 'openai/gpt-5' }); } finally { cleanup(tmp); + cleanup(sandboxHome); } }); });