fix(#4485): isolate hook E2E tests from ambient capabilities (#4529)

* test(#4485): isolate hook E2E capability homes

* test(#4485): isolate the remaining plan hook E2E

* test(#4485): make ambient-home assertions real

* test(#4485): remove stale helper imports

---------

Co-authored-by: Tom Boucher <trekkie@nomorestars.com>
This commit is contained in:
Michel Moreira
2026-09-15 00:44:18 -03:00
committed by GitHub
parent e2bfc06558
commit e5c4941f2a
4 changed files with 83 additions and 11 deletions

View File

@@ -1251,7 +1251,50 @@ function writePackageSourceMarkerFixture(configDir) {
return configDir;
}
module.exports = { runGsdTools, createTempDir, createTempProject, createTempGitProject, cleanup, tmpRootCandidates, readFileNormalized, readWorkflowCombined, parseFrontmatter, isUsageOutput, captureConsole, toPosixPath, absPlanningPath, runNpm, isolatedNpmEnv, withIsolatedProcessState, delay, waitFor, resetRuntimeWarningCaches, SESSION_ENV_KEYS, saveSessionEnv, restoreSessionEnv, clearSessionEnv, isolateWorkstreamEnv, restoreWorkstreamEnv, TOOLS_PATH, SESSION_IDENTITY_ENV_KEYS, scrubConfigLocationEnv, installSpawnEnv, installSpawnHome, sandboxHome, writePackageSourceMarkerFixture, TEST_HOME_SANDBOX_MARKER, mockPartialWriteThenThrow, captureFdSync, suppressFdAsync };
/** Write one valid third-party gate into a synthetic user capability home. */
function writeAmbientCapabilityGate(home, id, point) {
const capDir = path.join(home, '.gsd', 'capabilities', id);
fs.mkdirSync(capDir, { recursive: true });
fs.writeFileSync(path.join(capDir, 'capability.json'), JSON.stringify({
id,
title: 'Ambient test capability',
version: '1.0.0',
role: 'feature',
tier: 'full',
description: 'Capability outside the test fixture that must remain invisible.',
engines: { gsd: '>=1.7.0' },
requires: [],
runtimeCompat: { supported: ['claude'], unsupported: [] },
skills: [],
agents: [],
config: {},
steps: [],
contributions: [],
gates: [{ point, check: { query: 'ambient.check' }, blocking: false, onError: 'skip' }],
}), 'utf8');
}
/**
* Put a capability in the parent process's ambient home for one serial test.
* The child must still receive installSpawnEnv()'s different sandbox home.
*/
function withAmbientCapabilityHome(t, prefix, id, point) {
const home = createTempDir(prefix);
writeAmbientCapabilityGate(home, id, point);
const previous = { HOME: process.env.HOME, USERPROFILE: process.env.USERPROFILE };
process.env.HOME = home;
process.env.USERPROFILE = home;
t.after(() => {
for (const [key, value] of Object.entries(previous)) {
if (value === undefined) delete process.env[key];
else process.env[key] = value;
}
cleanup(home);
});
return home;
}
module.exports = { runGsdTools, createTempDir, createTempProject, createTempGitProject, cleanup, tmpRootCandidates, readFileNormalized, readWorkflowCombined, parseFrontmatter, isUsageOutput, captureConsole, toPosixPath, absPlanningPath, runNpm, isolatedNpmEnv, withIsolatedProcessState, delay, waitFor, resetRuntimeWarningCaches, SESSION_ENV_KEYS, saveSessionEnv, restoreSessionEnv, clearSessionEnv, isolateWorkstreamEnv, restoreWorkstreamEnv, TOOLS_PATH, SESSION_IDENTITY_ENV_KEYS, scrubConfigLocationEnv, installSpawnEnv, installSpawnHome, sandboxHome, writePackageSourceMarkerFixture, writeAmbientCapabilityGate, withAmbientCapabilityHome, TEST_HOME_SANDBOX_MARKER, mockPartialWriteThenThrow, captureFdSync, suppressFdAsync };
// Lazy, for the reason builtLib() is lazy: reading either of these is what
// forces the built-lib require, so a test file that needs neither can still