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:
@@ -4,10 +4,10 @@
|
||||
// Per CONTRIBUTING.md exception matrix.
|
||||
|
||||
/**
|
||||
* GSD Secure-Phase Tests
|
||||
* MSD Secure-Phase Tests
|
||||
*
|
||||
* Validates the security-first enforcement layer:
|
||||
* - gsd-security-auditor agent frontmatter and structure
|
||||
* - msd-security-auditor agent frontmatter and structure
|
||||
* - secure-phase command file
|
||||
* - secure-phase workflow file
|
||||
* - SECURITY.md template
|
||||
@@ -23,19 +23,19 @@ const path = require('path');
|
||||
|
||||
const REPO_ROOT = path.join(__dirname, '..');
|
||||
const AGENTS_DIR = path.join(REPO_ROOT, 'agents');
|
||||
const COMMANDS_DIR = path.join(REPO_ROOT, 'commands', 'gsd');
|
||||
const WORKFLOWS_DIR = path.join(REPO_ROOT, 'gsd-core', 'workflows');
|
||||
const TEMPLATES_DIR = path.join(REPO_ROOT, 'gsd-core', 'templates');
|
||||
const COMMANDS_DIR = path.join(REPO_ROOT, 'commands', 'msd');
|
||||
const WORKFLOWS_DIR = path.join(REPO_ROOT, 'msd-core', 'workflows');
|
||||
const TEMPLATES_DIR = path.join(REPO_ROOT, 'msd-core', 'templates');
|
||||
|
||||
// ─── 1. Agent frontmatter — gsd-security-auditor.md ─────────────────────────
|
||||
// ─── 1. Agent frontmatter — msd-security-auditor.md ─────────────────────────
|
||||
|
||||
describe('SECURE: gsd-security-auditor agent', () => {
|
||||
const agentPath = path.join(AGENTS_DIR, 'gsd-security-auditor.md');
|
||||
describe('SECURE: msd-security-auditor agent', () => {
|
||||
const agentPath = path.join(AGENTS_DIR, 'msd-security-auditor.md');
|
||||
|
||||
test('agent file exists', () => {
|
||||
assert.ok(
|
||||
fs.existsSync(agentPath),
|
||||
'gsd-security-auditor.md must exist in agents/'
|
||||
'msd-security-auditor.md must exist in agents/'
|
||||
);
|
||||
});
|
||||
|
||||
@@ -48,12 +48,12 @@ describe('SECURE: gsd-security-auditor agent', () => {
|
||||
assert.ok(frontmatter.includes('color:'), 'missing color:');
|
||||
});
|
||||
|
||||
test('name is gsd-security-auditor', () => {
|
||||
test('name is msd-security-auditor', () => {
|
||||
const content = fs.readFileSync(agentPath, 'utf-8');
|
||||
const frontmatter = content.split('---')[1] || '';
|
||||
assert.ok(
|
||||
frontmatter.includes('name: gsd-security-auditor'),
|
||||
'name must be gsd-security-auditor'
|
||||
frontmatter.includes('name: msd-security-auditor'),
|
||||
'name must be msd-security-auditor'
|
||||
);
|
||||
});
|
||||
|
||||
@@ -114,16 +114,16 @@ describe('SECURE: secure-phase command file', () => {
|
||||
test('command file exists', () => {
|
||||
assert.ok(
|
||||
fs.existsSync(cmdPath),
|
||||
'secure-phase.md must exist in commands/gsd/'
|
||||
'secure-phase.md must exist in commands/msd/'
|
||||
);
|
||||
});
|
||||
|
||||
test('has valid frontmatter with name gsd:secure-phase', () => {
|
||||
test('has valid frontmatter with name msd:secure-phase', () => {
|
||||
const content = fs.readFileSync(cmdPath, 'utf-8');
|
||||
const frontmatter = content.split('---')[1] || '';
|
||||
assert.ok(
|
||||
frontmatter.includes('name: gsd:secure-phase'),
|
||||
'name must be gsd:secure-phase'
|
||||
frontmatter.includes('name: msd:secure-phase'),
|
||||
'name must be msd:secure-phase'
|
||||
);
|
||||
});
|
||||
|
||||
@@ -161,15 +161,15 @@ describe('SECURE: secure-phase workflow file', () => {
|
||||
test('workflow file exists', () => {
|
||||
assert.ok(
|
||||
fs.existsSync(wfPath),
|
||||
'secure-phase.md must exist in gsd-core/workflows/'
|
||||
'secure-phase.md must exist in msd-core/workflows/'
|
||||
);
|
||||
});
|
||||
|
||||
test('contains gsd-security-auditor reference', () => {
|
||||
test('contains msd-security-auditor reference', () => {
|
||||
const content = fs.readFileSync(wfPath, 'utf-8');
|
||||
assert.ok(
|
||||
content.includes('gsd-security-auditor'),
|
||||
'must reference gsd-security-auditor agent'
|
||||
content.includes('msd-security-auditor'),
|
||||
'must reference msd-security-auditor agent'
|
||||
);
|
||||
});
|
||||
|
||||
@@ -226,7 +226,7 @@ describe('SECURE: SECURITY.md template', () => {
|
||||
test('template exists', () => {
|
||||
assert.ok(
|
||||
fs.existsSync(tplPath),
|
||||
'SECURITY.md must exist in gsd-core/templates/'
|
||||
'SECURITY.md must exist in msd-core/templates/'
|
||||
);
|
||||
});
|
||||
|
||||
@@ -308,7 +308,7 @@ describe('SECURE: config.json security defaults', () => {
|
||||
test('config template exists', () => {
|
||||
assert.ok(
|
||||
fs.existsSync(configPath),
|
||||
'config.json must exist in gsd-core/templates/'
|
||||
'config.json must exist in msd-core/templates/'
|
||||
);
|
||||
});
|
||||
|
||||
@@ -360,7 +360,7 @@ describe('SECURE: VALIDATION.md security columns', () => {
|
||||
test('VALIDATION.md template exists', () => {
|
||||
assert.ok(
|
||||
fs.existsSync(valPath),
|
||||
'VALIDATION.md must exist in gsd-core/templates/'
|
||||
'VALIDATION.md must exist in msd-core/templates/'
|
||||
);
|
||||
});
|
||||
|
||||
@@ -405,13 +405,13 @@ describe('SECURE: VALIDATION.md security columns', () => {
|
||||
// ─── 7. Per-threat severity gate (#1626) ────────────────────────────────────
|
||||
|
||||
describe('SECURE: per-threat severity gate (#1626)', () => {
|
||||
const plannerPath = path.join(AGENTS_DIR, 'gsd-planner.md');
|
||||
const auditorPath = path.join(AGENTS_DIR, 'gsd-security-auditor.md');
|
||||
const plannerPath = path.join(AGENTS_DIR, 'msd-planner.md');
|
||||
const auditorPath = path.join(AGENTS_DIR, 'msd-security-auditor.md');
|
||||
const tplPath = path.join(TEMPLATES_DIR, 'SECURITY.md');
|
||||
const configDocPath = path.join(REPO_ROOT, 'gsd-core', 'references', 'planning-config.md');
|
||||
const configDocPath = path.join(REPO_ROOT, 'msd-core', 'references', 'planning-config.md');
|
||||
|
||||
// ── planner: Severity column in threat register header ──────────────────
|
||||
test('gsd-planner.md threat_model register header has Severity column', () => {
|
||||
test('msd-planner.md threat_model register header has Severity column', () => {
|
||||
const content = fs.readFileSync(plannerPath, 'utf-8');
|
||||
assert.ok(
|
||||
content.includes('| Threat ID | Category | Component | Severity | Disposition | Mitigation Plan |'),
|
||||
@@ -419,7 +419,7 @@ describe('SECURE: per-threat severity gate (#1626)', () => {
|
||||
);
|
||||
});
|
||||
|
||||
test('gsd-planner.md security instruction assigns severity to each threat', () => {
|
||||
test('msd-planner.md security instruction assigns severity to each threat', () => {
|
||||
const content = fs.readFileSync(plannerPath, 'utf-8');
|
||||
assert.ok(
|
||||
content.includes('severity') && content.includes('critical|high|medium|low'),
|
||||
@@ -427,7 +427,7 @@ describe('SECURE: per-threat severity gate (#1626)', () => {
|
||||
);
|
||||
});
|
||||
|
||||
test('gsd-planner.md checklist has Severity item', () => {
|
||||
test('msd-planner.md checklist has Severity item', () => {
|
||||
const content = fs.readFileSync(plannerPath, 'utf-8');
|
||||
assert.ok(
|
||||
content.includes('Every threat has a Severity (critical|high|medium|low)'),
|
||||
@@ -436,7 +436,7 @@ describe('SECURE: per-threat severity gate (#1626)', () => {
|
||||
});
|
||||
|
||||
// ── auditor: block_on uses severity vocabulary ───────────────────────────
|
||||
test('gsd-security-auditor.md block_on domain is severity vocabulary', () => {
|
||||
test('msd-security-auditor.md block_on domain is severity vocabulary', () => {
|
||||
const content = fs.readFileSync(auditorPath, 'utf-8');
|
||||
assert.ok(
|
||||
content.includes('block_on') && content.includes('critical') && content.includes('none'),
|
||||
@@ -444,7 +444,7 @@ describe('SECURE: per-threat severity gate (#1626)', () => {
|
||||
);
|
||||
});
|
||||
|
||||
test('gsd-security-auditor.md defines severity ordering critical > high > medium > low', () => {
|
||||
test('msd-security-auditor.md defines severity ordering critical > high > medium > low', () => {
|
||||
const content = fs.readFileSync(auditorPath, 'utf-8');
|
||||
assert.ok(
|
||||
content.includes('critical > high > medium > low'),
|
||||
@@ -452,7 +452,7 @@ describe('SECURE: per-threat severity gate (#1626)', () => {
|
||||
);
|
||||
});
|
||||
|
||||
test('gsd-security-auditor.md threats_open counts only open threats at or above block_on', () => {
|
||||
test('msd-security-auditor.md threats_open counts only open threats at or above block_on', () => {
|
||||
const content = fs.readFileSync(auditorPath, 'utf-8');
|
||||
assert.ok(
|
||||
content.includes('threats_open') && content.includes('severity rank') && content.includes('block_on'),
|
||||
@@ -460,7 +460,7 @@ describe('SECURE: per-threat severity gate (#1626)', () => {
|
||||
);
|
||||
});
|
||||
|
||||
test('gsd-security-auditor.md documents non-blocking below-threshold opens', () => {
|
||||
test('msd-security-auditor.md documents non-blocking below-threshold opens', () => {
|
||||
const content = fs.readFileSync(auditorPath, 'utf-8');
|
||||
assert.ok(
|
||||
content.includes('non-blocking') && content.includes('below'),
|
||||
@@ -503,7 +503,7 @@ describe('SECURE: per-threat severity gate (#1626)', () => {
|
||||
});
|
||||
|
||||
// ── auditor: classification vocabulary is severity-conditioned (not all-open-blocks) ──
|
||||
test('gsd-security-auditor.md BLOCKER classification conditions blocking on severity threshold (no unconditional all-open-blocks language)', () => {
|
||||
test('msd-security-auditor.md BLOCKER classification conditions blocking on severity threshold (no unconditional all-open-blocks language)', () => {
|
||||
const content = fs.readFileSync(auditorPath, 'utf-8');
|
||||
// The reworded classification must include both the blocking condition (severity >= block_on)
|
||||
// AND the non-blocking category for below-threshold threats.
|
||||
@@ -530,7 +530,7 @@ describe('SECURE: per-threat severity gate (#1626)', () => {
|
||||
});
|
||||
|
||||
// ── auditor: fail-closed for missing/unranked severity (Finding 1) ─────────
|
||||
test('gsd-security-auditor.md states fail-closed rule for missing/unranked severity', () => {
|
||||
test('msd-security-auditor.md states fail-closed rule for missing/unranked severity', () => {
|
||||
const content = fs.readFileSync(auditorPath, 'utf-8');
|
||||
assert.ok(
|
||||
content.includes('Fail-closed') && content.includes('missing') && content.includes('critical'),
|
||||
@@ -583,7 +583,7 @@ describe('SECURE: per-threat severity gate (#1626)', () => {
|
||||
// ─── 8. Threat-model-anchored behaviour (structural) ────────────────────────
|
||||
|
||||
describe('SECURE: threat-model-anchored behaviour', () => {
|
||||
const agentPath = path.join(AGENTS_DIR, 'gsd-security-auditor.md');
|
||||
const agentPath = path.join(AGENTS_DIR, 'msd-security-auditor.md');
|
||||
const wfPath = path.join(WORKFLOWS_DIR, 'secure-phase.md');
|
||||
|
||||
test('agent does NOT contain "scan for vulnerabilities" (verifies, not scans)', () => {
|
||||
@@ -743,7 +743,7 @@ const path = require('node:path');
|
||||
|
||||
const ROOT = path.join(__dirname, '..');
|
||||
const src = fs.readFileSync(
|
||||
path.join(ROOT, 'gsd-core', 'workflows', 'secure-phase.md'),
|
||||
path.join(ROOT, 'msd-core', 'workflows', 'secure-phase.md'),
|
||||
'utf8',
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user