Files
msd-core/tests/bug-3087-planner-directive-language.test.cjs
Tom Boucher 3f57a13ccf fix(#3087): restore 10 demoted directive phrases in gsd-planner.md (#3138)
* fix(#3087): restore 10 demoted directive phrases in gsd-planner.md

CRITICAL/MANDATORY/ALWAYS/MUST emphasis was systematically removed in
v1.38.4 (PR #2489) without documentation. Conflicts with PR #2489's own
stated intent (sycophancy-hardening). Downstream effect: weaker adherence
to user decisions and requirement coverage in v1.38.4-v1.40.x.

Restored:
  CRITICAL: User Decision Fidelity (heading)
  CRITICAL: Never Simplify User Decisions (heading)
  Multi-Source Coverage Audit (MANDATORY in every plan set)
  Audit ALL four source types before finalizing
  Discovery is MANDATORY unless you can prove...
  ALWAYS split if:
  requirements MUST list requirement IDs from ROADMAP
  CRITICAL: Every requirement ID MUST appear in at least one plan
  ALWAYS use the Write tool to create files
  CRITICAL — File naming convention (enforced)

Regression test: tests/bug-3087-planner-directive-language.test.cjs
(10 assertions, one per restored directive — all pass).
Suite: 6983/6983. Closes #3087.

* fix(changeset+test): fix pr field to 3138, wrap readFileSync in try/catch
2026-05-05 15:02:03 -04:00

47 lines
2.5 KiB
JavaScript

'use strict';
// Regression guard for bug #3087.
//
// Between v1.38.3 and v1.38.4, agents/gsd-planner.md had 10 instances of
// CRITICAL/MANDATORY/ALWAYS/MUST directive emphasis systematically removed.
// The change was undocumented and conflicts with the stated intent of PR #2489
// (the sycophancy-hardening pass that shipped in the same release). This test
// enforces the restored directive language so the demotion cannot recur silently.
const { test } = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const ROOT = path.join(__dirname, '..');
let src;
try {
src = fs.readFileSync(path.join(ROOT, 'agents', 'gsd-planner.md'), 'utf8');
} catch (err) {
throw new Error(`agents/gsd-planner.md not found — was the file renamed? (${err.message})`);
}
const directives = [
{ desc: 'User Decision Fidelity heading is CRITICAL', pattern: /## CRITICAL: User Decision Fidelity/ },
{ desc: 'Never Simplify heading is CRITICAL', pattern: /## CRITICAL: Never Simplify User Decisions/ },
{ desc: 'Multi-Source Audit heading is MANDATORY', pattern: /## Multi-Source Coverage Audit \(MANDATORY in every plan set\)/ },
{ desc: 'Source audit uses "Audit ALL" imperative', pattern: /Audit ALL four source types before finalizing/ },
{ desc: 'Discovery is MANDATORY', pattern: /Discovery is MANDATORY unless/ },
{ desc: 'Split signals use ALWAYS', pattern: /\*\*ALWAYS split if:\*\*/ },
{ desc: 'requirements field doc uses MUST', pattern: /\*\*MUST\*\* list requirement IDs from ROADMAP/ },
{ desc: 'Step 0 has CRITICAL requirement ID directive', pattern: /\*\*CRITICAL:\*\* Every requirement ID MUST appear/ },
{ desc: 'Write tool directive uses ALWAYS', pattern: /\*\*ALWAYS use the Write tool to create files\*\*/ },
{ desc: 'File naming convention heading is CRITICAL', pattern: /\*\*CRITICAL — File naming convention \(enforced\):\*\*/ },
];
for (const { desc, pattern } of directives) {
test(`gsd-planner.md: ${desc}`, () => {
assert.ok(
pattern.test(src),
`Directive enforcement missing from gsd-planner.md: "${desc}" — pattern ${pattern} not found. ` +
`This language was demoted in v1.38.4 (PR #2489) without documentation, conflicting with ` +
`the sycophancy-hardening intent of that release. See bug #3087.`,
);
});
}