test(#2665): reversion guards for all three round-4 fixes

None of the round-4 fixes had a test that fails on reversion: re-shipping
the test-instrumentation chain passes #2858 (everything ships, so every
require resolves), dropping the strict env from test.yml demotes the guard
to report-only with nothing red, and the skillsHome derivation tests are
enumeration-relative over declarations that are all empty today. One
guard each, every one negative-controlled against its reverted fix (fails
pre-fix, passes post-fix):

- packaging-shipped-scripts-require-only-shipped.test.cjs asserts the four
  chain files are absent from the npm pack file list (reuses the tarball
  set the #2858 gate already resolves — no second npm pack).
- live-config-guard.test.cjs asserts all three test jobs wire
  GSD_STRICT_LIVE_CONFIG_GUARD, matching the WHOLE expression anchored —
  a prefix match accepted both a Windows-silently-strict tail and a
  malformed one.
- helpers-process-isolation.test.cjs cold-requires helpers.cjs in a child
  with sentinel skillsHome env vars injected into both enumerations, so
  the walk itself is under test rather than today's empty declarations.
This commit is contained in:
0xdhx
2026-08-03 03:09:17 -05:00
parent 7b8c36f904
commit 652b99b71b
3 changed files with 112 additions and 0 deletions

View File

@@ -235,3 +235,57 @@ describe('#2665: TEST_ENV_BASE config-location coverage', () => {
});
});
});
describe('#2665 round 4: the skillsHome walk is reversion-sensitive', () => {
// The coverage tests above are enumeration-relative, and skillsHome.env is
// empty everywhere today — so reverting the skillsHome rungs from the
// derivation leaves every one of them green (measured by this round's
// pre-push adversarial review). This test closes that: it cold-requires
// helpers.cjs in a child process after injecting sentinel skillsHome env
// vars into BOTH enumerations (registry and non-registry), so the walk
// itself is what is under test, not today's empty declarations.
test('sentinel skillsHome vars flow into TEST_ENV_BASE on both rungs', () => {
const { execFileSync } = require('node:child_process');
const regPath = require.resolve('../gsd-core/bin/lib/capability-registry.cjs');
const rhPath = require.resolve('../gsd-core/bin/lib/runtime-homes.cjs');
const helpersPath = require.resolve('./helpers.cjs');
const script = `
'use strict';
const reg = require(${JSON.stringify(regPath)});
const rh = require(${JSON.stringify(rhPath)});
// Rung 1 (registry): give one runtime a skillsHome env var. kilo already
// declares skillsHome (env: []); push a sentinel into whichever runtime
// declares it, or graft one onto the first runtime if none does.
const declaring = Object.values(reg.runtimes).find(
(r) => r?.runtime?.configHome?.skillsHome,
) ?? Object.values(reg.runtimes)[0];
if (!declaring.runtime.configHome.skillsHome) {
declaring.runtime.configHome.skillsHome = { kind: 'dot-home', name: '.x', env: [] };
}
declaring.runtime.configHome.skillsHome.env = ['GSD_TEST_SENTINEL_REGISTRY_SKILLS'];
// Rung 2 (non-registry): graft a skillsHome onto the first descriptor.
rh.NON_REGISTRY_CONFIG_HOME_DESCRIPTORS[0].skillsHome = {
kind: 'dot-home', name: '.x', env: ['GSD_TEST_SENTINEL_NONREG_SKILLS'],
};
const { TEST_ENV_BASE } = require(${JSON.stringify(helpersPath)});
const missing = [
'GSD_TEST_SENTINEL_REGISTRY_SKILLS',
'GSD_TEST_SENTINEL_NONREG_SKILLS',
].filter((k) => TEST_ENV_BASE[k] !== '');
if (missing.length > 0) {
console.error('skillsHome walk missed: ' + missing.join(', '));
process.exit(1);
}
process.exit(0);
`;
const out = execFileSync(process.execPath, ['-e', script], {
cwd: __dirname,
encoding: 'utf-8',
stdio: ['pipe', 'pipe', 'pipe'],
timeout: 30_000,
});
void out; // exit 0 is the assertion; execFileSync throws on nonzero
});
});