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:
@@ -3,7 +3,7 @@
|
||||
* audit-command-cutover.test.cjs — ADR-959 phase 4d-impl-3 equivalence tests.
|
||||
*
|
||||
* Verifies that `audit-uat` and `audit-open`, after cutover from the hardcoded
|
||||
* `case 'audit-uat':` and `case 'audit-open':` arms in gsd-tools.cjs to the
|
||||
* `case 'audit-uat':` and `case 'audit-open':` arms in msd-tools.cjs to the
|
||||
* capability registry dispatch path (default → dispatchCapabilityCommand →
|
||||
* audit-command-router.cjs → routeAuditUat | routeAuditOpen), behave
|
||||
* identically to the old inline cases.
|
||||
@@ -19,11 +19,11 @@
|
||||
const { describe, test, beforeEach, afterEach } = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
|
||||
const { runGsdTools, createTempProject, cleanup } = require('./helpers.cjs');
|
||||
const { runMsdTools, createTempProject, cleanup } = require('./helpers.cjs');
|
||||
|
||||
const registry = require('../gsd-core/bin/lib/capability-registry.cjs');
|
||||
const { routeAuditUat, routeAuditOpen } = require('../gsd-core/bin/lib/audit-command-router.cjs');
|
||||
const { scanFencedBlocks } = require('../gsd-core/bin/lib/markdown-sectionizer.cjs');
|
||||
const registry = require('../msd-core/bin/lib/capability-registry.cjs');
|
||||
const { routeAuditUat, routeAuditOpen } = require('../msd-core/bin/lib/audit-command-router.cjs');
|
||||
const { scanFencedBlocks } = require('../msd-core/bin/lib/markdown-sectionizer.cjs');
|
||||
|
||||
// ─── helpers ─────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -147,7 +147,7 @@ describe('audit cutover: dispatch path (default-case → capability registry)',
|
||||
let tmpDir;
|
||||
|
||||
beforeEach(() => {
|
||||
tmpDir = createTempProject('gsd-audit-cutover-');
|
||||
tmpDir = createTempProject('msd-audit-cutover-');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -155,7 +155,7 @@ describe('audit cutover: dispatch path (default-case → capability registry)',
|
||||
});
|
||||
|
||||
test('audit-uat dispatches via capability registry (no "Unknown command" error)', () => {
|
||||
const result = runGsdTools(['audit-uat'], tmpDir);
|
||||
const result = runMsdTools(['audit-uat'], tmpDir);
|
||||
// audit-uat with a minimal project may succeed or fail on file-not-found;
|
||||
// the key assertion is it never emits "Unknown command: audit-uat"
|
||||
const isUnknownCmd = (result.error || '').includes('Unknown command: audit-uat');
|
||||
@@ -166,7 +166,7 @@ describe('audit cutover: dispatch path (default-case → capability registry)',
|
||||
});
|
||||
|
||||
test('audit-open dispatches via capability registry (no "Unknown command" error)', () => {
|
||||
const result = runGsdTools(['audit-open'], tmpDir);
|
||||
const result = runMsdTools(['audit-open'], tmpDir);
|
||||
const isUnknownCmd = (result.error || '').includes('Unknown command: audit-open');
|
||||
assert.strictEqual(isUnknownCmd, false,
|
||||
`Must not emit "Unknown command: audit-open". stderr: ${result.error}`);
|
||||
@@ -175,7 +175,7 @@ describe('audit cutover: dispatch path (default-case → capability registry)',
|
||||
});
|
||||
|
||||
test('audit-open --json dispatches via capability registry', () => {
|
||||
const result = runGsdTools(['audit-open', '--json'], tmpDir);
|
||||
const result = runMsdTools(['audit-open', '--json'], tmpDir);
|
||||
const isUnknownCmd = (result.error || '').includes('Unknown command: audit-open');
|
||||
assert.strictEqual(isUnknownCmd, false,
|
||||
`Must not emit "Unknown command: audit-open" with --json. stderr: ${result.error}`);
|
||||
@@ -195,7 +195,7 @@ describe('audit cutover: output shape equivalence', () => {
|
||||
let tmpDir;
|
||||
|
||||
beforeEach(() => {
|
||||
tmpDir = createTempProject('gsd-audit-behavior-');
|
||||
tmpDir = createTempProject('msd-audit-behavior-');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -203,7 +203,7 @@ describe('audit cutover: output shape equivalence', () => {
|
||||
});
|
||||
|
||||
test('audit-open (text) succeeds and produces non-empty output', () => {
|
||||
const result = runGsdTools(['audit-open'], tmpDir);
|
||||
const result = runMsdTools(['audit-open'], tmpDir);
|
||||
assert.ok(result.success,
|
||||
`audit-open must succeed. stderr: ${result.error}`);
|
||||
assert.ok(result.output && result.output.length > 0,
|
||||
@@ -216,7 +216,7 @@ describe('audit cutover: output shape equivalence', () => {
|
||||
});
|
||||
|
||||
test('audit-open --json produces valid JSON with expected shape', () => {
|
||||
const result = runGsdTools(['audit-open', '--json'], tmpDir);
|
||||
const result = runMsdTools(['audit-open', '--json'], tmpDir);
|
||||
assert.ok(result.success,
|
||||
`audit-open --json must succeed. stderr: ${result.error}`);
|
||||
let parsed;
|
||||
@@ -234,7 +234,7 @@ describe('audit cutover: output shape equivalence', () => {
|
||||
});
|
||||
|
||||
test('audit-open (text) report title present as standalone line', () => {
|
||||
const result = runGsdTools(['audit-open'], tmpDir);
|
||||
const result = runMsdTools(['audit-open'], tmpDir);
|
||||
assert.ok(result.success,
|
||||
`audit-open must succeed. stderr: ${result.error}`);
|
||||
const lines = result.output.split('\n').map(l => l.trim()).filter(Boolean);
|
||||
@@ -245,7 +245,7 @@ describe('audit cutover: output shape equivalence', () => {
|
||||
});
|
||||
|
||||
test('audit-uat succeeds and produces non-empty stdout', () => {
|
||||
const result = runGsdTools(['audit-uat'], tmpDir);
|
||||
const result = runMsdTools(['audit-uat'], tmpDir);
|
||||
assert.ok(result.success,
|
||||
`audit-uat must succeed. stderr: ${result.error}`);
|
||||
assert.ok(result.output && result.output.length > 0,
|
||||
@@ -253,44 +253,44 @@ describe('audit cutover: output shape equivalence', () => {
|
||||
});
|
||||
|
||||
test('audit-uat --raw flag passes through (does not break dispatch)', () => {
|
||||
const result = runGsdTools(['audit-uat', '--raw'], tmpDir);
|
||||
// --raw is a gsd-tools global flag; it modifies output encoding but
|
||||
const result = runMsdTools(['audit-uat', '--raw'], tmpDir);
|
||||
// --raw is a msd-tools global flag; it modifies output encoding but
|
||||
// the command must still succeed and produce output
|
||||
assert.ok(result.success,
|
||||
`audit-uat --raw must succeed. stderr: ${result.error}`);
|
||||
});
|
||||
});
|
||||
|
||||
// ─── 4. JSON-ERRORS — GSD_JSON_ERRORS mode passes through cleanly ────────────
|
||||
// ─── 4. JSON-ERRORS — MSD_JSON_ERRORS mode passes through cleanly ────────────
|
||||
|
||||
describe('audit cutover: GSD_JSON_ERRORS mode (both commands succeed without structured error)', () => {
|
||||
describe('audit cutover: MSD_JSON_ERRORS mode (both commands succeed without structured error)', () => {
|
||||
let tmpDir;
|
||||
|
||||
beforeEach(() => {
|
||||
tmpDir = createTempProject('gsd-audit-jsonerr-');
|
||||
tmpDir = createTempProject('msd-audit-jsonerr-');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cleanup(tmpDir);
|
||||
});
|
||||
|
||||
test('audit-open --json with GSD_JSON_ERRORS=1 succeeds (no spurious error payload)', () => {
|
||||
test('audit-open --json with MSD_JSON_ERRORS=1 succeeds (no spurious error payload)', () => {
|
||||
// Successful commands must not emit JSON error payloads; verify exit 0.
|
||||
const result = runGsdTools(['audit-open', '--json'], tmpDir, { GSD_JSON_ERRORS: '1' });
|
||||
const result = runMsdTools(['audit-open', '--json'], tmpDir, { MSD_JSON_ERRORS: '1' });
|
||||
assert.ok(result.success,
|
||||
`audit-open --json must succeed even with GSD_JSON_ERRORS=1; stderr: ${result.error}`);
|
||||
`audit-open --json must succeed even with MSD_JSON_ERRORS=1; stderr: ${result.error}`);
|
||||
});
|
||||
|
||||
test('audit-open text with GSD_JSON_ERRORS=1 succeeds (no spurious error payload)', () => {
|
||||
const result = runGsdTools(['audit-open'], tmpDir, { GSD_JSON_ERRORS: '1' });
|
||||
test('audit-open text with MSD_JSON_ERRORS=1 succeeds (no spurious error payload)', () => {
|
||||
const result = runMsdTools(['audit-open'], tmpDir, { MSD_JSON_ERRORS: '1' });
|
||||
assert.ok(result.success,
|
||||
`audit-open text mode must succeed even with GSD_JSON_ERRORS=1; stderr: ${result.error}`);
|
||||
`audit-open text mode must succeed even with MSD_JSON_ERRORS=1; stderr: ${result.error}`);
|
||||
});
|
||||
|
||||
test('audit-uat with GSD_JSON_ERRORS=1 succeeds (no spurious error payload)', () => {
|
||||
const result = runGsdTools(['audit-uat'], tmpDir, { GSD_JSON_ERRORS: '1' });
|
||||
test('audit-uat with MSD_JSON_ERRORS=1 succeeds (no spurious error payload)', () => {
|
||||
const result = runMsdTools(['audit-uat'], tmpDir, { MSD_JSON_ERRORS: '1' });
|
||||
assert.ok(result.success,
|
||||
`audit-uat must succeed even with GSD_JSON_ERRORS=1; stderr: ${result.error}`);
|
||||
`audit-uat must succeed even with MSD_JSON_ERRORS=1; stderr: ${result.error}`);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -393,7 +393,7 @@ describe('audit cutover: registry entries correct', () => {
|
||||
/**
|
||||
* Regression test for #2659.
|
||||
*
|
||||
* The `audit-open` dispatch case in bin/gsd-tools.cjs previously called bare
|
||||
* The `audit-open` dispatch case in bin/msd-tools.cjs previously called bare
|
||||
* `output(...)` on both the --json and text branches. `output` is never in
|
||||
* local scope — the entire core module is imported as `const core`, so every
|
||||
* other case uses `core.output(...)`. The bare calls therefore crashed with
|
||||
@@ -407,13 +407,13 @@ describe('audit cutover: registry entries correct', () => {
|
||||
const { test, describe, beforeEach, afterEach } = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
|
||||
const { runGsdTools, createTempProject, cleanup } = require('./helpers.cjs');
|
||||
const { runMsdTools, createTempProject, cleanup } = require('./helpers.cjs');
|
||||
|
||||
describe('audit-open — does not crash with ReferenceError (#2659)', () => {
|
||||
let tmpDir;
|
||||
|
||||
beforeEach(() => {
|
||||
tmpDir = createTempProject('gsd-bug-2659-');
|
||||
tmpDir = createTempProject('msd-bug-2659-');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -421,7 +421,7 @@ describe('audit-open — does not crash with ReferenceError (#2659)', () => {
|
||||
});
|
||||
|
||||
test('audit-open (text output) succeeds and produces stdout', () => {
|
||||
const result = runGsdTools('audit-open', tmpDir);
|
||||
const result = runMsdTools('audit-open', tmpDir);
|
||||
assert.ok(
|
||||
result.success,
|
||||
`audit-open must not crash. stderr: ${result.error}`
|
||||
@@ -437,7 +437,7 @@ describe('audit-open — does not crash with ReferenceError (#2659)', () => {
|
||||
});
|
||||
|
||||
test('audit-open --json succeeds and produces stdout', () => {
|
||||
const result = runGsdTools(['audit-open', '--json'], tmpDir);
|
||||
const result = runMsdTools(['audit-open', '--json'], tmpDir);
|
||||
assert.ok(
|
||||
result.success,
|
||||
`audit-open --json must not crash. stderr: ${result.error}`
|
||||
@@ -476,7 +476,7 @@ describe('audit-open — does not crash with ReferenceError (#2659)', () => {
|
||||
/**
|
||||
* Regression test for #2911.
|
||||
*
|
||||
* Two bugs in the `audit-open` dispatch case in bin/gsd-tools.cjs:
|
||||
* Two bugs in the `audit-open` dispatch case in bin/msd-tools.cjs:
|
||||
*
|
||||
* 1. Bare `output(...)` calls (only `core.output` is in scope) → ReferenceError.
|
||||
* 2. Even after switching to `core.output(formatted, raw)`, the human-readable
|
||||
@@ -502,7 +502,7 @@ const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const { runGsdTools, createTempProject, cleanup } = require('./helpers.cjs');
|
||||
const { runMsdTools, createTempProject, cleanup } = require('./helpers.cjs');
|
||||
|
||||
// ─── #3458 fixtures: phase-scoped scanners must also see archived phases ─────
|
||||
//
|
||||
@@ -625,7 +625,7 @@ describe('audit-open — output shape (#2911)', () => {
|
||||
let tmpDir;
|
||||
|
||||
beforeEach(() => {
|
||||
tmpDir = createTempProject('gsd-bug-2911-');
|
||||
tmpDir = createTempProject('msd-bug-2911-');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -633,7 +633,7 @@ describe('audit-open — output shape (#2911)', () => {
|
||||
});
|
||||
|
||||
test('text mode emits the formatted report as raw text (not JSON-encoded)', () => {
|
||||
const result = runGsdTools('audit-open', tmpDir);
|
||||
const result = runMsdTools('audit-open', tmpDir);
|
||||
assert.ok(
|
||||
result.success,
|
||||
`audit-open must not crash. stderr: ${result.error}`
|
||||
@@ -666,7 +666,7 @@ describe('audit-open — output shape (#2911)', () => {
|
||||
});
|
||||
|
||||
test('--json mode emits parseable JSON matching auditOpenArtifacts shape', () => {
|
||||
const result = runGsdTools(['audit-open', '--json'], tmpDir);
|
||||
const result = runMsdTools(['audit-open', '--json'], tmpDir);
|
||||
assert.ok(
|
||||
result.success,
|
||||
`audit-open --json must not crash. stderr: ${result.error}`
|
||||
@@ -681,7 +681,7 @@ describe('audit-open — output shape (#2911)', () => {
|
||||
assert.equal(typeof parsed, 'object', 'parsed payload must be an object');
|
||||
assert.ok(parsed !== null, 'parsed payload must not be null');
|
||||
|
||||
// Shape contract from auditOpenArtifacts() in gsd-core/bin/lib/audit.cjs.
|
||||
// Shape contract from auditOpenArtifacts() in msd-core/bin/lib/audit.cjs.
|
||||
assert.equal(typeof parsed.scanned_at, 'string', 'must include scanned_at ISO timestamp');
|
||||
assert.equal(typeof parsed.has_open_items, 'boolean', 'must include has_open_items boolean');
|
||||
assert.equal(typeof parsed.counts, 'object', 'must include counts object');
|
||||
@@ -730,7 +730,7 @@ describe('audit-open — output shape (#2911)', () => {
|
||||
const archivedPhaseDir = path.join(tmpDir, '.planning', 'milestones', 'v1.0-phases', '01-alpha');
|
||||
writePhaseArtifacts(archivedPhaseDir, '01', UNRESOLVED_ARTIFACTS);
|
||||
|
||||
const result = runGsdTools(['audit-open', '--json'], tmpDir);
|
||||
const result = runMsdTools(['audit-open', '--json'], tmpDir);
|
||||
assert.ok(result.success, `audit-open --json must not crash. stderr: ${result.error}`);
|
||||
const parsed = JSON.parse(result.output);
|
||||
|
||||
@@ -748,7 +748,7 @@ describe('audit-open — output shape (#2911)', () => {
|
||||
const archivedPhaseDir = path.join(tmpDir, '.planning', 'milestones', 'v1.0-phases', '02-beta');
|
||||
writePhaseArtifacts(archivedPhaseDir, '02', UNRESOLVED_ARTIFACTS);
|
||||
|
||||
const result = runGsdTools(['audit-open', '--json'], tmpDir);
|
||||
const result = runMsdTools(['audit-open', '--json'], tmpDir);
|
||||
assert.ok(result.success, `audit-open --json must not crash. stderr: ${result.error}`);
|
||||
const parsed = JSON.parse(result.output);
|
||||
|
||||
@@ -763,7 +763,7 @@ describe('audit-open — output shape (#2911)', () => {
|
||||
const activePhaseDir = path.join(tmpDir, '.planning', 'phases', '01-alpha');
|
||||
writePhaseArtifacts(activePhaseDir, '01', UNRESOLVED_ARTIFACTS);
|
||||
|
||||
const result = runGsdTools(['audit-open', '--json'], tmpDir);
|
||||
const result = runMsdTools(['audit-open', '--json'], tmpDir);
|
||||
assert.ok(result.success, `audit-open --json must not crash. stderr: ${result.error}`);
|
||||
const parsed = JSON.parse(result.output);
|
||||
|
||||
@@ -781,7 +781,7 @@ describe('audit-open — output shape (#2911)', () => {
|
||||
const archivedPhaseDir = path.join(tmpDir, '.planning', 'milestones', 'v1.0-phases', '01-alpha');
|
||||
writePhaseArtifacts(archivedPhaseDir, '01', RESOLVED_ARTIFACTS);
|
||||
|
||||
const result = runGsdTools(['audit-open', '--json'], tmpDir);
|
||||
const result = runMsdTools(['audit-open', '--json'], tmpDir);
|
||||
assert.ok(result.success, `audit-open --json must not crash. stderr: ${result.error}`);
|
||||
const parsed = JSON.parse(result.output);
|
||||
|
||||
@@ -834,7 +834,7 @@ describe('audit-open — output shape (#2911)', () => {
|
||||
if (!tryMkdirForgedName(t, forgedPhaseDir)) return;
|
||||
fs.writeFileSync(path.join(forgedPhaseDir, 'deferred-items.md'), DEFERRED_ITEM_UNRESOLVED);
|
||||
|
||||
const result = runGsdTools('audit-open', tmpDir);
|
||||
const result = runMsdTools('audit-open', tmpDir);
|
||||
assert.ok(result.success, `audit-open must not crash. stderr: ${result.error}`);
|
||||
|
||||
const lines = result.output.split('\n').map(l => l.trim());
|
||||
@@ -849,7 +849,7 @@ describe('audit-open — output shape (#2911)', () => {
|
||||
if (!tryMkdirForgedName(t, forgedPhaseDir)) return;
|
||||
fs.writeFileSync(path.join(forgedPhaseDir, 'deferred-items.md'), DEFERRED_ITEM_UNRESOLVED);
|
||||
|
||||
const result = runGsdTools('audit-open', tmpDir);
|
||||
const result = runMsdTools('audit-open', tmpDir);
|
||||
assert.ok(result.success, `audit-open must not crash. stderr: ${result.error}`);
|
||||
|
||||
assert.ok(
|
||||
@@ -867,7 +867,7 @@ describe('audit-open — output shape (#2911)', () => {
|
||||
const archivedPhaseDir = path.join(tmpDir, '.planning', 'milestones', 'v1.0-phases', '02-beta');
|
||||
writePhaseArtifacts(archivedPhaseDir, '02', UNRESOLVED_ARTIFACTS);
|
||||
|
||||
const result = runGsdTools(['audit-open', '--json'], tmpDir);
|
||||
const result = runMsdTools(['audit-open', '--json'], tmpDir);
|
||||
assert.ok(result.success, `audit-open --json must not crash. stderr: ${result.error}`);
|
||||
const parsed = JSON.parse(result.output);
|
||||
|
||||
@@ -889,7 +889,7 @@ describe('audit-open — output shape (#2911)', () => {
|
||||
fs.rmSync(path.join(tmpDir, '.planning', 'phases'), { recursive: true, force: true });
|
||||
fs.writeFileSync(path.join(tmpDir, '.planning', 'phases'), 'not a directory');
|
||||
|
||||
const result = runGsdTools(['audit-open', '--json'], tmpDir);
|
||||
const result = runMsdTools(['audit-open', '--json'], tmpDir);
|
||||
assert.ok(result.success, `audit-open --json must not crash. stderr: ${result.error}`);
|
||||
const parsed = JSON.parse(result.output);
|
||||
|
||||
@@ -909,7 +909,7 @@ describe('audit-open — output shape (#2911)', () => {
|
||||
// getArchivedPhaseDirs's readdirSync throws (ENOTDIR).
|
||||
fs.writeFileSync(path.join(tmpDir, '.planning', 'milestones'), 'not a directory');
|
||||
|
||||
const result = runGsdTools(['audit-open', '--json'], tmpDir);
|
||||
const result = runMsdTools(['audit-open', '--json'], tmpDir);
|
||||
assert.ok(result.success, `audit-open --json must not crash. stderr: ${result.error}`);
|
||||
const parsed = JSON.parse(result.output);
|
||||
|
||||
@@ -936,7 +936,7 @@ describe('audit-open — output shape (#2911)', () => {
|
||||
const archivedPhaseDir = path.join(tmpDir, '.planning', 'milestones', 'v1.0-phases', '01-alpha');
|
||||
writePhaseArtifacts(archivedPhaseDir, '01', UNRESOLVED_ARTIFACTS);
|
||||
|
||||
const jsonResult = runGsdTools(['audit-open', '--json'], tmpDir);
|
||||
const jsonResult = runMsdTools(['audit-open', '--json'], tmpDir);
|
||||
assert.ok(jsonResult.success, `audit-open --json must not crash. stderr: ${jsonResult.error}`);
|
||||
const parsed = JSON.parse(jsonResult.output);
|
||||
|
||||
@@ -947,7 +947,7 @@ describe('audit-open — output shape (#2911)', () => {
|
||||
assert.deepEqual(archivedFlags, [false, true],
|
||||
'exactly one of the two duplicate-named entries must carry archived_milestone');
|
||||
|
||||
const textResult = runGsdTools(['audit-open'], tmpDir);
|
||||
const textResult = runMsdTools(['audit-open'], tmpDir);
|
||||
assert.ok(textResult.success, `audit-open (text) must not crash. stderr: ${textResult.error}`);
|
||||
const uatLines = textResult.output.split('\n').filter(l => l.includes('01-UAT.md'));
|
||||
assert.equal(uatLines.length, 2,
|
||||
@@ -963,7 +963,7 @@ describe('audit-open — output shape (#2911)', () => {
|
||||
writePhaseArtifacts(path.join(tmpDir, '.planning', 'milestones', 'v1.9-phases', '01-b'), '01', UNRESOLVED_ARTIFACTS);
|
||||
writePhaseArtifacts(path.join(tmpDir, '.planning', 'milestones', 'v1.10-phases', '01-c'), '01', UNRESOLVED_ARTIFACTS);
|
||||
|
||||
const result = runGsdTools(['audit-open', '--json'], tmpDir);
|
||||
const result = runMsdTools(['audit-open', '--json'], tmpDir);
|
||||
assert.ok(result.success, `audit-open --json must not crash. stderr: ${result.error}`);
|
||||
const parsed = JSON.parse(result.output);
|
||||
|
||||
@@ -986,7 +986,7 @@ describe('audit-open — output shape (#2911)', () => {
|
||||
const forgedQuickDir = path.join(tmpDir, '.planning', 'quick', FORGED_QUICK_TASK_DIR_NAME);
|
||||
if (!tryMkdirForgedName(t, forgedQuickDir)) return;
|
||||
|
||||
const result = runGsdTools('audit-open', tmpDir);
|
||||
const result = runMsdTools('audit-open', tmpDir);
|
||||
assert.ok(result.success, `audit-open must not crash. stderr: ${result.error}`);
|
||||
|
||||
const lines = result.output.split('\n').map(l => l.trim());
|
||||
@@ -1000,7 +1000,7 @@ describe('audit-open — output shape (#2911)', () => {
|
||||
const forgedQuickDir = path.join(tmpDir, '.planning', 'quick', FORGED_QUICK_TASK_DIR_NAME);
|
||||
if (!tryMkdirForgedName(t, forgedQuickDir)) return;
|
||||
|
||||
const result = runGsdTools('audit-open', tmpDir);
|
||||
const result = runMsdTools('audit-open', tmpDir);
|
||||
assert.ok(result.success, `audit-open must not crash. stderr: ${result.error}`);
|
||||
|
||||
assert.ok(
|
||||
@@ -1041,7 +1041,7 @@ const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const os = require('node:os');
|
||||
|
||||
const auditModule = require('../gsd-core/bin/lib/audit.cjs');
|
||||
const auditModule = require('../msd-core/bin/lib/audit.cjs');
|
||||
const { auditOpenArtifacts } = auditModule;
|
||||
const { cleanup } = require('./helpers.cjs');
|
||||
|
||||
@@ -1050,17 +1050,17 @@ function mkTmp() {
|
||||
}
|
||||
|
||||
describe('bug #2836: audit-open quick-task summary filename + UAT terminal status', () => {
|
||||
// Ensure GSD env vars do not redirect planningDir() away from our fixture.
|
||||
// Ensure MSD env vars do not redirect planningDir() away from our fixture.
|
||||
let prevProject, prevWorkstream;
|
||||
before(() => {
|
||||
prevProject = process.env.GSD_PROJECT;
|
||||
prevWorkstream = process.env.GSD_WORKSTREAM;
|
||||
delete process.env.GSD_PROJECT;
|
||||
delete process.env.GSD_WORKSTREAM;
|
||||
prevProject = process.env.MSD_PROJECT;
|
||||
prevWorkstream = process.env.MSD_WORKSTREAM;
|
||||
delete process.env.MSD_PROJECT;
|
||||
delete process.env.MSD_WORKSTREAM;
|
||||
});
|
||||
after(() => {
|
||||
if (prevProject !== undefined) process.env.GSD_PROJECT = prevProject;
|
||||
if (prevWorkstream !== undefined) process.env.GSD_WORKSTREAM = prevWorkstream;
|
||||
if (prevProject !== undefined) process.env.MSD_PROJECT = prevProject;
|
||||
if (prevWorkstream !== undefined) process.env.MSD_WORKSTREAM = prevWorkstream;
|
||||
});
|
||||
|
||||
test('quick task with ${quick_id}-SUMMARY.md is recognized as complete (not missing)', () => {
|
||||
@@ -1276,7 +1276,7 @@ describe('bug #2836: workflows/help.md one-liner reconciliation', () => {
|
||||
test('help.md quick-task one-liner uses ${quick_id}-SUMMARY.md pattern', () => {
|
||||
// After #3039, help content moved into help/modes/full.md.
|
||||
const helpPath = path.resolve(
|
||||
__dirname, '..', 'gsd-core', 'workflows', 'help', 'modes', 'full.md'
|
||||
__dirname, '..', 'msd-core', 'workflows', 'help', 'modes', 'full.md'
|
||||
);
|
||||
const content = fs.readFileSync(helpPath, 'utf-8');
|
||||
|
||||
@@ -1321,7 +1321,7 @@ describe('bug #2836: workflows/help.md one-liner reconciliation', () => {
|
||||
*
|
||||
* Primary guard: behavioral audit-scanner tests (tasks read by scanQuickTasks)
|
||||
* Secondary guard: template-contract text checks (template text IS the runtime contract)
|
||||
* Writer-path guard: contract assertions on quick.md + gsd-executor.md (source-text-is-the-product)
|
||||
* Writer-path guard: contract assertions on quick.md + msd-executor.md (source-text-is-the-product)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
@@ -1332,13 +1332,13 @@ const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const os = require('node:os');
|
||||
|
||||
const auditModule = require('../gsd-core/bin/lib/audit.cjs');
|
||||
const auditModule = require('../msd-core/bin/lib/audit.cjs');
|
||||
const { auditOpenArtifacts } = auditModule;
|
||||
const { cleanup } = require('./helpers.cjs');
|
||||
|
||||
const TEMPLATES_DIR = path.resolve(__dirname, '..', 'gsd-core', 'templates');
|
||||
const QUICK_MD = path.resolve(__dirname, '..', 'gsd-core', 'workflows', 'quick.md');
|
||||
const EXECUTOR_MD = path.resolve(__dirname, '..', 'agents', 'gsd-executor.md');
|
||||
const TEMPLATES_DIR = path.resolve(__dirname, '..', 'msd-core', 'templates');
|
||||
const QUICK_MD = path.resolve(__dirname, '..', 'msd-core', 'workflows', 'quick.md');
|
||||
const EXECUTOR_MD = path.resolve(__dirname, '..', 'agents', 'msd-executor.md');
|
||||
|
||||
function mkTmp() {
|
||||
return fs.mkdtempSync(path.join(os.tmpdir(), 'bug-950-'));
|
||||
@@ -1378,17 +1378,17 @@ function extractFrontmatter(content) {
|
||||
}
|
||||
|
||||
describe('bug #950: quick-task SUMMARY must carry status: complete', () => {
|
||||
// Ensure GSD env vars do not redirect planningDir() away from our fixture.
|
||||
// Ensure MSD env vars do not redirect planningDir() away from our fixture.
|
||||
let prevProject, prevWorkstream;
|
||||
before(() => {
|
||||
prevProject = process.env.GSD_PROJECT;
|
||||
prevWorkstream = process.env.GSD_WORKSTREAM;
|
||||
delete process.env.GSD_PROJECT;
|
||||
delete process.env.GSD_WORKSTREAM;
|
||||
prevProject = process.env.MSD_PROJECT;
|
||||
prevWorkstream = process.env.MSD_WORKSTREAM;
|
||||
delete process.env.MSD_PROJECT;
|
||||
delete process.env.MSD_WORKSTREAM;
|
||||
});
|
||||
after(() => {
|
||||
if (prevProject !== undefined) process.env.GSD_PROJECT = prevProject;
|
||||
if (prevWorkstream !== undefined) process.env.GSD_WORKSTREAM = prevWorkstream;
|
||||
if (prevProject !== undefined) process.env.MSD_PROJECT = prevProject;
|
||||
if (prevWorkstream !== undefined) process.env.MSD_WORKSTREAM = prevWorkstream;
|
||||
});
|
||||
|
||||
// ── Behavioral: scanner recognizes complete quick tasks ───────────────────
|
||||
@@ -1535,11 +1535,11 @@ describe('bug #950: quick-task SUMMARY must carry status: complete', () => {
|
||||
const fm = extractFrontmatter(content);
|
||||
assert.ok(
|
||||
fm !== null,
|
||||
'gsd-core/templates/summary.md: could not locate a YAML frontmatter block (leading --- or fenced ```markdown --- block)'
|
||||
'msd-core/templates/summary.md: could not locate a YAML frontmatter block (leading --- or fenced ```markdown --- block)'
|
||||
);
|
||||
assert.ok(
|
||||
/^status:\s*complete\s*$/m.test(fm),
|
||||
`gsd-core/templates/summary.md: \`status: complete\` not found in the frontmatter block.\n` +
|
||||
`msd-core/templates/summary.md: \`status: complete\` not found in the frontmatter block.\n` +
|
||||
`Frontmatter extracted:\n${fm}`
|
||||
);
|
||||
});
|
||||
@@ -1549,11 +1549,11 @@ describe('bug #950: quick-task SUMMARY must carry status: complete', () => {
|
||||
const fm = extractFrontmatter(content);
|
||||
assert.ok(
|
||||
fm !== null,
|
||||
'gsd-core/templates/summary-minimal.md: could not locate a leading YAML frontmatter block'
|
||||
'msd-core/templates/summary-minimal.md: could not locate a leading YAML frontmatter block'
|
||||
);
|
||||
assert.ok(
|
||||
/^status:\s*complete\s*$/m.test(fm),
|
||||
`gsd-core/templates/summary-minimal.md: \`status: complete\` not found in the frontmatter block.\n` +
|
||||
`msd-core/templates/summary-minimal.md: \`status: complete\` not found in the frontmatter block.\n` +
|
||||
`Frontmatter extracted:\n${fm}`
|
||||
);
|
||||
});
|
||||
@@ -1563,11 +1563,11 @@ describe('bug #950: quick-task SUMMARY must carry status: complete', () => {
|
||||
const fm = extractFrontmatter(content);
|
||||
assert.ok(
|
||||
fm !== null,
|
||||
'gsd-core/templates/summary-standard.md: could not locate a leading YAML frontmatter block'
|
||||
'msd-core/templates/summary-standard.md: could not locate a leading YAML frontmatter block'
|
||||
);
|
||||
assert.ok(
|
||||
/^status:\s*complete\s*$/m.test(fm),
|
||||
`gsd-core/templates/summary-standard.md: \`status: complete\` not found in the frontmatter block.\n` +
|
||||
`msd-core/templates/summary-standard.md: \`status: complete\` not found in the frontmatter block.\n` +
|
||||
`Frontmatter extracted:\n${fm}`
|
||||
);
|
||||
});
|
||||
@@ -1577,17 +1577,17 @@ describe('bug #950: quick-task SUMMARY must carry status: complete', () => {
|
||||
const fm = extractFrontmatter(content);
|
||||
assert.ok(
|
||||
fm !== null,
|
||||
'gsd-core/templates/summary-complex.md: could not locate a leading YAML frontmatter block'
|
||||
'msd-core/templates/summary-complex.md: could not locate a leading YAML frontmatter block'
|
||||
);
|
||||
assert.ok(
|
||||
/^status:\s*complete\s*$/m.test(fm),
|
||||
`gsd-core/templates/summary-complex.md: \`status: complete\` not found in the frontmatter block.\n` +
|
||||
`msd-core/templates/summary-complex.md: \`status: complete\` not found in the frontmatter block.\n` +
|
||||
`Frontmatter extracted:\n${fm}`
|
||||
);
|
||||
});
|
||||
|
||||
// ── Writer-path contract checks ───────────────────────────────────────────
|
||||
// Guards quick.md and gsd-executor.md so a future edit removing `status: complete`
|
||||
// Guards quick.md and msd-executor.md so a future edit removing `status: complete`
|
||||
// from the SUMMARY-creation instructions would fail the suite before the bug recurs.
|
||||
// (source-text-is-the-product: the deployed .md text IS the runtime contract for agents)
|
||||
|
||||
@@ -1595,16 +1595,16 @@ describe('bug #950: quick-task SUMMARY must carry status: complete', () => {
|
||||
const content = fs.readFileSync(QUICK_MD, 'utf-8');
|
||||
assert.ok(
|
||||
/status:\s*complete/.test(content),
|
||||
'gsd-core/workflows/quick.md must instruct the executor to write `status: complete` in the SUMMARY frontmatter. ' +
|
||||
'msd-core/workflows/quick.md must instruct the executor to write `status: complete` in the SUMMARY frontmatter. ' +
|
||||
'The <constraints> block must contain the `status: complete` requirement so a future edit cannot silently drop it.'
|
||||
);
|
||||
});
|
||||
|
||||
test('[WRITER-PATH] gsd-executor.md frontmatter spec requires status: complete', () => {
|
||||
test('[WRITER-PATH] msd-executor.md frontmatter spec requires status: complete', () => {
|
||||
const content = fs.readFileSync(EXECUTOR_MD, 'utf-8');
|
||||
assert.ok(
|
||||
/status[\s\S]{0,40}complete/.test(content),
|
||||
'agents/gsd-executor.md must document `status: complete` as a required SUMMARY frontmatter field. ' +
|
||||
'agents/msd-executor.md must document `status: complete` as a required SUMMARY frontmatter field. ' +
|
||||
'The Frontmatter section must include `status: complete` so the executor always emits it.'
|
||||
);
|
||||
});
|
||||
@@ -1628,7 +1628,7 @@ describe('bug #950: quick-task SUMMARY must carry status: complete', () => {
|
||||
{
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const { splitLines } = require('../gsd-core/bin/lib/text-lines.cjs');
|
||||
const { splitLines } = require('../msd-core/bin/lib/text-lines.cjs');
|
||||
|
||||
function readJson(result) {
|
||||
assert.ok(result.success, `command must succeed. stdout: ${result.output}\nstderr: ${result.error}`);
|
||||
@@ -1636,17 +1636,17 @@ describe('bug #950: quick-task SUMMARY must carry status: complete', () => {
|
||||
}
|
||||
|
||||
function ack(tmpDir, args) {
|
||||
return runGsdTools(['audit-open', 'acknowledge', ...args, '--json'], tmpDir);
|
||||
return runMsdTools(['audit-open', 'acknowledge', ...args, '--json'], tmpDir);
|
||||
}
|
||||
|
||||
function audit(tmpDir) {
|
||||
return readJson(runGsdTools(['audit-open', '--json'], tmpDir));
|
||||
return readJson(runMsdTools(['audit-open', '--json'], tmpDir));
|
||||
}
|
||||
|
||||
describe('audit-open acknowledge — suppression seam (#3458 follow-up)', () => {
|
||||
let tmpDir;
|
||||
|
||||
beforeEach(() => { tmpDir = createTempProject('gsd-3458-ack-'); });
|
||||
beforeEach(() => { tmpDir = createTempProject('msd-3458-ack-'); });
|
||||
afterEach(() => { cleanup(tmpDir); });
|
||||
|
||||
function planningPath(...segs) {
|
||||
@@ -2450,7 +2450,7 @@ describe('bug #950: quick-task SUMMARY must carry status: complete', () => {
|
||||
assert.ok(ack(tmpDir, ['--category', 'uat_gaps', '--phase', '01', '--file', '01-UAT.md', '--milestone', 'v1.0', '--at', '2026-08-15']).success);
|
||||
|
||||
// All-clear case: the only item left is a previously-acknowledged one.
|
||||
const clearReport = runGsdTools(['audit-open'], tmpDir);
|
||||
const clearReport = runMsdTools(['audit-open'], tmpDir);
|
||||
assert.ok(clearReport.success, `stderr: ${clearReport.error}`);
|
||||
assert.match(clearReport.output, /1 previously acknowledged item/i, 'all-clear footer must disclose the suppressed item');
|
||||
|
||||
@@ -2461,7 +2461,7 @@ describe('bug #950: quick-task SUMMARY must carry status: complete', () => {
|
||||
fs.mkdirSync(debugDir, { recursive: true });
|
||||
fs.writeFileSync(path.join(debugDir, 'investigate.md'), '---\nstatus: open\n---\n## Current Focus\ndigging\n');
|
||||
|
||||
const openReport = runGsdTools(['audit-open'], tmpDir);
|
||||
const openReport = runMsdTools(['audit-open'], tmpDir);
|
||||
assert.ok(openReport.success, `stderr: ${openReport.error}`);
|
||||
assert.match(openReport.output, /previously acknowledged item/i, 'footer must still disclose the acknowledged item while other items are open');
|
||||
});
|
||||
@@ -2586,17 +2586,17 @@ describe('bug #950: quick-task SUMMARY must carry status: complete', () => {
|
||||
}
|
||||
|
||||
function auditJson(tmpDir) {
|
||||
return readJson4546(runGsdTools(['audit-open', '--json'], tmpDir));
|
||||
return readJson4546(runMsdTools(['audit-open', '--json'], tmpDir));
|
||||
}
|
||||
|
||||
function ack4546(tmpDir, args) {
|
||||
return runGsdTools(['audit-open', 'acknowledge', ...args, '--json'], tmpDir);
|
||||
return runMsdTools(['audit-open', 'acknowledge', ...args, '--json'], tmpDir);
|
||||
}
|
||||
|
||||
describe('audit seed identity agrees with list-seeds (#4378)', () => {
|
||||
let tmpDir;
|
||||
|
||||
beforeEach(() => { tmpDir = createTempProject('gsd-4378-seedident-'); });
|
||||
beforeEach(() => { tmpDir = createTempProject('msd-4378-seedident-'); });
|
||||
afterEach(() => { cleanup(tmpDir); });
|
||||
|
||||
function planningPath(...segs) {
|
||||
@@ -2681,7 +2681,7 @@ describe('#4802: acknowledge refuses targets whose frontmatter fails to parse',
|
||||
const path = require('node:path');
|
||||
let tmpDir;
|
||||
|
||||
beforeEach(() => { tmpDir = createTempProject('gsd-4802-'); });
|
||||
beforeEach(() => { tmpDir = createTempProject('msd-4802-'); });
|
||||
afterEach(() => { cleanup(tmpDir); });
|
||||
|
||||
function planningPath(...segs) {
|
||||
@@ -2705,7 +2705,7 @@ describe('#4802: acknowledge refuses targets whose frontmatter fails to parse',
|
||||
].join('\n');
|
||||
|
||||
function ack(tmpDir, args) {
|
||||
return runGsdTools(['audit-open', 'acknowledge', ...args, '--json'], tmpDir);
|
||||
return runMsdTools(['audit-open', 'acknowledge', ...args, '--json'], tmpDir);
|
||||
}
|
||||
|
||||
test('threads: an unparseable-frontmatter target is refused, file byte-identical', () => {
|
||||
|
||||
Reference in New Issue
Block a user