Files
msd-core/tests/planner-mvp-mode.test.cjs
Jakub Zych a9a7a328e6 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.
2026-10-06 01:47:40 +02:00

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'
);
});
});