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:
@@ -9,7 +9,7 @@ const path = require('node:path');
|
||||
const fc = require('fast-check');
|
||||
|
||||
const {
|
||||
GSD_OWNED_ENTRIES,
|
||||
MSD_OWNED_ENTRIES,
|
||||
artifactTargets,
|
||||
MAX_DEPTH,
|
||||
resolveLiveConfigRoots,
|
||||
@@ -75,8 +75,8 @@ describe('#2665: live-config hermeticity guard', () => {
|
||||
test('a clean run produces no violations', () => {
|
||||
const root = tmpRoot();
|
||||
try {
|
||||
fs.mkdirSync(path.join(root, 'gsd-core', 'bin'), { recursive: true });
|
||||
fs.writeFileSync(path.join(root, 'gsd-core', 'bin', 'x.cjs'), 'x');
|
||||
fs.mkdirSync(path.join(root, 'msd-core', 'bin'), { recursive: true });
|
||||
fs.writeFileSync(path.join(root, 'msd-core', 'bin', 'x.cjs'), 'x');
|
||||
|
||||
const before = snapshotLiveConfig([root]);
|
||||
const after = snapshotLiveConfig([root]);
|
||||
@@ -92,13 +92,13 @@ describe('#2665: live-config hermeticity guard', () => {
|
||||
const before = snapshotLiveConfig([root]);
|
||||
// Exactly the Blocker 1 shape: an in-process install(true, …) landing a
|
||||
// full global install in a live config dir that was previously empty.
|
||||
fs.mkdirSync(path.join(root, 'gsd-core'), { recursive: true });
|
||||
fs.writeFileSync(path.join(root, 'gsd-file-manifest.json'), '{}');
|
||||
fs.mkdirSync(path.join(root, 'msd-core'), { recursive: true });
|
||||
fs.writeFileSync(path.join(root, 'msd-file-manifest.json'), '{}');
|
||||
|
||||
const violations = diffLiveConfig(before, snapshotLiveConfig([root]));
|
||||
const kinds = Object.fromEntries(violations.map((v) => [path.basename(v.path), v.kind]));
|
||||
assert.strictEqual(kinds['gsd-core'], 'created');
|
||||
assert.strictEqual(kinds['gsd-file-manifest.json'], 'created');
|
||||
assert.strictEqual(kinds['msd-core'], 'created');
|
||||
assert.strictEqual(kinds['msd-file-manifest.json'], 'created');
|
||||
} finally {
|
||||
cleanup(root);
|
||||
}
|
||||
@@ -107,9 +107,9 @@ describe('#2665: live-config hermeticity guard', () => {
|
||||
test('detects an existing install MODIFIED during the run', () => {
|
||||
const root = tmpRoot();
|
||||
try {
|
||||
const target = path.join(root, 'gsd-core', 'bin');
|
||||
const target = path.join(root, 'msd-core', 'bin');
|
||||
fs.mkdirSync(target, { recursive: true });
|
||||
const file = path.join(target, 'gsd-tools.cjs');
|
||||
const file = path.join(target, 'msd-tools.cjs');
|
||||
fs.writeFileSync(file, 'original');
|
||||
|
||||
const before = snapshotLiveConfig([root]);
|
||||
@@ -122,13 +122,13 @@ describe('#2665: live-config hermeticity guard', () => {
|
||||
const violations = diffLiveConfig(before, snapshotLiveConfig([root]));
|
||||
assert.strictEqual(violations.length, 1);
|
||||
assert.strictEqual(violations[0].kind, 'modified');
|
||||
assert.strictEqual(path.basename(violations[0].path), 'gsd-core');
|
||||
assert.strictEqual(path.basename(violations[0].path), 'msd-core');
|
||||
} finally {
|
||||
cleanup(root);
|
||||
}
|
||||
});
|
||||
|
||||
test('ignores non-GSD writes in a shared config root', () => {
|
||||
test('ignores non-MSD writes in a shared config root', () => {
|
||||
const root = tmpRoot();
|
||||
try {
|
||||
const before = snapshotLiveConfig([root]);
|
||||
@@ -144,15 +144,15 @@ describe('#2665: live-config hermeticity guard', () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('watches exactly the GSD-owned entry set', () => {
|
||||
test('watches exactly the MSD-owned entry set', () => {
|
||||
const root = tmpRoot();
|
||||
try {
|
||||
const snap = snapshotLiveConfig([root]);
|
||||
const watched = Object.keys(snap).map((p) => path.relative(root, p)).sort();
|
||||
// Top-level owned entries PLUS the nested paths GSD owns wholesale inside a
|
||||
// Top-level owned entries PLUS the nested paths MSD owns wholesale inside a
|
||||
// shared root; prefixed children contribute nothing in an empty root.
|
||||
const expected = [
|
||||
...GSD_OWNED_ENTRIES,
|
||||
...MSD_OWNED_ENTRIES,
|
||||
...artifactTargets().owned.map((o) => path.join(...o.split('/'))),
|
||||
].sort();
|
||||
assert.deepStrictEqual(watched, expected);
|
||||
@@ -161,28 +161,28 @@ describe('#2665: live-config hermeticity guard', () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('detects a gsd-prefixed artifact written into a SHARED dir', () => {
|
||||
test('detects a msd-prefixed artifact written into a SHARED dir', () => {
|
||||
const root = tmpRoot();
|
||||
try {
|
||||
fs.mkdirSync(path.join(root, 'skills'), { recursive: true });
|
||||
const before = snapshotLiveConfig([root]);
|
||||
// The exact leak the first version of this guard MISSED: a writer that
|
||||
// sandboxed HOME but inherited an ambient CLAUDE_CONFIG_DIR landed
|
||||
// <live>/skills/gsd-dev-preferences/SKILL.md, outside the three
|
||||
// top-level GSD entries.
|
||||
fs.mkdirSync(path.join(root, 'skills', 'gsd-dev-preferences'), { recursive: true });
|
||||
fs.writeFileSync(path.join(root, 'skills', 'gsd-dev-preferences', 'SKILL.md'), '# x');
|
||||
// <live>/skills/msd-dev-preferences/SKILL.md, outside the three
|
||||
// top-level MSD entries.
|
||||
fs.mkdirSync(path.join(root, 'skills', 'msd-dev-preferences'), { recursive: true });
|
||||
fs.writeFileSync(path.join(root, 'skills', 'msd-dev-preferences', 'SKILL.md'), '# x');
|
||||
|
||||
const violations = diffLiveConfig(before, snapshotLiveConfig([root]));
|
||||
assert.strictEqual(violations.length, 1);
|
||||
assert.strictEqual(violations[0].kind, 'created');
|
||||
assert.strictEqual(path.basename(violations[0].path), 'gsd-dev-preferences');
|
||||
assert.strictEqual(path.basename(violations[0].path), 'msd-dev-preferences');
|
||||
} finally {
|
||||
cleanup(root);
|
||||
}
|
||||
});
|
||||
|
||||
test('ignores NON-gsd artifacts in a shared dir', () => {
|
||||
test('ignores NON-msd artifacts in a shared dir', () => {
|
||||
const root = tmpRoot();
|
||||
try {
|
||||
fs.mkdirSync(path.join(root, 'skills'), { recursive: true });
|
||||
@@ -199,31 +199,31 @@ describe('#2665: live-config hermeticity guard', () => {
|
||||
|
||||
test('detects a leaked hook script and the install marker files', () => {
|
||||
// Self-found by re-deriving the census at round 5 rather than by a review
|
||||
// finding. bin/install.js writes hooks/gsd-*.js, .gsd-source and .gsd-profile
|
||||
// into the config ROOT; `hooks` was absent from GSD_PREFIXED_PARENTS and the
|
||||
// two dot-prefixed markers from GSD_OWNED_ENTRIES, so all three leaked past
|
||||
// the guard silently -- the same shape as the skills/gsd-dev-preferences miss
|
||||
// finding. bin/install.js writes hooks/msd-*.js, .msd-source and .msd-profile
|
||||
// into the config ROOT; `hooks` was absent from MSD_PREFIXED_PARENTS and the
|
||||
// two dot-prefixed markers from MSD_OWNED_ENTRIES, so all three leaked past
|
||||
// the guard silently -- the same shape as the skills/msd-dev-preferences miss
|
||||
// that motivated the prefixed-parent scan in the first place.
|
||||
const root = tmpRoot();
|
||||
try {
|
||||
fs.mkdirSync(path.join(root, 'hooks'), { recursive: true });
|
||||
const before = snapshotLiveConfig([root]);
|
||||
fs.writeFileSync(path.join(root, 'hooks', 'gsd-check-update.js'), '// x');
|
||||
fs.writeFileSync(path.join(root, '.gsd-source'), 'npm');
|
||||
fs.writeFileSync(path.join(root, '.gsd-profile'), 'default');
|
||||
fs.writeFileSync(path.join(root, 'hooks', 'msd-check-update.js'), '// x');
|
||||
fs.writeFileSync(path.join(root, '.msd-source'), 'npm');
|
||||
fs.writeFileSync(path.join(root, '.msd-profile'), 'default');
|
||||
|
||||
const created = diffLiveConfig(before, snapshotLiveConfig([root]))
|
||||
.filter((v) => v.kind === 'created')
|
||||
.map((v) => path.basename(v.path))
|
||||
.sort();
|
||||
assert.deepStrictEqual(created, ['.gsd-profile', '.gsd-source', 'gsd-check-update.js']);
|
||||
assert.deepStrictEqual(created, ['.msd-profile', '.msd-source', 'msd-check-update.js']);
|
||||
} finally {
|
||||
cleanup(root);
|
||||
}
|
||||
});
|
||||
|
||||
test('a NON-gsd hook belonging to the host agent is still ignored', () => {
|
||||
// Widening GSD_PREFIXED_PARENTS must not widen ownership: `hooks/` is shared
|
||||
test('a NON-msd hook belonging to the host agent is still ignored', () => {
|
||||
// Widening MSD_PREFIXED_PARENTS must not widen ownership: `hooks/` is shared
|
||||
// with the host agent, and a guard that flags its files gets switched off.
|
||||
const root = tmpRoot();
|
||||
try {
|
||||
@@ -240,7 +240,7 @@ describe('#2665: live-config hermeticity guard', () => {
|
||||
test('artifact parents are DERIVED from the registry, not hand-listed', () => {
|
||||
// Round 5's adversarial review refuted the completeness claim of the
|
||||
// hand-list: it missed Kilo's SINGULAR `command/`, `workflows/`, and hermes'
|
||||
// `skills/gsd` -- a whole directory whose name carries no `gsd-` prefix, so
|
||||
// `skills/msd` -- a whole directory whose name carries no `msd-` prefix, so
|
||||
// no prefix rule could ever reach it.
|
||||
const { parents, owned } = artifactTargets();
|
||||
// NB: `workflows` is declared only in LOCAL scope (windsurf), so it is
|
||||
@@ -249,14 +249,14 @@ describe('#2665: live-config hermeticity guard', () => {
|
||||
for (const p of ['agents', 'commands', 'command', 'skills', 'hooks', 'plugins', 'scripts', 'extensions']) {
|
||||
assert.ok(p in parents, `expected derived parent ${p} in ${JSON.stringify(Object.keys(parents))}`);
|
||||
}
|
||||
// kimi's kimi-agents layout declares prefix `gsd` (no hyphen); a fixed `gsd-`
|
||||
// scan cannot see agents/gsd.yaml, which is the defect this derivation closes.
|
||||
// kimi's kimi-agents layout declares prefix `msd` (no hyphen); a fixed `msd-`
|
||||
// scan cannot see agents/msd.yaml, which is the defect this derivation closes.
|
||||
assert.ok(
|
||||
parents.agents.includes('gsd'),
|
||||
`agents must carry kimi's bare 'gsd' prefix; got ${JSON.stringify(parents.agents)}`,
|
||||
parents.agents.includes('msd'),
|
||||
`agents must carry kimi's bare 'msd' prefix; got ${JSON.stringify(parents.agents)}`,
|
||||
);
|
||||
assert.ok(owned.includes('skills/gsd'), `expected hermes skills/gsd in ${JSON.stringify(owned)}`);
|
||||
// Exact GSD filenames only — never the shared directories that contain them.
|
||||
assert.ok(owned.includes('skills/msd'), `expected hermes skills/msd in ${JSON.stringify(owned)}`);
|
||||
// Exact MSD filenames only — never the shared directories that contain them.
|
||||
for (const o of ['scripts/fix-slash-commands.cjs', 'hooks/managed-hooks-registry.cjs']) {
|
||||
assert.ok(owned.includes(o), `expected owned nested ${o} in ${JSON.stringify(owned)}`);
|
||||
}
|
||||
@@ -265,22 +265,22 @@ describe('#2665: live-config hermeticity guard', () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('detects leaks a single hardcoded gsd- prefix cannot see', () => {
|
||||
test('detects leaks a single hardcoded msd- prefix cannot see', () => {
|
||||
const root = tmpRoot();
|
||||
try {
|
||||
for (const d of ['skills/gsd', 'agents', 'plugins', 'command', 'extensions']) {
|
||||
for (const d of ['skills/msd', 'agents', 'plugins', 'command', 'extensions']) {
|
||||
fs.mkdirSync(path.join(root, ...d.split('/')), { recursive: true });
|
||||
}
|
||||
const before = snapshotLiveConfig([root]);
|
||||
const future = new Date(Date.now() + 10000);
|
||||
// kimi declares prefix `gsd` (no hyphen) and writes agents/gsd.yaml;
|
||||
// pi writes extensions/gsd.js. A fixed `gsd-` scan sees neither.
|
||||
// kimi declares prefix `msd` (no hyphen) and writes agents/msd.yaml;
|
||||
// pi writes extensions/msd.js. A fixed `msd-` scan sees neither.
|
||||
const leaks = [
|
||||
['skills', 'gsd', 'executor.md'],
|
||||
['agents', 'gsd.yaml'],
|
||||
['extensions', 'gsd.js'],
|
||||
['plugins', 'gsd-core.js'],
|
||||
['command', 'gsd-plan.md'],
|
||||
['skills', 'msd', 'executor.md'],
|
||||
['agents', 'msd.yaml'],
|
||||
['extensions', 'msd.js'],
|
||||
['plugins', 'msd-core.js'],
|
||||
['command', 'msd-plan.md'],
|
||||
];
|
||||
for (const seg of leaks) {
|
||||
const f = path.join(root, ...seg);
|
||||
@@ -290,7 +290,7 @@ describe('#2665: live-config hermeticity guard', () => {
|
||||
}
|
||||
|
||||
const hit = diffLiveConfig(before, snapshotLiveConfig([root])).map((v) => v.path);
|
||||
for (const expected of ['skills/gsd', 'agents/gsd.yaml', 'extensions/gsd.js', 'plugins/gsd-core.js', 'command/gsd-plan.md']) {
|
||||
for (const expected of ['skills/msd', 'agents/msd.yaml', 'extensions/msd.js', 'plugins/msd-core.js', 'command/msd-plan.md']) {
|
||||
const abs = path.join(root, ...expected.split('/'));
|
||||
assert.ok(hit.includes(abs), `${expected} leaked undetected; got ${JSON.stringify(hit)}`);
|
||||
}
|
||||
@@ -303,7 +303,7 @@ describe('#2665: live-config hermeticity guard', () => {
|
||||
// The false-positive case a prior commit shipped: hooks/lib, hooks/package.json,
|
||||
// scripts/lib and scripts/changeset were watched WHOLESALE, so touching a
|
||||
// user-authored helper in any of them tripped the guard. The installer itself
|
||||
// preserves foreign files in all four, so they are not GSD's to watch.
|
||||
// preserves foreign files in all four, so they are not MSD's to watch.
|
||||
const root = tmpRoot();
|
||||
try {
|
||||
for (const d of ['hooks/lib', 'scripts/lib', 'scripts/changeset']) {
|
||||
@@ -339,52 +339,52 @@ describe('#2665: live-config hermeticity guard', () => {
|
||||
// The MISSED finding from round 5's review: B3 closed this for the registry
|
||||
// roots and left the identical hole in resolveExtraWatchTargets.
|
||||
const targets = resolveExtraWatchTargets({
|
||||
env: { GSD_HOME: '/ambient-gsd-home', KIMI_SHARE_DIR: '/ambient-kimi' },
|
||||
env: { MSD_HOME: '/ambient-msd-home', KIMI_SHARE_DIR: '/ambient-kimi' },
|
||||
os: { homedir: () => '/fallback-home' },
|
||||
});
|
||||
assert.ok(targets.includes(path.resolve('/ambient-gsd-home/.gsd')), 'ambient $GSD_HOME/.gsd');
|
||||
assert.ok(targets.includes(path.resolve('/fallback-home/.gsd')), 'HOME-derived .gsd fallback');
|
||||
assert.ok(targets.includes(path.resolve('/ambient-msd-home/.msd')), 'ambient $MSD_HOME/.msd');
|
||||
assert.ok(targets.includes(path.resolve('/fallback-home/.msd')), 'HOME-derived .msd fallback');
|
||||
assert.ok(
|
||||
targets.some((t) => t === path.resolve('/fallback-home/.kimi/config.toml')),
|
||||
`HOME-derived kimi fallback missing from ${JSON.stringify(targets)}`,
|
||||
);
|
||||
});
|
||||
|
||||
test('detects a DELETED top-level GSD entry', () => {
|
||||
test('detects a DELETED top-level MSD entry', () => {
|
||||
const root = tmpRoot();
|
||||
try {
|
||||
// A fixed owned entry is recorded at BOTH ends whether or not it exists,
|
||||
// so a deletion reads {exists:true} -> {exists:false}. Before the union
|
||||
// walk that pair matched no branch at all and the run passed silently.
|
||||
fs.mkdirSync(path.join(root, 'gsd-core'), { recursive: true });
|
||||
fs.writeFileSync(path.join(root, 'gsd-core', 'x'), 'x');
|
||||
fs.mkdirSync(path.join(root, 'msd-core'), { recursive: true });
|
||||
fs.writeFileSync(path.join(root, 'msd-core', 'x'), 'x');
|
||||
const before = snapshotLiveConfig([root]);
|
||||
cleanup(path.join(root, 'gsd-core'));
|
||||
cleanup(path.join(root, 'msd-core'));
|
||||
|
||||
const violations = diffLiveConfig(before, snapshotLiveConfig([root]));
|
||||
const deleted = violations.filter((v) => v.kind === 'deleted');
|
||||
assert.strictEqual(deleted.length, 1, JSON.stringify(violations));
|
||||
assert.strictEqual(path.basename(deleted[0].path), 'gsd-core');
|
||||
assert.strictEqual(path.basename(deleted[0].path), 'msd-core');
|
||||
} finally {
|
||||
cleanup(root);
|
||||
}
|
||||
});
|
||||
|
||||
test('detects a DELETED gsd-prefixed child of a shared dir', () => {
|
||||
test('detects a DELETED msd-prefixed child of a shared dir', () => {
|
||||
const root = tmpRoot();
|
||||
try {
|
||||
// The shape a `pre.exists && !post.exists` branch cannot reach on its own:
|
||||
// prefixed children are DISCOVERED by readdir, so a deleted one is absent
|
||||
// from the `after` snapshot entirely and never enters an after-keyed loop.
|
||||
fs.mkdirSync(path.join(root, 'skills', 'gsd-dev-preferences'), { recursive: true });
|
||||
fs.writeFileSync(path.join(root, 'skills', 'gsd-dev-preferences', 'SKILL.md'), '# x');
|
||||
fs.mkdirSync(path.join(root, 'skills', 'msd-dev-preferences'), { recursive: true });
|
||||
fs.writeFileSync(path.join(root, 'skills', 'msd-dev-preferences', 'SKILL.md'), '# x');
|
||||
const before = snapshotLiveConfig([root]);
|
||||
cleanup(path.join(root, 'skills', 'gsd-dev-preferences'));
|
||||
cleanup(path.join(root, 'skills', 'msd-dev-preferences'));
|
||||
|
||||
const violations = diffLiveConfig(before, snapshotLiveConfig([root]));
|
||||
const deleted = violations.filter((v) => v.kind === 'deleted');
|
||||
assert.strictEqual(deleted.length, 1, JSON.stringify(violations));
|
||||
assert.strictEqual(path.basename(deleted[0].path), 'gsd-dev-preferences');
|
||||
assert.strictEqual(path.basename(deleted[0].path), 'msd-dev-preferences');
|
||||
} finally {
|
||||
cleanup(root);
|
||||
}
|
||||
@@ -466,28 +466,28 @@ describe('#2665: live-config hermeticity guard', () => {
|
||||
});
|
||||
|
||||
test('the report names the path and the remedy', () => {
|
||||
const out = formatViolations([{ path: '/live/.claude/gsd-core', kind: 'created' }]);
|
||||
const out = formatViolations([{ path: '/live/.claude/msd-core', kind: 'created' }]);
|
||||
assert.match(out, /HERMETICITY WARNING/);
|
||||
assert.match(out, /\/live\/\.claude\/gsd-core/);
|
||||
assert.match(out, /\/live\/\.claude\/msd-core/);
|
||||
assert.match(out, /scrubConfigLocationEnv/);
|
||||
assert.match(out, /GSD_SKIP_LIVE_CONFIG_GUARD/);
|
||||
assert.match(out, /GSD_STRICT_LIVE_CONFIG_GUARD/);
|
||||
assert.match(out, /MSD_SKIP_LIVE_CONFIG_GUARD/);
|
||||
assert.match(out, /MSD_STRICT_LIVE_CONFIG_GUARD/);
|
||||
});
|
||||
});
|
||||
|
||||
// ── Round 3: the write surfaces that are not runtime config ROOTS ───────────
|
||||
describe('#2665: guard watches non-root write surfaces', () => {
|
||||
test('resolveExtraWatchTargets covers $GSD_HOME/.gsd and kimi config.toml', () => {
|
||||
test('resolveExtraWatchTargets covers $MSD_HOME/.msd and kimi config.toml', () => {
|
||||
const home = tmpRoot();
|
||||
const share = tmpRoot();
|
||||
try {
|
||||
const targets = resolveExtraWatchTargets({
|
||||
env: { GSD_HOME: home, KIMI_SHARE_DIR: share },
|
||||
env: { MSD_HOME: home, KIMI_SHARE_DIR: share },
|
||||
os: { homedir: () => home },
|
||||
});
|
||||
assert.ok(
|
||||
targets.includes(path.resolve(path.join(home, '.gsd'))),
|
||||
`expected $GSD_HOME/.gsd in ${JSON.stringify(targets)}`,
|
||||
targets.includes(path.resolve(path.join(home, '.msd'))),
|
||||
`expected $MSD_HOME/.msd in ${JSON.stringify(targets)}`,
|
||||
);
|
||||
assert.ok(
|
||||
targets.some((t) => t === path.resolve(path.join(share, 'config.toml'))),
|
||||
@@ -503,10 +503,10 @@ describe('#2665: guard watches non-root write surfaces', () => {
|
||||
const {
|
||||
NON_REGISTRY_CONFIG_HOME_DESCRIPTORS,
|
||||
resolveConfigHomeFromDescriptor,
|
||||
} = require('../gsd-core/bin/lib/runtime-homes.cjs');
|
||||
} = require('../msd-core/bin/lib/runtime-homes.cjs');
|
||||
const home = tmpRoot();
|
||||
try {
|
||||
const env = { GSD_HOME: home };
|
||||
const env = { MSD_HOME: home };
|
||||
const targets = resolveExtraWatchTargets({ env, os: { homedir: () => home } });
|
||||
|
||||
// Every descriptor in the array must contribute a target. Calling one
|
||||
@@ -516,7 +516,7 @@ describe('#2665: guard watches non-root write surfaces', () => {
|
||||
//
|
||||
// SCOPE BOUNDARY (per round-2 Nit 7, and it bites here): this asserts one
|
||||
// target PER DESCRIPTOR and nothing about whether one target per descriptor
|
||||
// is ENOUGH. It is not — <root>/hooks/ is also GSD-written and unwatched
|
||||
// is ENOUGH. It is not — <root>/hooks/ is also MSD-written and unwatched
|
||||
// (named residual in resolveExtraWatchTargets). A test whose expectation is
|
||||
// derived from the same array it checks cannot see that class.
|
||||
for (const d of NON_REGISTRY_CONFIG_HOME_DESCRIPTORS) {
|
||||
@@ -531,7 +531,7 @@ describe('#2665: guard watches non-root write surfaces', () => {
|
||||
assert.strictEqual(
|
||||
targets.length,
|
||||
1 + NON_REGISTRY_CONFIG_HOME_DESCRIPTORS.length,
|
||||
'expected the GSD store root plus exactly one target per descriptor',
|
||||
'expected the MSD store root plus exactly one target per descriptor',
|
||||
);
|
||||
} finally {
|
||||
cleanup(home);
|
||||
@@ -551,7 +551,7 @@ describe('#2665: guard watches non-root write surfaces', () => {
|
||||
const home = tmpRoot();
|
||||
const codeHome = tmpRoot();
|
||||
try {
|
||||
const env = { GSD_HOME: home, KIMI_CODE_HOME: codeHome };
|
||||
const env = { MSD_HOME: home, KIMI_CODE_HOME: codeHome };
|
||||
const targets = resolveExtraWatchTargets({ env, os: { homedir: () => home } });
|
||||
assert.ok(
|
||||
targets.includes(path.resolve(path.join(codeHome, 'config.toml'))),
|
||||
@@ -563,22 +563,22 @@ describe('#2665: guard watches non-root write surfaces', () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('GSD_HOME falls back to homedir when unset', () => {
|
||||
test('MSD_HOME falls back to homedir when unset', () => {
|
||||
const home = tmpRoot();
|
||||
try {
|
||||
const targets = resolveExtraWatchTargets({ env: {}, os: { homedir: () => home } });
|
||||
assert.ok(targets.includes(path.resolve(path.join(home, '.gsd'))));
|
||||
assert.ok(targets.includes(path.resolve(path.join(home, '.msd'))));
|
||||
} finally {
|
||||
cleanup(home);
|
||||
}
|
||||
});
|
||||
|
||||
test('detects a consent/defaults write into $GSD_HOME/.gsd', () => {
|
||||
test('detects a consent/defaults write into $MSD_HOME/.msd', () => {
|
||||
const home = tmpRoot();
|
||||
try {
|
||||
const target = path.join(home, '.gsd');
|
||||
const target = path.join(home, '.msd');
|
||||
const before = snapshotLiveConfig([], [target]);
|
||||
// The Blocker-1 shape one family over: an ambient GSD_HOME sends real
|
||||
// The Blocker-1 shape one family over: an ambient MSD_HOME sends real
|
||||
// consent records and defaults.json into the developer's own store.
|
||||
fs.mkdirSync(target, { recursive: true });
|
||||
fs.writeFileSync(path.join(target, 'consent.json'), '{}');
|
||||
@@ -612,8 +612,8 @@ describe('#2665: guard watches non-root write surfaces', () => {
|
||||
// This is the pre-round-3 guard shape — roots only. It is what let a leak
|
||||
// on either variable pass through the PR's own safety net unreported.
|
||||
const before = snapshotLiveConfig([]);
|
||||
fs.mkdirSync(path.join(home, '.gsd'), { recursive: true });
|
||||
fs.writeFileSync(path.join(home, '.gsd', 'consent.json'), '{}');
|
||||
fs.mkdirSync(path.join(home, '.msd'), { recursive: true });
|
||||
fs.writeFileSync(path.join(home, '.msd', 'consent.json'), '{}');
|
||||
|
||||
assert.deepStrictEqual(diffLiveConfig(before, snapshotLiveConfig([])), []);
|
||||
} finally {
|
||||
@@ -624,10 +624,10 @@ describe('#2665: guard watches non-root write surfaces', () => {
|
||||
test('a whole-dir extra target does not watch unrelated siblings', () => {
|
||||
const home = tmpRoot();
|
||||
try {
|
||||
const target = path.join(home, '.gsd');
|
||||
const target = path.join(home, '.msd');
|
||||
fs.mkdirSync(target, { recursive: true });
|
||||
const before = snapshotLiveConfig([], [target]);
|
||||
// A sibling of .gsd is outside the watched target entirely.
|
||||
// A sibling of .msd is outside the watched target entirely.
|
||||
fs.writeFileSync(path.join(home, 'unrelated.json'), '{}');
|
||||
|
||||
assert.deepStrictEqual(diffLiveConfig(before, snapshotLiveConfig([], [target])), []);
|
||||
@@ -732,7 +732,7 @@ describe('#2665: scan-budget truncation', () => {
|
||||
});
|
||||
|
||||
test('a modified path outranks unverified (a real leak is never downgraded)', () => {
|
||||
const p = '/live/.claude/gsd-core';
|
||||
const p = '/live/.claude/msd-core';
|
||||
const violations = diffLiveConfig(
|
||||
{ [p]: { exists: true, newest: 1, truncated: true } },
|
||||
{ [p]: { exists: true, newest: 2, truncated: true } },
|
||||
@@ -780,7 +780,7 @@ describe('#2665: scan-budget truncation', () => {
|
||||
});
|
||||
|
||||
describe('#2665 round 4: CI wires the guard to strict mode', () => {
|
||||
// The reversion this guards: dropping GSD_STRICT_LIVE_CONFIG_GUARD from
|
||||
// The reversion this guards: dropping MSD_STRICT_LIVE_CONFIG_GUARD from
|
||||
// test.yml silently demotes the guard back to report-only, and a future
|
||||
// leak of exactly the class #2665 closes prints a warning and CI stays
|
||||
// green. Windows lanes are deliberately report-only until the documented
|
||||
@@ -792,7 +792,7 @@ describe('#2665 round 4: CI wires the guard to strict mode', () => {
|
||||
// The Docs Required gate gets satisfied by ANY docs/ file in the diff --
|
||||
// including a generated index -- so it cannot stand in for this.
|
||||
const doc = fs.readFileSync(path.join(__dirname, '..', 'docs', 'TESTING-SUITES.md'), 'utf8');
|
||||
for (const v of ['GSD_STRICT_LIVE_CONFIG_GUARD', 'GSD_SKIP_LIVE_CONFIG_GUARD']) {
|
||||
for (const v of ['MSD_STRICT_LIVE_CONFIG_GUARD', 'MSD_SKIP_LIVE_CONFIG_GUARD']) {
|
||||
assert.ok(doc.includes(v), `${v} must be documented in docs/TESTING-SUITES.md`);
|
||||
}
|
||||
});
|
||||
@@ -803,7 +803,7 @@ describe('#2665 round 4: CI wires the guard to strict mode', () => {
|
||||
// strict mode entirely while this test stayed green. A hand-list that certifies
|
||||
// its own completeness is the exact defect this PR exists to fix, reproduced in
|
||||
// the test that guards the fix.
|
||||
test('EVERY job that runs the suite wires GSD_STRICT_LIVE_CONFIG_GUARD', () => {
|
||||
test('EVERY job that runs the suite wires MSD_STRICT_LIVE_CONFIG_GUARD', () => {
|
||||
const yaml = require('js-yaml');
|
||||
const root = path.join(__dirname, '..');
|
||||
const wf = yaml.load(fs.readFileSync(path.join(root, '.github', 'workflows', 'test.yml'), 'utf8'));
|
||||
@@ -839,7 +839,7 @@ describe('#2665 round 4: CI wires the guard to strict mode', () => {
|
||||
const problems = [];
|
||||
for (const name of suiteJobs) {
|
||||
const job = wf.jobs[name];
|
||||
const v = String(job?.env?.GSD_STRICT_LIVE_CONFIG_GUARD ?? '');
|
||||
const v = String(job?.env?.MSD_STRICT_LIVE_CONFIG_GUARD ?? '');
|
||||
// Windows lanes stay report-only until the pre-existing USERPROFILE leak
|
||||
// class is swept (SEVERITY note in scripts/live-config-guard.cjs), so a
|
||||
// job whose matrix includes Windows carries the conditional; an
|
||||
|
||||
Reference in New Issue
Block a user