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.
67 lines
2.6 KiB
JavaScript
67 lines
2.6 KiB
JavaScript
/**
|
|
* msd-planner agent — MVP-mode branch contract
|
|
* Verifies the agent definition contains the MVP-mode planning section,
|
|
* conditional reference loading, and Walking Skeleton handling.
|
|
*/
|
|
const { test, describe } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const AGENT = path.join(__dirname, '..', 'agents', 'msd-planner.md');
|
|
const REF_MVP = path.join(__dirname, '..', 'msd-core', 'references', 'planner-mvp-mode.md');
|
|
const REF_SKEL = path.join(__dirname, '..', 'msd-core', 'references', 'skeleton-template.md');
|
|
|
|
describe('msd-planner — MVP-mode branch', () => {
|
|
const content = fs.readFileSync(AGENT, 'utf-8');
|
|
|
|
test('agent defines an MVP Mode Detection section', () => {
|
|
assert.match(content, /MVP\s*Mode|MVP_MODE/i, 'must reference MVP mode');
|
|
assert.match(content, /vertical[\s-]?slice/i, 'must use vertical-slice terminology');
|
|
});
|
|
|
|
test('agent describes Walking Skeleton handling', () => {
|
|
assert.match(content, /Walking\s*Skeleton/i, 'must mention Walking Skeleton');
|
|
assert.match(content, /SKELETON\.md/, 'must mention SKELETON.md output');
|
|
});
|
|
|
|
test('agent references planner-mvp-mode.md conditionally', () => {
|
|
assert.match(
|
|
content,
|
|
/references\/planner-mvp-mode\.md/,
|
|
'must reference the MVP-mode rules file'
|
|
);
|
|
});
|
|
|
|
test('referenced files exist on disk', () => {
|
|
assert.ok(fs.existsSync(REF_MVP), `${REF_MVP} must exist`);
|
|
assert.ok(fs.existsSync(REF_SKEL), `${REF_SKEL} must exist`);
|
|
});
|
|
|
|
test('agent does not introduce horizontal/MVP mixing language', () => {
|
|
// Q1: all-or-nothing per phase. Reject phrasing that would imply mixing.
|
|
assert.doesNotMatch(
|
|
content,
|
|
/mix[a-z\s]*horizontal[a-z\s]*MVP|MVP[a-z\s]*and[a-z\s]*horizontal[a-z\s]*tasks/i,
|
|
'agent must enforce all-or-nothing per phase'
|
|
);
|
|
});
|
|
|
|
test('agent requires PLAN.md to start with user-story header in MVP mode', () => {
|
|
// The MVP Mode Detection section must instruct the planner to emit
|
|
// a "## Phase Goal" section with **As a** / **I want to** / **so that**
|
|
// bolded keywords as the first content under the phase header in PLAN.md.
|
|
assert.match(content, /Phase\s*Goal/i, 'must mention "Phase Goal" header');
|
|
assert.match(
|
|
content,
|
|
/\*\*As a\*\*[^\n]*\*\*I want to\*\*[^\n]*\*\*so that\*\*/i,
|
|
'must specify the bolded user-story format for PLAN.md emit'
|
|
);
|
|
assert.match(
|
|
content,
|
|
/user-story-template\.md/,
|
|
'must reference the user-story-template reference file'
|
|
);
|
|
});
|
|
});
|