refactor: hard-fork GSD -> MSD (Make Software Done)

Mechanical rename produced by scripts/msd-rename.cjs: gsd/Gsd/GSD -> msd/Msd/MSD
across contents and paths, upstream package/repo coordinates -> @golem15/msd-core
and golem15com/msd-core. Deep links into upstream history, sibling upstream
packages, the GSD-2 import feature, CHANGELOG.md and .changeset/ are kept as-is.

Hand edits on top: MSD block-letter banner and logos, LICENSE copyright line,
package/plugin identity, regenerated lockfile, install-tree fixtures, derived
registries and benchmark baseline; migration checksum baseline re-locked
(MSD keeps its own install state, so no install had applied the old sums);
sort-order and regex-escaped expectations in tests adjusted.
This commit is contained in:
Jakub Zych
2026-10-06 01:47:40 +02:00
parent fe069b2a56
commit a9a7a328e6
2763 changed files with 78465 additions and 78434 deletions

View File

@@ -15,16 +15,16 @@ const { createTempDir, cleanup } = require('./helpers.cjs');
const fc = require('./helpers/fast-check-setup.cjs');
const { ensureScriptsOut } = require('./helpers/exit-code-artifact-flags.cjs');
// Paths to the compiled product seam (src/cli-exit.cts → gsd-core/bin/lib/cli-exit.cjs)
// Paths to the compiled product seam (src/cli-exit.cts → msd-core/bin/lib/cli-exit.cjs)
// used for json-error mode regression tests which require io.cjs integration.
const BUILT_CLI_EXIT_PATH = path.resolve(__dirname, '../gsd-core/bin/lib/cli-exit.cjs');
const IO_PATH = path.resolve(__dirname, '../gsd-core/bin/lib/io.cjs');
const BUILT_CLI_EXIT_PATH = path.resolve(__dirname, '../msd-core/bin/lib/cli-exit.cjs');
const IO_PATH = path.resolve(__dirname, '../msd-core/bin/lib/io.cjs');
const SCRIPTS_CLI_EXIT_PATH = path.resolve(__dirname, '../scripts/lib/cli-exit.cjs');
const EXIT_CODE_REGISTRY_PATH = path.resolve(__dirname, '../gsd-core/bin/lib/exit-code-registry.cjs');
const EXIT_CODE_REGISTRY_PATH = path.resolve(__dirname, '../msd-core/bin/lib/exit-code-registry.cjs');
// #3911 (ADR-3889 Phase 7): the THIRD emitted copy, for hooks/ consumers that
// must terminate through terminateNow without depending on any build
// artifact (gsd-core/bin/lib is gitignored tsc output, absent on a raw
// artifact (msd-core/bin/lib is gitignored tsc output, absent on a raw
// plugin-marketplace or git-clone install).
const HOOKS_CLI_EXIT_PATH = path.resolve(__dirname, '../hooks/lib/cli-exit.js');
const HOOKS_EXIT_CODE_REGISTRY_PATH = path.resolve(__dirname, '../hooks/lib/exit-code-registry.js');
@@ -231,7 +231,7 @@ describe('runMain', () => {
* Fix: src/cli-exit.cts non-ExitError catch branch now checks getJsonErrorMode()
* and emits the same structured envelope as error() when active.
*
* Tests run against the compiled product seam (gsd-core/bin/lib/cli-exit.cjs)
* Tests run against the compiled product seam (msd-core/bin/lib/cli-exit.cjs)
* via subprocess so that io.cjs module-level state is isolated per spawn.
*/
describe('regressions', () => {
@@ -317,7 +317,7 @@ describe('regressions', () => {
const exitResult = spawnJsonErrorRun({
jsonMode: true,
errorType: 'ExitError',
message: 'Usage: gsd-tools <command> [args]',
message: 'Usage: msd-tools <command> [args]',
});
assert.strictEqual(exitResult.status, 1, 'ExitError exits with its code');
const exitStderr = exitResult.stderr.trim();
@@ -443,7 +443,7 @@ describe('regressions', () => {
test('scripts copy keeps ExitError plain-text under json mode', () => {
const result = spawnScriptsRun({
jsonMode: true,
throwExpr: `new ExitError(1, 'Usage: gsd-tools <command> [args]')`,
throwExpr: `new ExitError(1, 'Usage: msd-tools <command> [args]')`,
});
assert.strictEqual(result.status, 1, 'ExitError exits with its own code');
const trimmed = result.stderr.trim();
@@ -628,7 +628,7 @@ describe('regressions', () => {
assert.strictEqual(seen.frozen, true);
// #3884 (ADR-3473 §8.4) legitimately added two new codes —
// PICK_FIELD_ABSENT and PICK_OUTPUT_NOT_JSON — for the `--pick`
// absence contract (see .gsd/phase/feat-3884-failure-is-a-value/40-design.md
// absence contract (see .msd/phase/feat-3884-failure-is-a-value/40-design.md
// rows B6/B11). 23 -> 25 is an intentional, documented growth of the
// enum, not drift; bump the golden count rather than treat this as a
// Hyrum violation.
@@ -640,16 +640,16 @@ describe('regressions', () => {
});
// ── Matrix rows 22-23: the unbuilt-clone constraint ──────────────────────
test('the scripts copy loads with no gsd-core tree in scope at all', (t) => {
test('the scripts copy loads with no msd-core tree in scope at all', (t) => {
// The generated file is COMMITTED and 64+ scripts/ consumers require it,
// including scripts/check-env.cjs which runs before any build. It must
// therefore not reach into gsd-core/bin/lib/, which is gitignored tsc
// therefore not reach into msd-core/bin/lib/, which is gitignored tsc
// output absent on a fresh clone.
//
// Proven by copying the file into an isolated temp directory that has no
// gsd-core sibling and no node_modules — a require of the built tree is
// msd-core sibling and no node_modules — a require of the built tree is
// MODULE_NOT_FOUND there. Deliberately NOT done by renaming the real
// gsd-core/bin/lib: test files run in parallel, so mutating a shared
// msd-core/bin/lib: test files run in parallel, so mutating a shared
// production directory would break every sibling suite mid-run.
//
// This is the sole guard of the "depends on node: builtins only"
@@ -664,7 +664,7 @@ describe('regressions', () => {
// registry require; that failure mode is exercised on its own by the
// dedicated #3906 standalone-load test below, which is the one that
// asserts the CORRECT two-file set loads clean.
const dir = createTempDir('gsd-3904-standalone-');
const dir = createTempDir('msd-3904-standalone-');
t.after(() => cleanup(dir));
const copied = path.join(dir, 'cli-exit.cjs');
fs.copyFileSync(SCRIPTS_CLI_EXIT_PATH, copied);
@@ -686,10 +686,10 @@ describe('regressions', () => {
});
test('the build sentinel is still emitted', () => {
// gsd-core/bin/ensure-runtime-build.cjs keys isBuilt() on this exact filename.
// msd-core/bin/ensure-runtime-build.cjs keys isBuilt() on this exact filename.
assert.ok(
fs.statSync(BUILT_CLI_EXIT_PATH).isFile(),
'gsd-core/bin/lib/cli-exit.cjs must remain tsc output — it is the build sentinel',
'msd-core/bin/lib/cli-exit.cjs must remain tsc output — it is the build sentinel',
);
});
});
@@ -816,26 +816,26 @@ describe('#3906: resolveContractVersion', () => {
assert.equal(resolveContractVersion({ argv: ['node', 'x', '--exit-contract=v2'], env: {} }), 'v2');
});
test('GSD_EXIT_CONTRACT=v2 env -> v2', () => {
assert.equal(resolveContractVersion({ argv: ['node', 'x'], env: { GSD_EXIT_CONTRACT: 'v2' } }), 'v2');
test('MSD_EXIT_CONTRACT=v2 env -> v2', () => {
assert.equal(resolveContractVersion({ argv: ['node', 'x'], env: { MSD_EXIT_CONTRACT: 'v2' } }), 'v2');
});
test('flag v1 beats env v2', () => {
assert.equal(
resolveContractVersion({ argv: ['node', 'x', '--exit-contract=v1'], env: { GSD_EXIT_CONTRACT: 'v2' } }),
resolveContractVersion({ argv: ['node', 'x', '--exit-contract=v1'], env: { MSD_EXIT_CONTRACT: 'v2' } }),
'v1',
);
});
test('flag v2 beats env v1 (both directions)', () => {
assert.equal(
resolveContractVersion({ argv: ['node', 'x', '--exit-contract=v2'], env: { GSD_EXIT_CONTRACT: 'v1' } }),
resolveContractVersion({ argv: ['node', 'x', '--exit-contract=v2'], env: { MSD_EXIT_CONTRACT: 'v1' } }),
'v2',
);
});
test('an empty GSD_EXIT_CONTRACT reads as unset, not as an explicit selection', () => {
assert.equal(resolveContractVersion({ argv: ['node', 'x'], env: { GSD_EXIT_CONTRACT: '' } }), 'v1');
test('an empty MSD_EXIT_CONTRACT reads as unset, not as an explicit selection', () => {
assert.equal(resolveContractVersion({ argv: ['node', 'x'], env: { MSD_EXIT_CONTRACT: '' } }), 'v1');
});
for (const bad of ['v3', 'garbage', '--exit-contract=']) {
@@ -845,13 +845,13 @@ describe('#3906: resolveContractVersion', () => {
});
}
test('GSD_EXIT_CONTRACT=v3 (env garbage) is rejected the same way', () => {
assert.throws(() => resolveContractVersion({ argv: ['node', 'x'], env: { GSD_EXIT_CONTRACT: 'v3' } }));
test('MSD_EXIT_CONTRACT=v3 (env garbage) is rejected the same way', () => {
assert.throws(() => resolveContractVersion({ argv: ['node', 'x'], env: { MSD_EXIT_CONTRACT: 'v3' } }));
});
test('casing is decided: uppercase V2 is rejected, not silently accepted', () => {
assert.throws(() => resolveContractVersion({ argv: ['node', 'x', '--exit-contract=V2'], env: {} }));
assert.throws(() => resolveContractVersion({ argv: ['node', 'x'], env: { GSD_EXIT_CONTRACT: 'V2' } }));
assert.throws(() => resolveContractVersion({ argv: ['node', 'x'], env: { MSD_EXIT_CONTRACT: 'V2' } }));
});
test('resolveContractVersion persists into the shared cell read by getContractVersion', () => {
@@ -864,13 +864,13 @@ describe('#3906: resolveContractVersion', () => {
describe('#3906: parity — runMain and terminateNow project identically (mandatory per ADR-3889 §3)', () => {
// #3906 follow-up: this MUST drive the version through the REAL ambient
// mechanism (GSD_EXIT_CONTRACT in the child's env, never touched by the
// mechanism (MSD_EXIT_CONTRACT in the child's env, never touched by the
// script body itself), not by calling resolveContractVersion() explicitly
// inside the child. A test that pre-seeds the shared cell before invoking
// either terminator can pass even if getContractVersion() never actually
// wires the ambient process in at all — which is exactly the defect this
// matrix exists to catch (both terminators reading the SAME un-wired
// default 'v1' would still "agree", 16/16, while GSD_EXIT_CONTRACT was
// default 'v1' would still "agree", 16/16, while MSD_EXIT_CONTRACT was
// silently ignored). Neither script below calls resolveContractVersion or
// passes --exit-contract; the version reaches the process ONLY via env.
function runMainExit(outcome, version) {
@@ -881,7 +881,7 @@ describe('#3906: parity — runMain and terminateNow project identically (mandat
].join('\n');
return toLegacyResult(runNode(['-e', script], {
timeoutMs: PROBE_TIMEOUT_MS,
env: { ...process.env, GSD_EXIT_CONTRACT: version },
env: { ...process.env, MSD_EXIT_CONTRACT: version },
}));
}
@@ -892,7 +892,7 @@ describe('#3906: parity — runMain and terminateNow project identically (mandat
].join('\n');
return toLegacyResult(runNode(['-e', script], {
timeoutMs: PROBE_TIMEOUT_MS,
env: { ...process.env, GSD_EXIT_CONTRACT: version },
env: { ...process.env, MSD_EXIT_CONTRACT: version },
}));
}
@@ -951,13 +951,13 @@ describe('#3906: parity — runMain and terminateNow project identically (mandat
}
// #3906 follow-up: a matrix where every row merely agrees between the two
// terminators is satisfiable by a build that ignores GSD_EXIT_CONTRACT
// terminators is satisfiable by a build that ignores MSD_EXIT_CONTRACT
// entirely (both terminators would then agree on the un-wired v1 default
// for every row, 16/16, and the matrix above would still read green). This
// block is the non-vacuousness proof the brief demands: it asserts the ONE
// row that MUST be version-sensitive actually differs by version, and
// spot-checks a control row that must NOT.
test('non-vacuousness: DEGRADED is version-sensitive via ambient GSD_EXIT_CONTRACT', () => {
test('non-vacuousness: DEGRADED is version-sensitive via ambient MSD_EXIT_CONTRACT', () => {
const runMainV1 = runMainExit('DEGRADED', 'v1');
const runMainV2 = runMainExit('DEGRADED', 'v2');
const terminateNowV1 = terminateNowExit('DEGRADED', 'v1');
@@ -979,7 +979,7 @@ describe('#3906: parity — runMain and terminateNow project identically (mandat
);
});
test('control: a non-DEGRADED outcome (FAIL) stays version-invariant via ambient GSD_EXIT_CONTRACT', () => {
test('control: a non-DEGRADED outcome (FAIL) stays version-invariant via ambient MSD_EXIT_CONTRACT', () => {
const runMainV1 = runMainExit('FAIL', 'v1');
const runMainV2 = runMainExit('FAIL', 'v2');
assert.equal(runMainV1.status, 1);
@@ -989,28 +989,28 @@ describe('#3906: parity — runMain and terminateNow project identically (mandat
// ─── #3906 acceptance criterion, made executable ────────────────────────────
//
// "user can run the gsd-tools command with --exit-contract=v2 (or
// GSD_EXIT_CONTRACT=v2 in the environment) and observe the v2 registry
// "user can run the msd-tools command with --exit-contract=v2 (or
// MSD_EXIT_CONTRACT=v2 in the environment) and observe the v2 registry
// projection on the exit status; absent both, the same command yields the v1
// integers." Nothing in the module wired the ambient process to the
// terminators before this: getContractVersion() only ever read the shared
// cell, and nothing populated that cell absent an explicit
// resolveContractVersion()/setContractVersion() call — so a bare
// `GSD_EXIT_CONTRACT=v2 node -e "...terminateNow('DEGRADED')..."` exited 0,
// `MSD_EXIT_CONTRACT=v2 node -e "...terminateNow('DEGRADED')..."` exited 0,
// not 80. These tests spawn a fresh child per case (a fresh process has an
// empty cell) and touch NOTHING but the documented public surface.
describe('#3906: ambient GSD_EXIT_CONTRACT/--exit-contract wiring (acceptance criterion)', () => {
test('terminateNow: GSD_EXIT_CONTRACT=v2 -> DEGRADED exits 80', () => {
describe('#3906: ambient MSD_EXIT_CONTRACT/--exit-contract wiring (acceptance criterion)', () => {
test('terminateNow: MSD_EXIT_CONTRACT=v2 -> DEGRADED exits 80', () => {
const r = toLegacyResult(runNode(['-e', [
`const c = require(${JSON.stringify(BUILT_CLI_EXIT_PATH)});`,
`c.terminateNow('DEGRADED', {});`,
].join('\n')], { timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, GSD_EXIT_CONTRACT: 'v2' } }));
].join('\n')], { timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, MSD_EXIT_CONTRACT: 'v2' } }));
assert.equal(r.status, 80, `stderr: ${r.stderr}`);
});
test('terminateNow: no env, no flag -> DEGRADED exits 0 (v1 default unchanged)', () => {
const env = { ...process.env };
delete env.GSD_EXIT_CONTRACT;
delete env.MSD_EXIT_CONTRACT;
const r = toLegacyResult(runNode(['-e', [
`const c = require(${JSON.stringify(BUILT_CLI_EXIT_PATH)});`,
`c.terminateNow('DEGRADED', {});`,
@@ -1018,18 +1018,18 @@ describe('#3906: ambient GSD_EXIT_CONTRACT/--exit-contract wiring (acceptance cr
assert.equal(r.status, 0, `stderr: ${r.stderr}`);
});
test('runMain: GSD_EXIT_CONTRACT=v2 -> DEGRADED exits 80', () => {
test('runMain: MSD_EXIT_CONTRACT=v2 -> DEGRADED exits 80', () => {
const r = toLegacyResult(runNode(['-e', [
`const c = require(${JSON.stringify(BUILT_CLI_EXIT_PATH)});`,
`c.runMain(() => 'DEGRADED');`,
`setImmediate(() => {});`,
].join('\n')], { timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, GSD_EXIT_CONTRACT: 'v2' } }));
].join('\n')], { timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, MSD_EXIT_CONTRACT: 'v2' } }));
assert.equal(r.status, 80, `stderr: ${r.stderr}`);
});
test('runMain: no env, no flag -> DEGRADED exits 0 (v1 default unchanged)', () => {
const env = { ...process.env };
delete env.GSD_EXIT_CONTRACT;
delete env.MSD_EXIT_CONTRACT;
const r = toLegacyResult(runNode(['-e', [
`const c = require(${JSON.stringify(BUILT_CLI_EXIT_PATH)});`,
`c.runMain(() => 'DEGRADED');`,
@@ -1044,7 +1044,7 @@ describe('#3906: ambient GSD_EXIT_CONTRACT/--exit-contract wiring (acceptance cr
// real CLI entrypoint is invoked as `node <file> --exit-contract=v2`, so
// the flag path is proven with a real temp script file, not `-e`.
test('flag path: node <file> --exit-contract=v2 -> terminateNow DEGRADED exits 80', (t) => {
const dir = createTempDir('gsd-3906-flag-');
const dir = createTempDir('msd-3906-flag-');
t.after(() => cleanup(dir));
const scriptPath = path.join(dir, 'terminate-degraded.cjs');
fs.writeFileSync(scriptPath, [
@@ -1053,13 +1053,13 @@ describe('#3906: ambient GSD_EXIT_CONTRACT/--exit-contract wiring (acceptance cr
'',
].join('\n'));
const env = { ...process.env };
delete env.GSD_EXIT_CONTRACT;
delete env.MSD_EXIT_CONTRACT;
const r = toLegacyResult(runNode([scriptPath, '--exit-contract=v2'], { timeoutMs: PROBE_TIMEOUT_MS, env }));
assert.equal(r.status, 80, `stderr: ${r.stderr}`);
});
test('flag path: node <file> with no flag -> terminateNow DEGRADED exits 0', (t) => {
const dir = createTempDir('gsd-3906-flag-');
const dir = createTempDir('msd-3906-flag-');
t.after(() => cleanup(dir));
const scriptPath = path.join(dir, 'terminate-degraded.cjs');
fs.writeFileSync(scriptPath, [
@@ -1068,7 +1068,7 @@ describe('#3906: ambient GSD_EXIT_CONTRACT/--exit-contract wiring (acceptance cr
'',
].join('\n'));
const env = { ...process.env };
delete env.GSD_EXIT_CONTRACT;
delete env.MSD_EXIT_CONTRACT;
const r = toLegacyResult(runNode([scriptPath], { timeoutMs: PROBE_TIMEOUT_MS, env }));
assert.equal(r.status, 0, `stderr: ${r.stderr}`);
});
@@ -1077,25 +1077,25 @@ describe('#3906: ambient GSD_EXIT_CONTRACT/--exit-contract wiring (acceptance cr
// is the module's own sanctioned way to write an explicit version into the
// shared cell, and it is what this precedence rests on: getContractVersion's
// lazy ambient-resolution path must be skipped entirely once the cell is
// already populated, so a later read of GSD_EXIT_CONTRACT must NOT unseat it.
test('an explicit resolveContractVersion() call beats a later ambient GSD_EXIT_CONTRACT read (precedence)', () => {
// already populated, so a later read of MSD_EXIT_CONTRACT must NOT unseat it.
test('an explicit resolveContractVersion() call beats a later ambient MSD_EXIT_CONTRACT read (precedence)', () => {
const r = toLegacyResult(runNode(['-e', [
`const c = require(${JSON.stringify(BUILT_CLI_EXIT_PATH)});`,
`c.resolveContractVersion({ argv: ['node','x','--exit-contract=v1'], env: {} });`,
`c.terminateNow('DEGRADED', {});`,
].join('\n')], { timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, GSD_EXIT_CONTRACT: 'v2' } }));
].join('\n')], { timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, MSD_EXIT_CONTRACT: 'v2' } }));
assert.equal(
r.status, 0,
`an explicit resolveContractVersion('v1') call must beat a later ambient GSD_EXIT_CONTRACT=v2 read; stderr: ${r.stderr}`,
`an explicit resolveContractVersion('v1') call must beat a later ambient MSD_EXIT_CONTRACT=v2 read; stderr: ${r.stderr}`,
);
});
test('GSD_EXIT_CONTRACT=v3 (invalid) still THROWS on the lazy ambient path, never silently v1 (runMain: generic-throw arm, exit 1)', () => {
test('MSD_EXIT_CONTRACT=v3 (invalid) still THROWS on the lazy ambient path, never silently v1 (runMain: generic-throw arm, exit 1)', () => {
const r = toLegacyResult(runNode(['-e', [
`const c = require(${JSON.stringify(BUILT_CLI_EXIT_PATH)});`,
`c.runMain(() => 'DEGRADED');`,
`setImmediate(() => {});`,
].join('\n')], { timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, GSD_EXIT_CONTRACT: 'v3' } }));
].join('\n')], { timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, MSD_EXIT_CONTRACT: 'v3' } }));
assert.equal(r.status, 1, `expected the generic-throw exit code 1; stderr: ${r.stderr}`);
assert.ok(
/unrecognized exit-contract version/.test(r.stderr),
@@ -1108,11 +1108,11 @@ describe('#3906: ambient GSD_EXIT_CONTRACT/--exit-contract wiring (acceptance cr
// throw at all (an enforcement-hook caller's own outer catch could turn
// that into a fail-open exit 0). It must terminate deterministically with
// INTERNAL (70) and diagnose on stderr instead.
test('terminateNow: GSD_EXIT_CONTRACT=v3 (invalid) exits 70 (INTERNAL), not silently v1 and not a propagated throw', () => {
test('terminateNow: MSD_EXIT_CONTRACT=v3 (invalid) exits 70 (INTERNAL), not silently v1 and not a propagated throw', () => {
const r = toLegacyResult(runNode(['-e', [
`const c = require(${JSON.stringify(BUILT_CLI_EXIT_PATH)});`,
`c.terminateNow('DEGRADED', {});`,
].join('\n')], { timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, GSD_EXIT_CONTRACT: 'v3' } }));
].join('\n')], { timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, MSD_EXIT_CONTRACT: 'v3' } }));
assert.equal(r.status, 70, `expected INTERNAL (70); stderr: ${r.stderr}`);
assert.ok(
/unrecognized exit-contract version/.test(r.stderr),
@@ -1124,21 +1124,21 @@ describe('#3906: ambient GSD_EXIT_CONTRACT/--exit-contract wiring (acceptance cr
// ─── #3912 regression: `--exit-contract=<v>` in LEADING argv position ──────
//
// resolveContractVersion() scans argv non-destructively (findExitContractFlag,
// gsd-core/bin/lib/cli-exit.cjs). Nothing previously spliced the flag out of
// the `gsd-tools` CLI dispatcher's own argv before it fell through to command
// msd-core/bin/lib/cli-exit.cjs). Nothing previously spliced the flag out of
// the `msd-tools` CLI dispatcher's own argv before it fell through to command
// dispatch — the `--json-errors` block did this splice for itself, but
// `--exit-contract=<v>` never got the same treatment. The dispatcher treats
// argv[0] as the command name, so:
// `gsd-tools --exit-contract=v2 state validate --strict` (leading) died
// `msd-tools --exit-contract=v2 state validate --strict` (leading) died
// with "Unknown command: --exit-contract=v2" (exit 64) — the flag was never
// consumed and squatted on the command-name slot.
// `gsd-tools state-snapshot --exit-contract=v2` (trailing) worked, because
// `msd-tools state-snapshot --exit-contract=v2` (trailing) worked, because
// the flag landed after the command name and never collided with dispatch.
describe('#3912: gsd-tools dispatcher splices --exit-contract=<v> regardless of argv position', () => {
const GSD_TOOLS_BIN = path.resolve(__dirname, '../gsd-core/bin/gsd-tools.cjs');
describe('#3912: msd-tools dispatcher splices --exit-contract=<v> regardless of argv position', () => {
const MSD_TOOLS_BIN = path.resolve(__dirname, '../msd-core/bin/msd-tools.cjs');
function run(args, options = {}) {
return toLegacyResult(runNode([GSD_TOOLS_BIN, ...args], { timeoutMs: PROBE_TIMEOUT_MS, ...options }));
return toLegacyResult(runNode([MSD_TOOLS_BIN, ...args], { timeoutMs: PROBE_TIMEOUT_MS, ...options }));
}
// Fixture: a temp dir with a `.planning/` directory but no `STATE.md`, so
@@ -1514,11 +1514,11 @@ describe('#3906: terminateNow', () => {
assert.equal(r.status, 70, `expected INTERNAL (70); stderr: ${r.stderr}`);
});
test('FAIL under an invalid ambient GSD_EXIT_CONTRACT=v3 exits 70, not a Node crash and not a silent v1', () => {
test('FAIL under an invalid ambient MSD_EXIT_CONTRACT=v3 exits 70, not a Node crash and not a silent v1', () => {
const r = toLegacyResult(runNode(['-e', [
`const c = require(${JSON.stringify(BUILT_CLI_EXIT_PATH)});`,
`c.terminateNow('FAIL', {});`,
].join('\n')], { timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, GSD_EXIT_CONTRACT: 'v3' } }));
].join('\n')], { timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, MSD_EXIT_CONTRACT: 'v3' } }));
assert.equal(r.status, 70, `expected INTERNAL (70), not a Node crash / silent v1; stderr: ${r.stderr}`);
assert.notEqual(r.status, 1, 'FAIL under a valid v1 resolution would exit 1 — 70 proves the invalid version was not silently accepted as v1');
});
@@ -1666,8 +1666,8 @@ describe('#3906: cross-copy — the built copy and the scripts copy agree', () =
}
});
test('scripts/lib/cli-exit.cjs + its sibling exit-code-registry.cjs load standalone, no gsd-core sibling', (t) => {
const dir = createTempDir('gsd-3906-standalone-');
test('scripts/lib/cli-exit.cjs + its sibling exit-code-registry.cjs load standalone, no msd-core sibling', (t) => {
const dir = createTempDir('msd-3906-standalone-');
t.after(() => cleanup(dir));
const copiedExit = path.join(dir, 'cli-exit.cjs');
const copiedRegistry = path.join(dir, 'exit-code-registry.cjs');
@@ -1675,7 +1675,7 @@ describe('#3906: cross-copy — the built copy and the scripts copy agree', () =
fs.copyFileSync(path.resolve(__dirname, '../scripts/lib/exit-code-registry.cjs'), copiedRegistry);
// This directory contains ONLY these two files — no node_modules, no
// gsd-core sibling. A successful load here is the behavioral proof (per
// msd-core sibling. A successful load here is the behavioral proof (per
// CONTRIBUTING.md's ban on source-grepping a generated .cjs for its
// require() specifiers) that this module's only dependencies are
// node: builtins plus ./exit-code-registry.cjs: anything else would
@@ -1719,16 +1719,16 @@ describe('#3906: cross-copy — the built copy and the scripts copy agree', () =
//
// The WHOLE POINT of hooks/lib/cli-exit.js is that a shipped enforcement hook
// can terminate through terminateNow WITHOUT depending on any build
// artifact. gsd-core/bin/lib is gitignored tsc output and is ABSENT on a raw
// artifact. msd-core/bin/lib is gitignored tsc output and is ABSENT on a raw
// plugin-marketplace or git-clone install. These tests prove that property
// hermetically: by copying ONLY hooks/lib/cli-exit.js and its sibling
// hooks/lib/exit-code-registry.js into a fresh, otherwise-empty tmpdir (no
// gsd-core sibling, no node_modules) and requiring the copy from a CHILD
// msd-core sibling, no node_modules) and requiring the copy from a CHILD
// process rooted there.
describe('#3911: hooks/lib/cli-exit.js loads and terminates with no build present (A4, load-bearing)', () => {
/** Copy both hooks/lib artifacts into a fresh, otherwise-empty tmpdir. */
function makeStandaloneHooksCopy(t) {
const dir = createTempDir('gsd-3911-hooks-standalone-');
const dir = createTempDir('msd-3911-hooks-standalone-');
t.after(() => cleanup(dir));
const copiedExit = path.join(dir, 'cli-exit.js');
const copiedRegistry = path.join(dir, 'exit-code-registry.js');
@@ -1738,7 +1738,7 @@ describe('#3911: hooks/lib/cli-exit.js loads and terminates with no build presen
}
// This test must FAIL if hooks/lib/cli-exit.js ever gains a require
// reaching outside hooks/lib/ (e.g. back into gsd-core/bin/lib, or a
// reaching outside hooks/lib/ (e.g. back into msd-core/bin/lib, or a
// node_modules package): the tmpdir contains NOTHING else, so any such
// require resolves to MODULE_NOT_FOUND and the child crashes before
// terminateNow ever runs, failing every assertion below.
@@ -1845,7 +1845,7 @@ describe('#3911: the --check guards for the new hooks/lib artifacts can actually
const CHECK_TIMEOUT_MS = 90000;
test('gen-hooks-cli-exit.cjs --check fails on a corrupted TMPDIR copy of hooks/lib/cli-exit.js, names the file, and clears on restore', (t) => {
const dir = createTempDir('gsd-3911-hooks-cli-exit-check-');
const dir = createTempDir('msd-3911-hooks-cli-exit-check-');
t.after(() => cleanup(dir));
const copiedOut = path.join(dir, 'cli-exit.js');
const original = fs.readFileSync(HOOKS_CLI_EXIT_PATH);
@@ -1875,7 +1875,7 @@ describe('#3911: the --check guards for the new hooks/lib artifacts can actually
});
test('gen-exit-code-registry.cjs --check fails on a corrupted TMPDIR copy of hooks/lib/exit-code-registry.js, names the file, and clears on restore', (t) => {
const dir = createTempDir('gsd-3911-exit-code-registry-check-');
const dir = createTempDir('msd-3911-exit-code-registry-check-');
t.after(() => cleanup(dir));
// Copy all FIVE generated artifacts into the tmpdir so --check compares
@@ -1975,7 +1975,7 @@ describe('#3912: pending-outcome cell (runMain precedence + parity)', () => {
// Under v2, DEGRADED alone would project to 80; PASS must win with 0.
const r = toLegacyResult(runNode(['-e', script], {
timeoutMs: PROBE_TIMEOUT_MS,
env: { ...process.env, GSD_EXIT_CONTRACT: 'v2' },
env: { ...process.env, MSD_EXIT_CONTRACT: 'v2' },
}));
assert.equal(r.status, 0, `explicit PASS return must win over the pending DEGRADED cell; stderr: ${r.stderr}`);
});
@@ -1989,7 +1989,7 @@ describe('#3912: pending-outcome cell (runMain precedence + parity)', () => {
].join('\n');
const r = toLegacyResult(runNode(['-e', script], {
timeoutMs: PROBE_TIMEOUT_MS,
env: { ...process.env, GSD_EXIT_CONTRACT: 'v2' },
env: { ...process.env, MSD_EXIT_CONTRACT: 'v2' },
}));
assert.equal(r.status, 42, `explicit numeric return must win over the pending DEGRADED cell; stderr: ${r.stderr}`);
});
@@ -2012,11 +2012,11 @@ describe('#3912: pending-outcome cell (runMain precedence + parity)', () => {
`setImmediate(() => {});`,
].join('\n');
const v1 = toLegacyResult(runNode(['-e', script], {
timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, GSD_EXIT_CONTRACT: 'v1' },
timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, MSD_EXIT_CONTRACT: 'v1' },
}));
assert.equal(v1.status, 0, `stderr: ${v1.stderr}`);
const v2 = toLegacyResult(runNode(['-e', script], {
timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, GSD_EXIT_CONTRACT: 'v2' },
timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, MSD_EXIT_CONTRACT: 'v2' },
}));
assert.equal(v2.status, 80, `stderr: ${v2.stderr}`);
});
@@ -2038,11 +2038,11 @@ describe('#3912: pending-outcome cell (runMain precedence + parity)', () => {
`setImmediate(() => {});`,
].join('\n');
const v1 = toLegacyResult(runNode(['-e', script], {
timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, GSD_EXIT_CONTRACT: 'v1' },
timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, MSD_EXIT_CONTRACT: 'v1' },
}));
assert.equal(v1.status, 1, `an already-set non-zero exitCode must not be clobbered down to DEGRADED's v1 projection (0); stderr: ${v1.stderr}`);
const v2 = toLegacyResult(runNode(['-e', script], {
timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, GSD_EXIT_CONTRACT: 'v2' },
timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, MSD_EXIT_CONTRACT: 'v2' },
}));
assert.equal(v2.status, 1, `an already-set non-zero exitCode must not be clobbered by DEGRADED's v2 projection (80) either; stderr: ${v2.stderr}`);
});
@@ -2050,7 +2050,7 @@ describe('#3912: pending-outcome cell (runMain precedence + parity)', () => {
// C6: extends the existing three-copy parity coverage (json-error-mode cell,
// tested above at "both copies of the exit module share one json-error-mode
// cell") to the pending-outcome cell, across all THREE emitted copies —
// built (gsd-core/bin/lib), scripts/lib, and hooks/lib — not just two.
// built (msd-core/bin/lib), scripts/lib, and hooks/lib — not just two.
test('C6: all three emitted copies of cli-exit share ONE pending-outcome cell', () => {
const r = toLegacyResult(runNode(['-e', [
`const built = require(${JSON.stringify(BUILT_CLI_EXIT_PATH)});`,
@@ -2081,7 +2081,7 @@ describe('#3912: pending-outcome cell (runMain precedence + parity)', () => {
`c.runMain(() => undefined);`,
`setImmediate(() => {});`,
].join('\n')], {
timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, GSD_EXIT_CONTRACT: version },
timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, MSD_EXIT_CONTRACT: version },
}));
const expected = version === 'v1' ? 0 : 80;
assert.equal(