Files
msd-core/tests
0xdhx 35df0891af fix(#3156): sandbox HOME on raw installer spawns — the one leak no scrub reaches
The strict live-config guard this PR ships went red on CI: the suite creates
$HOME/.gsd/defaults.json. Diagnosed rather than suppressed, because the guard
is right — this is #2665's class arriving through the one door the scrub set is
structurally unable to close.

bin/install.js writeNonClaudeDefaults() (#2834) writes
path.join(os.homedir(), '.gsd', 'defaults.json') for every non-Claude runtime.
os.homedir() consults NO GSD variable, so:

  - no entry in CONFIG_LOCATION_ENV_KEYS can reach it, however the set is
    derived; and
  - blanking GSD_HOME does not reach it either -- a blank GSD_HOME falls back
    to exactly that homedir().

Only a sandboxed HOME contains it, and HOME is deliberately excluded from
TEST_ENV_BASE because blanking it would break far more than it fixed. So the
containment belongs per-spawn, which is the discipline the suite already
applies by hand -- install-minimal-hooks.test.cjs:576 carries a comment
naming this exact hazard for the --codex spawn, while the parameterized
--${runtime} spawn 130 lines below it does not. Instance fixed, class open.

Rather than add a fifth hand-synced env shape to a PR whose subject is that
hand-synced copies drift, this adds ONE export -- installSpawnEnv() in
tests/helpers.cjs -- and routes every raw installer spawn through it, including
the shared tests/helpers/install-shared.cjs installerEnv(), which every install
suite already consumes. Callers passing an explicit { HOME, USERPROFILE } are
unaffected: overrides spread last.

Census (measured, not reasoned): of the 119 test files that spawn bin/install.js,
exactly four wrote into a sandboxed $HOME before this commit -- install,
copilot-install, install-minimal-hooks, opencode-plugin-adapter -- and zero do
after. Only install.test.cjs sits in CI's targeted lane, which is why ubuntu
went red on one file while the macOS full lanes went red on four.

Attribution: the leak reproduces unchanged at upstream/next itself, so the
defect is base-owned and pre-existing; only the detector is new. The guard
found a real leak on next within one run.

No new failures: the surviving names under a sandboxed HOME
(folded:enh-2380-sync-skills, getGlobalConfigDir (Copilot)) fail at base too,
and base additionally fails folded:bug-3288-model-catalog-install-path, which
this tree does not.
2026-08-08 05:56:22 -05:00
..