From 7e2f74e9a9e1b7689b75f6309cf6ee0c2cabbbbe Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Fri, 3 Jul 2026 01:34:33 -0400 Subject: [PATCH] test(#1971): isolate folded CLI blocks from host ambient GSD_ env MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gsd-test surfaced 9 failures: folded fix-1437 (phase.list-plans) and bug-1826 (phases clear) tests spawn gsd-tools via runGsdTools, which copies process.env into the child. Their host suites (phase-command-router / phases-command-router) force GSD_WORKSTREAM=test-unit at the suite level, redirecting the child's project lookup away from each test's temp project → plan/dir counts came back 0. Clear GSD_WORKSTREAM in each folded block's beforeEach (restoring the standalone condition) and restore in afterEach. Also scope the folded bug-416 GSD_TEST_MODE set to a before/after hook in health-validation (Codex review) so it no longer leaks into host child processes. Assertions unchanged. Co-Authored-By: Claude Opus 4.8 --- tests/health-validation.test.cjs | 11 +++++++++-- tests/phase-command-router.test.cjs | 8 ++++++++ tests/phases-command-router.test.cjs | 8 ++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/tests/health-validation.test.cjs b/tests/health-validation.test.cjs index 0853b5761..19fdacdfe 100644 --- a/tests/health-validation.test.cjs +++ b/tests/health-validation.test.cjs @@ -722,8 +722,6 @@ describe('Drift item 3 — W006 false positive when disk has zero-padded letter * Answer space: | null. */ -process.env.GSD_TEST_MODE = '1'; - const { describe, test, before, after } = require('node:test'); const assert = require('node:assert/strict'); const fs = require('node:fs'); @@ -732,6 +730,15 @@ const os = require('node:os'); const { runGsdTools, cleanup } = require('./helpers.cjs'); +// Consolidation #1969: scope GSD_TEST_MODE to this folded block so it does not +// leak (via the runGsdTools env copy) into host tests registered before the fold. +const __savedTestMode = process.env.GSD_TEST_MODE; +before(() => { process.env.GSD_TEST_MODE = '1'; }); +after(() => { + if (__savedTestMode === undefined) delete process.env.GSD_TEST_MODE; + else process.env.GSD_TEST_MODE = __savedTestMode; +}); + // ── helpers ────────────────────────────────────────────────────────────────── function mkplanning(base) { diff --git a/tests/phase-command-router.test.cjs b/tests/phase-command-router.test.cjs index c8ebf1ad8..674f99ef0 100644 --- a/tests/phase-command-router.test.cjs +++ b/tests/phase-command-router.test.cjs @@ -481,8 +481,14 @@ function touch(dir, ...files) { let tmpDir; let phaseDir; +// Consolidation #1969: the host suite forces GSD_WORKSTREAM=test-unit, which +// runGsdTools propagates into child processes and redirects the project lookup. +// Clear it for these tests (unset when this file ran standalone); restore after. +let __savedWorkstream; beforeEach(() => { + __savedWorkstream = process.env.GSD_WORKSTREAM; + delete process.env.GSD_WORKSTREAM; const proj = setupProject('01-feature'); tmpDir = proj.tmpDir; phaseDir = proj.phaseDir; @@ -490,6 +496,8 @@ beforeEach(() => { afterEach(() => { cleanup(tmpDir); + if (__savedWorkstream === undefined) delete process.env.GSD_WORKSTREAM; + else process.env.GSD_WORKSTREAM = __savedWorkstream; }); describe('bug-1437 — phase.list-plans is wired in gsd-tools', () => { diff --git a/tests/phases-command-router.test.cjs b/tests/phases-command-router.test.cjs index e0092823b..00d9d6cd5 100644 --- a/tests/phases-command-router.test.cjs +++ b/tests/phases-command-router.test.cjs @@ -114,13 +114,21 @@ const { runGsdTools, createTempProject, cleanup } = require('./helpers.cjs'); describe('bug #1826: phases clear --confirm guard', () => { let tmpDir; + // Consolidation #1969: the host suite forces GSD_WORKSTREAM=test-unit, which + // runGsdTools propagates into child processes and redirects the project lookup. + // Clear it for these tests (unset when this file ran standalone); restore after. + let __savedWorkstream; beforeEach(() => { + __savedWorkstream = process.env.GSD_WORKSTREAM; + delete process.env.GSD_WORKSTREAM; tmpDir = createTempProject(); }); afterEach(() => { cleanup(tmpDir); + if (__savedWorkstream === undefined) delete process.env.GSD_WORKSTREAM; + else process.env.GSD_WORKSTREAM = __savedWorkstream; }); test('phases clear without --confirm is rejected when phase dirs exist', () => {