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:
@@ -25,10 +25,10 @@ const {
|
||||
_readRawConfigKey,
|
||||
CANONICAL_POINTS_FALLBACK,
|
||||
CANONICAL_POINTS,
|
||||
} = require('../gsd-core/bin/lib/loop-resolver.cjs');
|
||||
} = require('../msd-core/bin/lib/loop-resolver.cjs');
|
||||
|
||||
// The real registry for integration tests
|
||||
const realRegistry = require('../gsd-core/bin/lib/capability-registry.cjs');
|
||||
const realRegistry = require('../msd-core/bin/lib/capability-registry.cjs');
|
||||
|
||||
// ─── Synthetic registry fixtures ─────────────────────────────────────────────
|
||||
|
||||
@@ -84,7 +84,7 @@ before(() => {
|
||||
|
||||
tmpUiDisabledConfigDir = fs.mkdtempSync(path.join(os.tmpdir(), 'loop-resolver-ui-disabled-'));
|
||||
fs.writeFileSync(
|
||||
path.join(tmpUiDisabledConfigDir, '.gsd-surface.json'),
|
||||
path.join(tmpUiDisabledConfigDir, '.msd-surface.json'),
|
||||
JSON.stringify({
|
||||
baseProfile: 'full',
|
||||
disabledClusters: ['ui'],
|
||||
@@ -501,7 +501,7 @@ describe('#3661: code-review capability.json + generated registry (matrix Sectio
|
||||
assert.strictEqual(hook.supportsReviewerLanes, true, 'Expected the real code-review active hook to carry supportsReviewerLanes: true');
|
||||
});
|
||||
|
||||
// F4-F7 (CLI-behavioral: gsd_run loop render-hooks / config-set through the real
|
||||
// F4-F7 (CLI-behavioral: msd_run loop render-hooks / config-set through the real
|
||||
// subprocess, against a temp git project) live in tests/code-review.test.cjs's
|
||||
// 'CR-CONFIG: config key registration' describe block, alongside the sibling
|
||||
// workflow.code_review / workflow.code_review_depth CLI round-trip tests.
|
||||
@@ -851,7 +851,7 @@ describe('renderLoopHooks', () => {
|
||||
steps: [{
|
||||
capId: 'research',
|
||||
point: 'plan:pre',
|
||||
ref: { agent: 'gsd-phase-researcher' },
|
||||
ref: { agent: 'msd-phase-researcher' },
|
||||
fragment: { inline: 'Research the phase before planning.' },
|
||||
produces: ['RESEARCH.md'],
|
||||
consumes: ['CONTEXT.md'],
|
||||
@@ -862,7 +862,7 @@ describe('renderLoopHooks', () => {
|
||||
assert.deepEqual(resolved.activeHooks[0].fragment, { inline: 'Research the phase before planning.' });
|
||||
|
||||
const rendered = renderLoopHooks(resolved);
|
||||
assert.match(rendered, /agent:gsd-phase-researcher/);
|
||||
assert.match(rendered, /agent:msd-phase-researcher/);
|
||||
assert.match(rendered, /Research the phase before planning\./);
|
||||
});
|
||||
|
||||
@@ -960,17 +960,17 @@ describe('renderLoopHooks', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// ─── 9. End-to-end cmdLoopRenderHooks (via gsd-tools subprocess) ─────────────
|
||||
// ─── 9. End-to-end cmdLoopRenderHooks (via msd-tools subprocess) ─────────────
|
||||
|
||||
const { runNode } = require('./helpers/process-seam.cjs');
|
||||
const { PROBE_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
|
||||
const ROOT = path.resolve(__dirname, '..');
|
||||
const GSD_TOOLS = path.join(ROOT, 'gsd-core', 'bin', 'gsd-tools.cjs');
|
||||
const MSD_TOOLS = path.join(ROOT, 'msd-core', 'bin', 'msd-tools.cjs');
|
||||
|
||||
describe('cmdLoopRenderHooks end-to-end (via gsd-tools)', () => {
|
||||
describe('cmdLoopRenderHooks end-to-end (via msd-tools)', () => {
|
||||
test('loop render-hooks plan:pre returns JSON envelope with ui-phase step active', () => {
|
||||
const result = runNode(
|
||||
[GSD_TOOLS, 'loop', 'render-hooks', 'plan:pre', '--cwd', tmpProjectDir],
|
||||
[MSD_TOOLS, 'loop', 'render-hooks', 'plan:pre', '--cwd', tmpProjectDir],
|
||||
{ cwd: ROOT, timeoutMs: PROBE_TIMEOUT_MS },
|
||||
);
|
||||
assert.strictEqual(result.exitCode, 0, 'Expected exit 0. stderr: ' + (result.stderr || ''));
|
||||
@@ -987,7 +987,7 @@ describe('cmdLoopRenderHooks end-to-end (via gsd-tools)', () => {
|
||||
// FIX 4: schema-default activation — no config.json in project → ui-phase step active by default
|
||||
test('loop render-hooks plan:pre with no config.json → ui-phase step active by schema default', () => {
|
||||
const result = runNode(
|
||||
[GSD_TOOLS, 'loop', 'render-hooks', 'plan:pre', '--cwd', tmpEmptyProjectDir],
|
||||
[MSD_TOOLS, 'loop', 'render-hooks', 'plan:pre', '--cwd', tmpEmptyProjectDir],
|
||||
{ cwd: ROOT, timeoutMs: PROBE_TIMEOUT_MS },
|
||||
);
|
||||
assert.strictEqual(result.exitCode, 0, 'Expected exit 0. stderr: ' + (result.stderr || ''));
|
||||
@@ -1003,7 +1003,7 @@ describe('cmdLoopRenderHooks end-to-end (via gsd-tools)', () => {
|
||||
test('loop render-hooks plan:pre with ui capability disabled in surface → ui hooks absent', () => {
|
||||
const result = runNode(
|
||||
[
|
||||
GSD_TOOLS,
|
||||
MSD_TOOLS,
|
||||
'loop',
|
||||
'render-hooks',
|
||||
'plan:pre',
|
||||
@@ -1027,7 +1027,7 @@ describe('cmdLoopRenderHooks end-to-end (via gsd-tools)', () => {
|
||||
// FIX 4: explicit false in config.json overrides schema default
|
||||
test('loop render-hooks plan:pre with ui_phase=false in config.json → ui-phase step absent', () => {
|
||||
const result = runNode(
|
||||
[GSD_TOOLS, 'loop', 'render-hooks', 'plan:pre', '--cwd', tmpFalseConfigProjectDir],
|
||||
[MSD_TOOLS, 'loop', 'render-hooks', 'plan:pre', '--cwd', tmpFalseConfigProjectDir],
|
||||
{ cwd: ROOT, timeoutMs: PROBE_TIMEOUT_MS },
|
||||
);
|
||||
assert.strictEqual(result.exitCode, 0, 'Expected exit 0. stderr: ' + (result.stderr || ''));
|
||||
@@ -1042,7 +1042,7 @@ describe('cmdLoopRenderHooks end-to-end (via gsd-tools)', () => {
|
||||
|
||||
test('loop render-hooks invalid-point exits non-zero', () => {
|
||||
const result = runNode(
|
||||
[GSD_TOOLS, 'loop', 'render-hooks', 'plan:mid', '--cwd', tmpProjectDir],
|
||||
[MSD_TOOLS, 'loop', 'render-hooks', 'plan:mid', '--cwd', tmpProjectDir],
|
||||
{ cwd: ROOT, timeoutMs: PROBE_TIMEOUT_MS },
|
||||
);
|
||||
assert.notStrictEqual(result.exitCode, 0, 'Expected non-zero exit for invalid point');
|
||||
@@ -1085,7 +1085,7 @@ describe('--active-cap flag (loop render-hooks)', () => {
|
||||
|
||||
test('--active-cap tdd with tdd_mode=true → stdout trimmed === "true", exit 0', () => {
|
||||
const result = runNode(
|
||||
[GSD_TOOLS, 'loop', 'render-hooks', 'execute:post', '--active-cap', 'tdd', '--cwd', tddOnDir],
|
||||
[MSD_TOOLS, 'loop', 'render-hooks', 'execute:post', '--active-cap', 'tdd', '--cwd', tddOnDir],
|
||||
{ cwd: ROOT, timeoutMs: PROBE_TIMEOUT_MS },
|
||||
);
|
||||
assert.strictEqual(result.exitCode, 0, 'Expected exit 0. stderr: ' + (result.stderr || ''));
|
||||
@@ -1094,7 +1094,7 @@ describe('--active-cap flag (loop render-hooks)', () => {
|
||||
|
||||
test('--active-cap tdd with tdd_mode=false → stdout trimmed === "false", exit 0', () => {
|
||||
const result = runNode(
|
||||
[GSD_TOOLS, 'loop', 'render-hooks', 'execute:post', '--active-cap', 'tdd', '--cwd', tddOffDir],
|
||||
[MSD_TOOLS, 'loop', 'render-hooks', 'execute:post', '--active-cap', 'tdd', '--cwd', tddOffDir],
|
||||
{ cwd: ROOT, timeoutMs: PROBE_TIMEOUT_MS },
|
||||
);
|
||||
assert.strictEqual(result.exitCode, 0, 'Expected exit 0. stderr: ' + (result.stderr || ''));
|
||||
@@ -1103,7 +1103,7 @@ describe('--active-cap flag (loop render-hooks)', () => {
|
||||
|
||||
test('--active-cap <nonexistent-cap> → stdout trimmed === "false", exit 0', () => {
|
||||
const result = runNode(
|
||||
[GSD_TOOLS, 'loop', 'render-hooks', 'execute:post', '--active-cap', 'no-such-capability-xyz', '--cwd', tddOffDir],
|
||||
[MSD_TOOLS, 'loop', 'render-hooks', 'execute:post', '--active-cap', 'no-such-capability-xyz', '--cwd', tddOffDir],
|
||||
{ cwd: ROOT, timeoutMs: PROBE_TIMEOUT_MS },
|
||||
);
|
||||
assert.strictEqual(result.exitCode, 0, 'Expected exit 0 for unknown capId. stderr: ' + (result.stderr || ''));
|
||||
@@ -1112,7 +1112,7 @@ describe('--active-cap flag (loop render-hooks)', () => {
|
||||
|
||||
test('--active-cap with no value → non-zero exit and error message', () => {
|
||||
const result = runNode(
|
||||
[GSD_TOOLS, 'loop', 'render-hooks', 'execute:post', '--active-cap', '--cwd', tddOffDir],
|
||||
[MSD_TOOLS, 'loop', 'render-hooks', 'execute:post', '--active-cap', '--cwd', tddOffDir],
|
||||
{ cwd: ROOT, timeoutMs: PROBE_TIMEOUT_MS },
|
||||
);
|
||||
assert.notStrictEqual(result.exitCode, 0, 'Expected non-zero exit when --active-cap has no value');
|
||||
@@ -1122,7 +1122,7 @@ describe('--active-cap flag (loop render-hooks)', () => {
|
||||
test('--active-cap output is exactly "true" or "false" (no JSON envelope, clean for shell capture)', () => {
|
||||
// The entire stdout must be just "true" or "false" + newline — no envelope object
|
||||
const result = runNode(
|
||||
[GSD_TOOLS, 'loop', 'render-hooks', 'execute:post', '--active-cap', 'tdd', '--cwd', tddOnDir],
|
||||
[MSD_TOOLS, 'loop', 'render-hooks', 'execute:post', '--active-cap', 'tdd', '--cwd', tddOnDir],
|
||||
{ cwd: ROOT, timeoutMs: PROBE_TIMEOUT_MS },
|
||||
);
|
||||
assert.strictEqual(result.exitCode, 0, 'Expected exit 0. stderr: ' + (result.stderr || ''));
|
||||
@@ -1163,7 +1163,7 @@ describe('Phase 4 regression: capabilityStatesById gates on active (not enabled)
|
||||
// With NEW `state.active === true`, active=false → hook NOT rendered (CORRECT).
|
||||
const registry = makeRegistry({
|
||||
point: 'plan:pre',
|
||||
steps: [{ capId: 'test-cap', ref: { skill: 'gsd-test-skill' } }],
|
||||
steps: [{ capId: 'test-cap', ref: { skill: 'msd-test-skill' } }],
|
||||
// No `when` → unconditional hook (no per-hook config gate to fall back on)
|
||||
});
|
||||
|
||||
@@ -1194,7 +1194,7 @@ describe('Phase 4 regression: capabilityStatesById gates on active (not enabled)
|
||||
// This test must PASS against BOTH old and new code (it's the unbroken branch).
|
||||
const registry = makeRegistry({
|
||||
point: 'plan:pre',
|
||||
steps: [{ capId: 'test-cap', ref: { skill: 'gsd-test-skill' } }],
|
||||
steps: [{ capId: 'test-cap', ref: { skill: 'msd-test-skill' } }],
|
||||
});
|
||||
|
||||
const capabilityStatesById = new Map([
|
||||
@@ -1222,16 +1222,16 @@ describe('Phase 4 regression: capabilityStatesById gates on active (not enabled)
|
||||
describe('ADR-1244 D2: load-failed capability gates fail OPEN with a loud warning (#2009)', () => {
|
||||
// Decision (#2009): a capability that fails to LOAD must not block the loop.
|
||||
// cmdLoopRenderHooks injects NO gate (the loop proceeds — fail open) and emits a
|
||||
// loud warning naming the load reason and the exact `gsd capability remove <id>`
|
||||
// loud warning naming the load reason and the exact `msd capability remove <id>`
|
||||
// remediation, both to STDERR (the channel host workflows actually surface) and
|
||||
// in the envelope's `warnings` array. Previously it injected a blocking=true,
|
||||
// onError=halt gate that halted every declared point project-wide.
|
||||
|
||||
// Helper: write an overlay cap with an incompatible engines.gsd (→ skipped at load)
|
||||
// Helper: write an overlay cap with an incompatible engines.msd (→ skipped at load)
|
||||
// that declares gate(s) at the given point(s). `capId` may be an invalid id to
|
||||
// exercise the sanitization path.
|
||||
function writeSkippedGateCap(overlayHome, capId, gatePoints) {
|
||||
const capDir = path.join(overlayHome, '.gsd', 'capabilities', capId);
|
||||
const capDir = path.join(overlayHome, '.msd', 'capabilities', capId);
|
||||
fs.mkdirSync(capDir, { recursive: true });
|
||||
const capManifest = {
|
||||
id: capId,
|
||||
@@ -1241,7 +1241,7 @@ describe('ADR-1244 D2: load-failed capability gates fail OPEN with a loud warnin
|
||||
description: 'ADR-1244 D2 fail-open wiring test',
|
||||
tier: 'standard',
|
||||
requires: [],
|
||||
engines: { gsd: '>=99.0.0' }, // intentionally incompatible → always skipped at load
|
||||
engines: { msd: '>=99.0.0' }, // intentionally incompatible → always skipped at load
|
||||
runtimeCompat: { supported: ['*'], unsupported: [] },
|
||||
skills: [], agents: [], hooks: [], config: {}, steps: [], contributions: [],
|
||||
gates: gatePoints.map((point) => ({ point, check: { query: 'always-pass' }, blocking: true, onError: 'halt' })),
|
||||
@@ -1251,8 +1251,8 @@ describe('ADR-1244 D2: load-failed capability gates fail OPEN with a loud warnin
|
||||
|
||||
function renderHooks(overlayHome, point, extraArgs = []) {
|
||||
const result = runNode(
|
||||
[GSD_TOOLS, 'loop', 'render-hooks', point, '--cwd', overlayHome, ...extraArgs],
|
||||
{ cwd: ROOT, timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, GSD_HOME: overlayHome } },
|
||||
[MSD_TOOLS, 'loop', 'render-hooks', point, '--cwd', overlayHome, ...extraArgs],
|
||||
{ cwd: ROOT, timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, MSD_HOME: overlayHome } },
|
||||
);
|
||||
assert.strictEqual(result.exitCode, 0, `Expected exit 0 at ${point}. stderr: ` + (result.stderr || ''));
|
||||
return result;
|
||||
@@ -1291,14 +1291,14 @@ describe('ADR-1244 D2: load-failed capability gates fail OPEN with a loud warnin
|
||||
assert.ok(warnEnv, 'envelope.warnings must name the load-failed cap. Got: ' + JSON.stringify(envelope.warnings));
|
||||
// AC1: ...carrying the exact remediation, and making clear the gate is not enforced.
|
||||
assert.ok(
|
||||
warnEnv.includes(`gsd capability remove ${capId}`),
|
||||
'warning must include the `gsd capability remove <id>` remediation. Got: ' + warnEnv,
|
||||
warnEnv.includes(`msd capability remove ${capId}`),
|
||||
'warning must include the `msd capability remove <id>` remediation. Got: ' + warnEnv,
|
||||
);
|
||||
assert.match(warnEnv, /skipped|not enforced|failing open/i, 'warning must say the gate is not enforced. Got: ' + warnEnv);
|
||||
|
||||
// ...and ALSO to stderr (the channel host workflows actually see).
|
||||
assert.ok(
|
||||
result.stderr.includes(`gsd capability remove ${capId}`),
|
||||
result.stderr.includes(`msd capability remove ${capId}`),
|
||||
'stderr must carry the loud fail-open warning with remediation. Got: ' + result.stderr,
|
||||
);
|
||||
});
|
||||
@@ -1318,7 +1318,7 @@ describe('ADR-1244 D2: load-failed capability gates fail OPEN with a loud warnin
|
||||
injected, undefined,
|
||||
`${point} must NOT inject any hook for a load-failed cap (fail open). Got: ` + JSON.stringify(envelope.activeHooks),
|
||||
);
|
||||
const warn = (envelope.warnings || []).find((w) => w.includes(`gsd capability remove ${capId}`));
|
||||
const warn = (envelope.warnings || []).find((w) => w.includes(`msd capability remove ${capId}`));
|
||||
assert.ok(warn, `${point} must surface a fail-open warning with remediation. Got: ` + JSON.stringify(envelope.warnings));
|
||||
}
|
||||
});
|
||||
@@ -1329,7 +1329,7 @@ describe('ADR-1244 D2: load-failed capability gates fail OPEN with a loud warnin
|
||||
|
||||
// A directory name that is a valid POSIX filename but NOT a valid capability
|
||||
// id, and contains a shell metacharacter. It must never appear inside a
|
||||
// runnable `gsd capability remove <id>` command in the surfaced warning.
|
||||
// runnable `msd capability remove <id>` command in the surfaced warning.
|
||||
const evilId = 'Bad;Cap';
|
||||
writeSkippedGateCap(overlayHome, evilId, ['ship:pre']);
|
||||
|
||||
@@ -1339,7 +1339,7 @@ describe('ADR-1244 D2: load-failed capability gates fail OPEN with a loud warnin
|
||||
const combined = (envelope.warnings || []).join('\n') + '\n' + result.stderr;
|
||||
// The raw metacharacter id must not be embedded in a runnable remove command.
|
||||
assert.ok(
|
||||
!combined.includes(`gsd capability remove ${evilId}`),
|
||||
!combined.includes(`msd capability remove ${evilId}`),
|
||||
'invalid capability id must NOT be placed in a runnable remove command. Got: ' + combined,
|
||||
);
|
||||
// A warning is still surfaced (fail-open is loud), using the withheld-id form.
|
||||
|
||||
Reference in New Issue
Block a user