* 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
47 lines
2.5 KiB
JavaScript
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.`,
|
|
);
|
|
});
|
|
}
|