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 @@
|
||||
// Claude Code loads at runtime. Checking text content IS checking the deployed contract.
|
||||
|
||||
/**
|
||||
* GSD Agent Frontmatter Tests
|
||||
* MSD Agent Frontmatter Tests
|
||||
*
|
||||
* Validates that all agent .md files have correct frontmatter fields:
|
||||
* - Anti-heredoc instruction present in file-writing agents
|
||||
@@ -19,8 +19,8 @@ const path = require('path');
|
||||
const { listAgentFiles } = require('./helpers/agent-roster.cjs');
|
||||
|
||||
const AGENTS_DIR = path.join(__dirname, '..', 'agents');
|
||||
const WORKFLOWS_DIR = path.join(__dirname, '..', 'gsd-core', 'workflows');
|
||||
const COMMANDS_DIR = path.join(__dirname, '..', 'commands', 'gsd');
|
||||
const WORKFLOWS_DIR = path.join(__dirname, '..', 'msd-core', 'workflows');
|
||||
const COMMANDS_DIR = path.join(__dirname, '..', 'commands', 'msd');
|
||||
|
||||
// Sorted basenames (without `.md`); reads below re-add `.md` via `name + '.md'`.
|
||||
const ALL_AGENTS = listAgentFiles(AGENTS_DIR);
|
||||
@@ -107,11 +107,11 @@ describe('HOOK: hooks frontmatter pattern', () => {
|
||||
|
||||
describe('SPAWN: spawn type consistency', () => {
|
||||
// #1689: `subagent_type="{TOKEN}"` is a workflow-bound placeholder for
|
||||
// parameterized executor dispatch (resolved at runtime via `gsd-tools
|
||||
// resolve-agent`, defaulting to gsd-executor), not a concrete agent name.
|
||||
// parameterized executor dispatch (resolved at runtime via `msd-tools
|
||||
// resolve-agent`, defaulting to msd-executor), not a concrete agent name.
|
||||
// The static spawn-type checks below skip these — the effective value is
|
||||
// validated at dispatch time, and execute-phase.md still documents the
|
||||
// built-in roster (incl. gsd-executor) in <available_agent_types>.
|
||||
// built-in roster (incl. msd-executor) in <available_agent_types>.
|
||||
const PARAMETERIZED_SPAWN_TYPE = /^\{[^}]+\}$/;
|
||||
|
||||
test('no "First, read agent .md" workaround pattern remains', () => {
|
||||
@@ -121,7 +121,7 @@ describe('SPAWN: spawn type consistency', () => {
|
||||
const files = fs.readdirSync(dir).filter(f => f.endsWith('.md'));
|
||||
for (const file of files) {
|
||||
const content = fs.readFileSync(path.join(dir, file), 'utf-8');
|
||||
const hasWorkaround = content.includes('First, read ~/.claude/agents/gsd-');
|
||||
const hasWorkaround = content.includes('First, read ~/.claude/agents/msd-');
|
||||
assert.ok(
|
||||
!hasWorkaround,
|
||||
`${file} still has "First, read agent .md" workaround — use named subagent_type instead`
|
||||
@@ -156,13 +156,13 @@ describe('SPAWN: spawn type consistency', () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('diagnose-issues uses gsd-debugger (not general-purpose)', () => {
|
||||
test('diagnose-issues uses msd-debugger (not general-purpose)', () => {
|
||||
const content = fs.readFileSync(
|
||||
path.join(WORKFLOWS_DIR, 'diagnose-issues.md'), 'utf-8'
|
||||
);
|
||||
assert.ok(
|
||||
content.includes('subagent_type="gsd-debugger"'),
|
||||
'diagnose-issues should spawn gsd-debugger, not general-purpose'
|
||||
content.includes('subagent_type="msd-debugger"'),
|
||||
'diagnose-issues should spawn msd-debugger, not general-purpose'
|
||||
);
|
||||
});
|
||||
|
||||
@@ -171,7 +171,7 @@ describe('SPAWN: spawn type consistency', () => {
|
||||
// context. Without an <available_agent_types> section, the orchestrator may
|
||||
// fall back to general-purpose, silently breaking agent capabilities.
|
||||
// PR #1139 added this to plan-phase and execute-phase but missed all other
|
||||
// workflows that spawn named GSD agents.
|
||||
// workflows that spawn named MSD agents.
|
||||
const dirs = [WORKFLOWS_DIR, COMMANDS_DIR];
|
||||
for (const dir of dirs) {
|
||||
if (!fs.existsSync(dir)) continue;
|
||||
@@ -249,7 +249,7 @@ describe('AGENT: required frontmatter fields', () => {
|
||||
// ─── Model resolution uniformity (#3895) ─────────────────────────────────────
|
||||
|
||||
describe('MODEL: no agent hardcodes a model frontmatter pin', () => {
|
||||
// Exactly one shipped agent (gsd-mempalace-curator) carried `model: sonnet`
|
||||
// Exactly one shipped agent (msd-mempalace-curator) carried `model: sonnet`
|
||||
// while the other 33 resolved through the model-profile system. The pin
|
||||
// intercepted #2517's deliberate inherit case — the ship:post dispatch OMITS
|
||||
// model= on inherit so the agent inherits the orchestrator's model, but the
|
||||
@@ -270,9 +270,9 @@ describe('MODEL: no agent hardcodes a model frontmatter pin', () => {
|
||||
});
|
||||
|
||||
test('the curator keeps its catalog entry (deleting the pin must not orphan the agent)', () => {
|
||||
const catalog = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'gsd-core', 'bin', 'shared', 'model-catalog.json'), 'utf-8'));
|
||||
const entry = catalog.agents && catalog.agents['gsd-mempalace-curator'];
|
||||
assert.ok(entry, 'catalog entry for gsd-mempalace-curator must exist');
|
||||
const catalog = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'msd-core', 'bin', 'shared', 'model-catalog.json'), 'utf-8'));
|
||||
const entry = catalog.agents && catalog.agents['msd-mempalace-curator'];
|
||||
assert.ok(entry, 'catalog entry for msd-mempalace-curator must exist');
|
||||
assert.equal(entry.golden, 'sonnet', 'golden profile preserves the pinned behavior');
|
||||
assert.equal(entry.balanced, 'sonnet', 'balanced profile preserves the pinned behavior');
|
||||
});
|
||||
@@ -305,44 +305,44 @@ describe('COLOR: color frontmatter must be a documented named color', () => {
|
||||
// ─── CLAUDE.md Compliance ───────────────────────────────────────────────────
|
||||
|
||||
describe('CLAUDEMD: CLAUDE.md compliance enforcement', () => {
|
||||
test('gsd-plan-checker has Dimension 10: CLAUDE.md Compliance', () => {
|
||||
const content = fs.readFileSync(path.join(AGENTS_DIR, 'gsd-plan-checker.md'), 'utf-8');
|
||||
test('msd-plan-checker has Dimension 10: CLAUDE.md Compliance', () => {
|
||||
const content = fs.readFileSync(path.join(AGENTS_DIR, 'msd-plan-checker.md'), 'utf-8');
|
||||
assert.ok(
|
||||
content.includes('Dimension 10: CLAUDE.md Compliance'),
|
||||
'gsd-plan-checker must have Dimension 10 for CLAUDE.md compliance checking'
|
||||
'msd-plan-checker must have Dimension 10 for CLAUDE.md compliance checking'
|
||||
);
|
||||
assert.ok(
|
||||
content.includes('claude_md_compliance'),
|
||||
'gsd-plan-checker must use claude_md_compliance as dimension identifier'
|
||||
'msd-plan-checker must use claude_md_compliance as dimension identifier'
|
||||
);
|
||||
});
|
||||
|
||||
test('gsd-phase-researcher has CLAUDE.md enforcement directive', () => {
|
||||
const content = fs.readFileSync(path.join(AGENTS_DIR, 'gsd-phase-researcher.md'), 'utf-8');
|
||||
test('msd-phase-researcher has CLAUDE.md enforcement directive', () => {
|
||||
const content = fs.readFileSync(path.join(AGENTS_DIR, 'msd-phase-researcher.md'), 'utf-8');
|
||||
assert.ok(
|
||||
content.includes('CLAUDE.md enforcement'),
|
||||
'gsd-phase-researcher must enforce CLAUDE.md directives during research'
|
||||
'msd-phase-researcher must enforce CLAUDE.md directives during research'
|
||||
);
|
||||
assert.ok(
|
||||
content.includes('Project Constraints (from CLAUDE.md)'),
|
||||
'gsd-phase-researcher must output a Project Constraints section from CLAUDE.md'
|
||||
'msd-phase-researcher must output a Project Constraints section from CLAUDE.md'
|
||||
);
|
||||
});
|
||||
|
||||
test('gsd-executor has CLAUDE.md enforcement directive', () => {
|
||||
const content = fs.readFileSync(path.join(AGENTS_DIR, 'gsd-executor.md'), 'utf-8');
|
||||
test('msd-executor has CLAUDE.md enforcement directive', () => {
|
||||
const content = fs.readFileSync(path.join(AGENTS_DIR, 'msd-executor.md'), 'utf-8');
|
||||
assert.ok(
|
||||
content.includes('CLAUDE.md enforcement'),
|
||||
'gsd-executor must enforce CLAUDE.md directives during execution'
|
||||
'msd-executor must enforce CLAUDE.md directives during execution'
|
||||
);
|
||||
assert.ok(
|
||||
content.includes('CLAUDE.md rule — it takes precedence over plan instructions'),
|
||||
'gsd-executor must specify CLAUDE.md precedence over plan instructions'
|
||||
'msd-executor must specify CLAUDE.md precedence over plan instructions'
|
||||
);
|
||||
});
|
||||
|
||||
test('all three agents read CLAUDE.md in project_context', () => {
|
||||
const agents = ['gsd-plan-checker', 'gsd-phase-researcher', 'gsd-executor'];
|
||||
const agents = ['msd-plan-checker', 'msd-phase-researcher', 'msd-executor'];
|
||||
for (const agent of agents) {
|
||||
const content = fs.readFileSync(path.join(AGENTS_DIR, agent + '.md'), 'utf-8');
|
||||
assert.ok(
|
||||
@@ -356,36 +356,36 @@ describe('CLAUDEMD: CLAUDE.md compliance enforcement', () => {
|
||||
// ─── Verification Data-Flow and Environment Audit (#1245) ────────────────────
|
||||
|
||||
describe('VERIFY: data-flow trace, environment audit, and behavioral spot-checks', () => {
|
||||
test('gsd-verifier has Step 4b: Data-Flow Trace', () => {
|
||||
const content = fs.readFileSync(path.join(AGENTS_DIR, 'gsd-verifier.md'), 'utf-8');
|
||||
test('msd-verifier has Step 4b: Data-Flow Trace', () => {
|
||||
const content = fs.readFileSync(path.join(AGENTS_DIR, 'msd-verifier.md'), 'utf-8');
|
||||
assert.ok(
|
||||
content.includes('Step 4b: Data-Flow Trace'),
|
||||
'gsd-verifier must have Step 4b for data-flow tracing'
|
||||
'msd-verifier must have Step 4b for data-flow tracing'
|
||||
);
|
||||
assert.ok(
|
||||
content.includes('HOLLOW'),
|
||||
'gsd-verifier must define HOLLOW status for wired-but-disconnected artifacts'
|
||||
'msd-verifier must define HOLLOW status for wired-but-disconnected artifacts'
|
||||
);
|
||||
assert.ok(
|
||||
content.includes('DISCONNECTED'),
|
||||
'gsd-verifier must define DISCONNECTED status for missing data sources'
|
||||
'msd-verifier must define DISCONNECTED status for missing data sources'
|
||||
);
|
||||
});
|
||||
|
||||
test('gsd-verifier has Step 7b: Behavioral Spot-Checks', () => {
|
||||
const content = fs.readFileSync(path.join(AGENTS_DIR, 'gsd-verifier.md'), 'utf-8');
|
||||
test('msd-verifier has Step 7b: Behavioral Spot-Checks', () => {
|
||||
const content = fs.readFileSync(path.join(AGENTS_DIR, 'msd-verifier.md'), 'utf-8');
|
||||
assert.ok(
|
||||
content.includes('Step 7b: Behavioral Spot-Checks'),
|
||||
'gsd-verifier must have Step 7b for behavioral spot-checks'
|
||||
'msd-verifier must have Step 7b for behavioral spot-checks'
|
||||
);
|
||||
assert.ok(
|
||||
content.includes('SKIP'),
|
||||
'gsd-verifier spot-checks must support SKIP status for untestable items'
|
||||
'msd-verifier spot-checks must support SKIP status for untestable items'
|
||||
);
|
||||
});
|
||||
|
||||
test('gsd-verifier VERIFICATION.md template includes data-flow and spot-check sections', () => {
|
||||
const content = fs.readFileSync(path.join(AGENTS_DIR, 'gsd-verifier.md'), 'utf-8');
|
||||
test('msd-verifier VERIFICATION.md template includes data-flow and spot-check sections', () => {
|
||||
const content = fs.readFileSync(path.join(AGENTS_DIR, 'msd-verifier.md'), 'utf-8');
|
||||
assert.ok(
|
||||
content.includes('Data-Flow Trace (Level 4)'),
|
||||
'VERIFICATION.md template must include Data-Flow Trace section'
|
||||
@@ -396,8 +396,8 @@ describe('VERIFY: data-flow trace, environment audit, and behavioral spot-checks
|
||||
);
|
||||
});
|
||||
|
||||
test('gsd-verifier success criteria include data-flow and spot-checks', () => {
|
||||
const content = fs.readFileSync(path.join(AGENTS_DIR, 'gsd-verifier.md'), 'utf-8');
|
||||
test('msd-verifier success criteria include data-flow and spot-checks', () => {
|
||||
const content = fs.readFileSync(path.join(AGENTS_DIR, 'msd-verifier.md'), 'utf-8');
|
||||
assert.ok(
|
||||
content.includes('Data-flow trace (Level 4)'),
|
||||
'success criteria must include data-flow trace step'
|
||||
@@ -408,20 +408,20 @@ describe('VERIFY: data-flow trace, environment audit, and behavioral spot-checks
|
||||
);
|
||||
});
|
||||
|
||||
test('gsd-phase-researcher has Step 2.6: Environment Availability Audit', () => {
|
||||
const content = fs.readFileSync(path.join(AGENTS_DIR, 'gsd-phase-researcher.md'), 'utf-8');
|
||||
test('msd-phase-researcher has Step 2.6: Environment Availability Audit', () => {
|
||||
const content = fs.readFileSync(path.join(AGENTS_DIR, 'msd-phase-researcher.md'), 'utf-8');
|
||||
assert.ok(
|
||||
content.includes('Step 2.6: Environment Availability Audit'),
|
||||
'gsd-phase-researcher must have Step 2.6 for environment availability auditing'
|
||||
'msd-phase-researcher must have Step 2.6 for environment availability auditing'
|
||||
);
|
||||
assert.ok(
|
||||
content.includes('Environment Availability'),
|
||||
'gsd-phase-researcher must include Environment Availability section in RESEARCH.md template'
|
||||
'msd-phase-researcher must include Environment Availability section in RESEARCH.md template'
|
||||
);
|
||||
});
|
||||
|
||||
test('gsd-phase-researcher success criteria include environment audit', () => {
|
||||
const content = fs.readFileSync(path.join(AGENTS_DIR, 'gsd-phase-researcher.md'), 'utf-8');
|
||||
test('msd-phase-researcher success criteria include environment audit', () => {
|
||||
const content = fs.readFileSync(path.join(AGENTS_DIR, 'msd-phase-researcher.md'), 'utf-8');
|
||||
assert.ok(
|
||||
content.includes('Environment availability audited'),
|
||||
'success criteria must include environment availability audit step'
|
||||
@@ -454,7 +454,7 @@ describe('DISCUSS: discussion log generation', () => {
|
||||
});
|
||||
|
||||
test('discussion-log template exists', () => {
|
||||
const templatePath = path.join(__dirname, '..', 'gsd-core', 'templates', 'discussion-log.md');
|
||||
const templatePath = path.join(__dirname, '..', 'msd-core', 'templates', 'discussion-log.md');
|
||||
assert.ok(
|
||||
fs.existsSync(templatePath),
|
||||
'discussion-log.md template must exist'
|
||||
@@ -473,16 +473,16 @@ describe('EDITWRITE: section-writer agents must have both Write and Edit in tool
|
||||
// These agents perform in-place section edits on shared/existing files (e.g.
|
||||
// AI-SPEC.md). Without Edit in tools:, the "Edit-only" discipline in their
|
||||
// spawn-prompt is unenforceable — they fall back to whole-file Write and
|
||||
// clobber sibling sections. Same bug class as #571/#575 (fixed gsd-doc-writer).
|
||||
// clobber sibling sections. Same bug class as #571/#575 (fixed msd-doc-writer).
|
||||
// Issue #581.
|
||||
const SECTION_WRITER_AGENTS = [
|
||||
'gsd-eval-planner',
|
||||
'gsd-ai-researcher',
|
||||
'gsd-domain-researcher',
|
||||
'gsd-phase-researcher',
|
||||
'gsd-ui-researcher',
|
||||
'gsd-debug-session-manager',
|
||||
'gsd-planner', // #973: planner lacked Edit; whole-file Write truncated ROADMAP.md
|
||||
'msd-eval-planner',
|
||||
'msd-ai-researcher',
|
||||
'msd-domain-researcher',
|
||||
'msd-phase-researcher',
|
||||
'msd-ui-researcher',
|
||||
'msd-debug-session-manager',
|
||||
'msd-planner', // #973: planner lacked Edit; whole-file Write truncated ROADMAP.md
|
||||
];
|
||||
|
||||
for (const agent of SECTION_WRITER_AGENTS) {
|
||||
@@ -509,7 +509,7 @@ describe('COMPAT: agents must not use runtime-specific frontmatter keys', () =>
|
||||
// permissionMode is Claude Code-specific and breaks Gemini CLI agent loading.
|
||||
// It also has no effect on subagent Write permissions in Claude Code (blocked
|
||||
// at runtime level regardless). See #1522, #1387.
|
||||
const AGENTS_WITH_WRITE = ['gsd-executor', 'gsd-debugger'];
|
||||
const AGENTS_WITH_WRITE = ['msd-executor', 'msd-debugger'];
|
||||
|
||||
for (const agent of AGENTS_WITH_WRITE) {
|
||||
test(`${agent} does not have permissionMode (breaks Gemini CLI)`, () => {
|
||||
@@ -534,10 +534,10 @@ describe('COMPAT: agents must not use runtime-specific frontmatter keys', () =>
|
||||
/**
|
||||
* Regression tests for bug #2346
|
||||
*
|
||||
* Multiple GSD agents (gsd-ui-checker, gsd-planner) entered unbounded Read
|
||||
* Multiple MSD agents (msd-ui-checker, msd-planner) entered unbounded Read
|
||||
* loops — re-reading the same file hundreds of times in a single run. Root
|
||||
* cause: no explicit no-re-read rule or tool-budget cap in the agent prompts.
|
||||
* gsd-pattern-mapper was fixed in #2312; this covers the remaining agents.
|
||||
* msd-pattern-mapper was fixed in #2312; this covers the remaining agents.
|
||||
*
|
||||
* Fix: add <critical_rules> block to each affected agent with:
|
||||
* 1. No-re-read constraint
|
||||
@@ -559,18 +559,18 @@ const AGENTS_DIR = path.join(__dirname, '..', 'agents');
|
||||
// prevents unbounded Read loops. There is no behavioral equivalent without a live LLM run.
|
||||
describe('bug #2346: agent read loop guards', () => {
|
||||
|
||||
describe('gsd-ui-checker', () => {
|
||||
const agentPath = path.join(AGENTS_DIR, 'gsd-ui-checker.md');
|
||||
describe('msd-ui-checker', () => {
|
||||
const agentPath = path.join(AGENTS_DIR, 'msd-ui-checker.md');
|
||||
const content = fs.readFileSync(agentPath, 'utf-8');
|
||||
|
||||
test('agent file exists', () => {
|
||||
assert.ok(fs.existsSync(agentPath), 'agents/gsd-ui-checker.md must exist');
|
||||
assert.ok(fs.existsSync(agentPath), 'agents/msd-ui-checker.md must exist');
|
||||
});
|
||||
|
||||
test('has <critical_rules> block', () => {
|
||||
assert.ok(
|
||||
content.includes('<critical_rules>'),
|
||||
'gsd-ui-checker.md must have a <critical_rules> block to prevent unbounded read loops (#2346)'
|
||||
'msd-ui-checker.md must have a <critical_rules> block to prevent unbounded read loops (#2346)'
|
||||
);
|
||||
});
|
||||
|
||||
@@ -596,18 +596,18 @@ describe('bug #2346: agent read loop guards', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('gsd-planner', () => {
|
||||
const agentPath = path.join(AGENTS_DIR, 'gsd-planner.md');
|
||||
describe('msd-planner', () => {
|
||||
const agentPath = path.join(AGENTS_DIR, 'msd-planner.md');
|
||||
const content = fs.readFileSync(agentPath, 'utf-8');
|
||||
|
||||
test('agent file exists', () => {
|
||||
assert.ok(fs.existsSync(agentPath), 'agents/gsd-planner.md must exist');
|
||||
assert.ok(fs.existsSync(agentPath), 'agents/msd-planner.md must exist');
|
||||
});
|
||||
|
||||
test('has <critical_rules> block', () => {
|
||||
assert.ok(
|
||||
content.includes('<critical_rules>'),
|
||||
'gsd-planner.md must have a <critical_rules> block to prevent unbounded read loops (#2346)'
|
||||
'msd-planner.md must have a <critical_rules> block to prevent unbounded read loops (#2346)'
|
||||
);
|
||||
});
|
||||
|
||||
@@ -652,12 +652,12 @@ describe('bug #2346: agent read loop guards', () => {
|
||||
/**
|
||||
* Bug #3605: Stale slash command references in 5 agent files
|
||||
*
|
||||
* After #3042 deleted /gsd-research-phase (replaced by
|
||||
* /gsd-plan-phase --research-phase <N>) and v1.40.0 consolidated /gsd-insert-phase
|
||||
* into /gsd-phase insert, six occurrences survived in agents/*.md because none of
|
||||
* After #3042 deleted /msd-research-phase (replaced by
|
||||
* /msd-plan-phase --research-phase <N>) and v1.40.0 consolidated /msd-insert-phase
|
||||
* into /msd-phase insert, six occurrences survived in agents/*.md because none of
|
||||
* the consolidation passes (#3029, #3044, #3131) included agents/ in their per-name
|
||||
* scrub scope. scripts/fix-slash-commands.cjs lists agents/ in SEARCH_DIRS but only
|
||||
* runs the /gsd- → /gsd: namespace transform, not retired-name replacement.
|
||||
* runs the /msd- → /msd: namespace transform, not retired-name replacement.
|
||||
*
|
||||
* This guard fails when any retired command name reappears in agents/*.md.
|
||||
*/
|
||||
@@ -672,11 +672,11 @@ const path = require('node:path');
|
||||
const AGENTS_DIR = path.join(__dirname, '..', 'agents');
|
||||
|
||||
const RETIRED_COMMANDS = [
|
||||
'/gsd-research-phase',
|
||||
'/gsd-insert-phase',
|
||||
'/gsd-add-phase',
|
||||
'/gsd-remove-phase',
|
||||
'/gsd-analyze-dependencies',
|
||||
'/msd-research-phase',
|
||||
'/msd-insert-phase',
|
||||
'/msd-add-phase',
|
||||
'/msd-remove-phase',
|
||||
'/msd-analyze-dependencies',
|
||||
];
|
||||
|
||||
// Not the shared listAgentFiles() helper: this returns ABSOLUTE paths (consumed
|
||||
@@ -748,7 +748,7 @@ describe('bug #3605: agent contracts must not reference retired slash commands',
|
||||
/**
|
||||
* Tests for #2427 — prompt-level sycophancy hardening of audit-class agents.
|
||||
* Verifies the four required changes are present in each agent file:
|
||||
* 1. Third-person framing (no "You are a GSD X" opening in <role>)
|
||||
* 1. Third-person framing (no "You are a MSD X" opening in <role>)
|
||||
* 2. FORCE adversarial stance block
|
||||
* 3. Explicit failure modes list
|
||||
* 4. BLOCKER/WARNING classification requirement
|
||||
@@ -762,15 +762,15 @@ const path = require('node:path');
|
||||
const AGENTS_DIR = path.join(__dirname, '../agents');
|
||||
|
||||
const AUDIT_AGENTS = [
|
||||
'gsd-plan-checker.md',
|
||||
'gsd-code-reviewer.md',
|
||||
'gsd-security-auditor.md',
|
||||
'gsd-verifier.md',
|
||||
'gsd-eval-auditor.md',
|
||||
'gsd-nyquist-auditor.md',
|
||||
'gsd-ui-auditor.md',
|
||||
'gsd-integration-checker.md',
|
||||
'gsd-doc-verifier.md',
|
||||
'msd-plan-checker.md',
|
||||
'msd-code-reviewer.md',
|
||||
'msd-security-auditor.md',
|
||||
'msd-verifier.md',
|
||||
'msd-eval-auditor.md',
|
||||
'msd-nyquist-auditor.md',
|
||||
'msd-ui-auditor.md',
|
||||
'msd-integration-checker.md',
|
||||
'msd-doc-verifier.md',
|
||||
];
|
||||
|
||||
function readAgent(agentsDir, filename) {
|
||||
@@ -797,13 +797,13 @@ describe('enh-2427 — sycophancy hardening: audit-class agents', () => {
|
||||
assert.ok(content.length > 0, `${filename} should not be empty`);
|
||||
});
|
||||
|
||||
test('(1) third-person framing — <role> does not open with "You are a GSD"', () => {
|
||||
test('(1) third-person framing — <role> does not open with "You are a MSD"', () => {
|
||||
content = content || readAgent(AGENTS_DIR, filename);
|
||||
role = role || extractRole(content);
|
||||
const firstSentence = role.trim().slice(0, 80);
|
||||
assert.ok(
|
||||
!firstSentence.startsWith('You are a GSD'),
|
||||
`${filename}: <role> must not open with "You are a GSD" — use third-person submission framing. Got: "${firstSentence}"`
|
||||
!firstSentence.startsWith('You are a MSD'),
|
||||
`${filename}: <role> must not open with "You are a MSD" — use third-person submission framing. Got: "${firstSentence}"`
|
||||
);
|
||||
});
|
||||
|
||||
@@ -856,7 +856,7 @@ describe('enh-2427 — sycophancy hardening: audit-class agents', () => {
|
||||
/**
|
||||
* Regression tests for bug #571
|
||||
*
|
||||
* gsd-doc-writer in fix mode used the Write tool (whole-file replace) instead
|
||||
* msd-doc-writer in fix mode used the Write tool (whole-file replace) instead
|
||||
* of the Edit tool (surgical replacement) when correcting specific failing
|
||||
* claims. When the target doc was generated but not yet committed, Write could
|
||||
* truncate the file to a single line with no git recovery path.
|
||||
@@ -879,23 +879,23 @@ const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const AGENTS_DIR = path.join(__dirname, '..', 'agents');
|
||||
const WORKFLOWS_DIR = path.join(__dirname, '..', 'gsd-core', 'workflows');
|
||||
const WORKFLOWS_DIR = path.join(__dirname, '..', 'msd-core', 'workflows');
|
||||
|
||||
const AGENT_PATH = path.join(AGENTS_DIR, 'gsd-doc-writer.md');
|
||||
const AGENT_PATH = path.join(AGENTS_DIR, 'msd-doc-writer.md');
|
||||
const WORKFLOW_PATH = path.join(WORKFLOWS_DIR, 'docs-update.md');
|
||||
|
||||
// ─── Agent fix: Edit in tools frontmatter ────────────────────────────────────
|
||||
|
||||
describe('bug #571: gsd-doc-writer agent', () => {
|
||||
describe('bug #571: msd-doc-writer agent', () => {
|
||||
const content = fs.readFileSync(AGENT_PATH, 'utf-8');
|
||||
|
||||
test('agent file exists', () => {
|
||||
assert.ok(fs.existsSync(AGENT_PATH), 'agents/gsd-doc-writer.md must exist');
|
||||
assert.ok(fs.existsSync(AGENT_PATH), 'agents/msd-doc-writer.md must exist');
|
||||
});
|
||||
|
||||
test('tools frontmatter includes Edit', () => {
|
||||
const toolsMatch = content.match(/^tools:\s*(.+)$/m);
|
||||
assert.ok(toolsMatch, 'gsd-doc-writer.md must have a tools: frontmatter line');
|
||||
assert.ok(toolsMatch, 'msd-doc-writer.md must have a tools: frontmatter line');
|
||||
assert.ok(
|
||||
toolsMatch[1].includes('Edit'),
|
||||
'tools: frontmatter must include Edit so fix mode can make surgical replacements (#571)'
|
||||
@@ -965,7 +965,7 @@ describe('bug #571: docs-update workflow fix_loop', () => {
|
||||
const content = fs.readFileSync(WORKFLOW_PATH, 'utf-8');
|
||||
|
||||
test('workflow file exists', () => {
|
||||
assert.ok(fs.existsSync(WORKFLOW_PATH), 'gsd-core/workflows/docs-update.md must exist');
|
||||
assert.ok(fs.existsSync(WORKFLOW_PATH), 'msd-core/workflows/docs-update.md must exist');
|
||||
});
|
||||
|
||||
describe('fix_loop step', () => {
|
||||
@@ -1077,15 +1077,15 @@ const REPO_ROOT = path.resolve(__dirname, '..');
|
||||
// same truncation-resilient write contract added for bug #214. OpenCode shares
|
||||
// OUTPUT_TOKEN_MAX=32000 with the thinking budget (upstream opencode#18108), so
|
||||
// an oversized single `write` tool call is truncated mid-payload, yielding
|
||||
// `JSON Parse error: Expected '}'`, and OpenCode then doom-loops. gsd-phase-researcher
|
||||
// `JSON Parse error: Expected '}'`, and OpenCode then doom-loops. msd-phase-researcher
|
||||
// is locked by its own bug-214 test; this locks the other large-file writers.
|
||||
const WRITER_AGENTS = [
|
||||
'gsd-research-synthesizer',
|
||||
'gsd-planner',
|
||||
'gsd-executor',
|
||||
'gsd-domain-researcher',
|
||||
'gsd-project-researcher',
|
||||
'gsd-ui-researcher',
|
||||
'msd-research-synthesizer',
|
||||
'msd-planner',
|
||||
'msd-executor',
|
||||
'msd-domain-researcher',
|
||||
'msd-project-researcher',
|
||||
'msd-ui-researcher',
|
||||
];
|
||||
|
||||
function readAgent(name) {
|
||||
@@ -1120,7 +1120,7 @@ describe('bug #214: large-file writer agents must survive write-tool truncation'
|
||||
test('defines the continuation sentinel', () => {
|
||||
assert.match(
|
||||
prompt,
|
||||
/<!-- gsd:write-continue -->/,
|
||||
/<!-- msd:write-continue -->/,
|
||||
`${name}: must define the continuation sentinel for incremental writes.`
|
||||
);
|
||||
});
|
||||
@@ -1178,7 +1178,7 @@ const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const REPO_ROOT = path.resolve(__dirname, '..');
|
||||
const RESEARCHER_PATH = path.join(REPO_ROOT, 'agents', 'gsd-phase-researcher.md');
|
||||
const RESEARCHER_PATH = path.join(REPO_ROOT, 'agents', 'msd-phase-researcher.md');
|
||||
|
||||
function readResearcherPrompt() {
|
||||
return fs.readFileSync(RESEARCHER_PATH, 'utf8');
|
||||
@@ -1200,7 +1200,7 @@ describe('bug #214: phase researcher must survive OpenCode write-tool truncation
|
||||
);
|
||||
assert.match(
|
||||
prompt,
|
||||
/<!-- gsd:write-continue -->/,
|
||||
/<!-- msd:write-continue -->/,
|
||||
'Step 6 must define the continuation sentinel for incremental writes.'
|
||||
);
|
||||
assert.match(
|
||||
@@ -1243,7 +1243,7 @@ describe('bug #214: phase researcher must survive OpenCode write-tool truncation
|
||||
'use strict';
|
||||
|
||||
// allow-test-rule: source-text-is-the-product (see #2990)
|
||||
// agents/gsd-code-fixer.md is the deployed agent definition the runtime
|
||||
// agents/msd-code-fixer.md is the deployed agent definition the runtime
|
||||
// loads. Parsing its bash code blocks into structured invocation records
|
||||
// (extractCleanupGitInvocations + the recovery-block parsers below) IS
|
||||
// testing the runtime contract — what command sequence the agent
|
||||
@@ -1251,17 +1251,17 @@ describe('bug #214: phase researcher must survive OpenCode write-tool truncation
|
||||
// fields from a known-shape product file, then assertions go against
|
||||
// those typed fields, not against the raw markdown text.
|
||||
|
||||
// Consolidation #1969: scope GSD_TEST_MODE to this folded block so it does not
|
||||
// Consolidation #1969: scope MSD_TEST_MODE to this folded block so it does not
|
||||
// leak into sibling folded suites in the shared file (was process-isolated when
|
||||
// standalone). This unit suite only parses agent markdown, but keep the flag set
|
||||
// for its own duration to preserve the origin behaviour, and restore it after.
|
||||
const { before: __gtmBefore, after: __gtmAfter } = require('node:test');
|
||||
const __savedGsdTestMode = process.env.GSD_TEST_MODE;
|
||||
__gtmBefore(() => { process.env.GSD_TEST_MODE = '1'; });
|
||||
__gtmAfter(() => { if (__savedGsdTestMode === undefined) delete process.env.GSD_TEST_MODE; else process.env.GSD_TEST_MODE = __savedGsdTestMode; });
|
||||
const __savedMsdTestMode = process.env.MSD_TEST_MODE;
|
||||
__gtmBefore(() => { process.env.MSD_TEST_MODE = '1'; });
|
||||
__gtmAfter(() => { if (__savedMsdTestMode === undefined) delete process.env.MSD_TEST_MODE; else process.env.MSD_TEST_MODE = __savedMsdTestMode; });
|
||||
|
||||
/**
|
||||
* Bug #2990: gsd-code-fixer worktree setup fails when current branch
|
||||
* Bug #2990: msd-code-fixer worktree setup fails when current branch
|
||||
* is already checked out in the main repo.
|
||||
*
|
||||
* The original agent definition called `git worktree add "$wt" "$branch"`,
|
||||
@@ -1269,7 +1269,7 @@ __gtmAfter(() => { if (__savedGsdTestMode === undefined) delete process.env.GSD_
|
||||
* to check out the same branch in two worktrees by default, so the setup
|
||||
* failed before the agent could do any work.
|
||||
*
|
||||
* Fix: create a NEW branch `gsd-reviewfix/${padded_phase}-$$` and attach
|
||||
* Fix: create a NEW branch `msd-reviewfix/${padded_phase}-$$` and attach
|
||||
* the worktree to it via `git worktree add -b "$reviewfix_branch" "$wt"
|
||||
* "$branch"`. The cleanup tail then fast-forwards `$branch` to
|
||||
* `$reviewfix_branch` so the user's branch captures the agent's commits.
|
||||
@@ -1280,7 +1280,7 @@ const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const AGENT_PATH = path.join(__dirname, '..', 'agents', 'gsd-code-fixer.md');
|
||||
const AGENT_PATH = path.join(__dirname, '..', 'agents', 'msd-code-fixer.md');
|
||||
|
||||
function parseWorktreeAddInvocations(markdown) {
|
||||
// Pull `git worktree add ...` calls and classify each into structured
|
||||
@@ -1310,13 +1310,13 @@ function parseWorktreeAddInvocations(markdown) {
|
||||
return invocations;
|
||||
}
|
||||
|
||||
describe('Bug #2990: gsd-code-fixer worktree attaches to a NEW branch, not the user-checked-out one', () => {
|
||||
describe('Bug #2990: msd-code-fixer worktree attaches to a NEW branch, not the user-checked-out one', () => {
|
||||
const md = fs.readFileSync(AGENT_PATH, 'utf-8');
|
||||
const invocations = parseWorktreeAddInvocations(md);
|
||||
|
||||
test('sanity: at least one git-worktree-add invocation exists in the agent definition', () => {
|
||||
assert.ok(invocations.length > 0,
|
||||
'expected gsd-code-fixer.md to document at least one git worktree add invocation');
|
||||
'expected msd-code-fixer.md to document at least one git worktree add invocation');
|
||||
});
|
||||
|
||||
test('every git-worktree-add invocation uses -b $reviewfix_branch (not bare $branch)', () => {
|
||||
@@ -1336,7 +1336,7 @@ describe('Bug #2990: gsd-code-fixer worktree attaches to a NEW branch, not the u
|
||||
});
|
||||
|
||||
/**
|
||||
* Bug #2647: gsd-code-fixer hand-rolled its worktree at a hardcoded `/tmp/sv-...`
|
||||
* Bug #2647: msd-code-fixer hand-rolled its worktree at a hardcoded `/tmp/sv-...`
|
||||
* mktemp path, which on Windows/Git Bash landed OUTSIDE the project tree —
|
||||
* outside the agent session's permission allowlist, so every Read inside the
|
||||
* worktree prompted — and mktemp's MAX_PATH-avoidance substitute produced an
|
||||
@@ -1350,7 +1350,7 @@ describe('Bug #2990: gsd-code-fixer worktree attaches to a NEW branch, not the u
|
||||
* and assert the path is repo-relative under `.claude/worktrees/`, never an
|
||||
* absolute `/tmp` path, and concurrency-unique.
|
||||
*/
|
||||
describe('Bug #2647: gsd-code-fixer worktree path is repo-relative, not a hardcoded /tmp path', () => {
|
||||
describe('Bug #2647: msd-code-fixer worktree path is repo-relative, not a hardcoded /tmp path', () => {
|
||||
const md = fs.readFileSync(AGENT_PATH, 'utf-8');
|
||||
|
||||
// Extract `wt=...` shell assignments from fenced bash blocks (skip inline
|
||||
@@ -1381,7 +1381,7 @@ describe('Bug #2647: gsd-code-fixer worktree path is repo-relative, not a hardco
|
||||
|
||||
test('the worktree path is NOT an absolute /tmp path', () => {
|
||||
const wtAssigns = parseWtAssignments(md);
|
||||
assert.ok(wtAssigns.length > 0, 'expected at least one wt= assignment in gsd-code-fixer.md');
|
||||
assert.ok(wtAssigns.length > 0, 'expected at least one wt= assignment in msd-code-fixer.md');
|
||||
const tmpViolations = wtAssigns.filter(v => /\/tmp\/sv-|mktemp -d "\/tmp\//.test(v));
|
||||
assert.deepEqual(
|
||||
tmpViolations,
|
||||
@@ -1392,7 +1392,7 @@ describe('Bug #2647: gsd-code-fixer worktree path is repo-relative, not a hardco
|
||||
|
||||
test('the worktree path is repo-relative under .claude/worktrees/', () => {
|
||||
const wtAssigns = parseWtAssignments(md);
|
||||
assert.ok(wtAssigns.length > 0, 'expected at least one wt= assignment in gsd-code-fixer.md');
|
||||
assert.ok(wtAssigns.length > 0, 'expected at least one wt= assignment in msd-code-fixer.md');
|
||||
const nonRelative = wtAssigns.filter(v => !v.includes('.claude/worktrees/rf-'));
|
||||
assert.deepEqual(
|
||||
nonRelative,
|
||||
@@ -1403,7 +1403,7 @@ describe('Bug #2647: gsd-code-fixer worktree path is repo-relative, not a hardco
|
||||
|
||||
test('the worktree path is concurrency-unique (PID + epoch suffix)', () => {
|
||||
const wtAssigns = parseWtAssignments(md);
|
||||
assert.ok(wtAssigns.length > 0, 'expected at least one wt= assignment in gsd-code-fixer.md');
|
||||
assert.ok(wtAssigns.length > 0, 'expected at least one wt= assignment in msd-code-fixer.md');
|
||||
// The path must carry BOTH a PID (`$$`) AND a time component (`$(date +%s)`)
|
||||
// so concurrent runs for the same phase do not collide — the property
|
||||
// mktemp's XXXXXX provided before #2647. Requiring both (not either) is
|
||||
@@ -1470,7 +1470,7 @@ describe('Bug #2990: cleanup tail fast-forwards $branch and deletes the temp bra
|
||||
const records = extractCleanupGitInvocations(md);
|
||||
|
||||
test('cleanup tail bash block exists and is parseable', () => {
|
||||
assert.notEqual(records, null, 'expected to find a "Cleanup tail" bash block in agents/gsd-code-fixer.md');
|
||||
assert.notEqual(records, null, 'expected to find a "Cleanup tail" bash block in agents/msd-code-fixer.md');
|
||||
assert.ok(records.length > 0, 'expected at least one git invocation in the cleanup tail');
|
||||
});
|
||||
|
||||
@@ -1552,7 +1552,7 @@ describe('Bug #2990 (#3001 CR): recovery code reads reviewfix_branch from sentin
|
||||
/**
|
||||
* Regression test for bug #2686
|
||||
*
|
||||
* The gsd-code-fixer agent (spawned by /gsd-code-review-fix) operated directly
|
||||
* The msd-code-fixer agent (spawned by /msd-code-review-fix) operated directly
|
||||
* against the main working tree. When it ran concurrently with a foreground
|
||||
* session both processes raced for HEAD, the index, and on-disk files. The
|
||||
* foreground session's next commit could land on the wrong branch (whichever
|
||||
@@ -1562,14 +1562,14 @@ describe('Bug #2990 (#3001 CR): recovery code reads reviewfix_branch from sentin
|
||||
* FIRST git operation, run ALL subsequent git operations inside that worktree
|
||||
* path, and call `git worktree remove` for cleanup when done.
|
||||
*
|
||||
* This mirrors the pattern already used by every other per-issue GSD agent at
|
||||
* This mirrors the pattern already used by every other per-issue MSD agent at
|
||||
* /private/tmp/sv-<n>.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
// allow-test-rule: source-text-is-the-product (see #2686)
|
||||
// The gsd-code-fixer agent's working instructions ARE the product — Claude
|
||||
// The msd-code-fixer agent's working instructions ARE the product — Claude
|
||||
// executes them literally at runtime. Testing the text content tests the
|
||||
// deployed contract: if the instruction is absent, the isolation guarantee
|
||||
// is absent.
|
||||
@@ -1583,8 +1583,8 @@ describe('bug-2686: review-fix agent worktree isolation', () => {
|
||||
let agentContent;
|
||||
|
||||
before(() => {
|
||||
const agentPath = path.join(__dirname, '..', 'agents', 'gsd-code-fixer.md');
|
||||
assert.ok(fs.existsSync(agentPath), 'agents/gsd-code-fixer.md must exist');
|
||||
const agentPath = path.join(__dirname, '..', 'agents', 'msd-code-fixer.md');
|
||||
assert.ok(fs.existsSync(agentPath), 'agents/msd-code-fixer.md must exist');
|
||||
agentContent = fs.readFileSync(agentPath, 'utf-8');
|
||||
});
|
||||
|
||||
@@ -1593,7 +1593,7 @@ describe('bug-2686: review-fix agent worktree isolation', () => {
|
||||
|
||||
assert.ok(
|
||||
worktreePos !== -1,
|
||||
'gsd-code-fixer.md must include a "git worktree add" instruction to isolate operations from the main working tree (#2686)'
|
||||
'msd-code-fixer.md must include a "git worktree add" instruction to isolate operations from the main working tree (#2686)'
|
||||
);
|
||||
|
||||
// `git checkout -- {file}` is a file-restore within the worktree — safe, not a branch switch.
|
||||
@@ -1609,8 +1609,8 @@ describe('bug-2686: review-fix agent worktree isolation', () => {
|
||||
}
|
||||
|
||||
// commit command must come after worktree setup — the fixer may use
|
||||
// either `git commit` directly or `gsd-sdk query commit`
|
||||
const commitMatch = /(?:git commit|gsd-sdk query commit)/.exec(agentContent);
|
||||
// either `git commit` directly or `msd-sdk query commit`
|
||||
const commitMatch = /(?:git commit|msd-sdk query commit)/.exec(agentContent);
|
||||
if (commitMatch) {
|
||||
const commitPos = commitMatch.index;
|
||||
assert.ok(
|
||||
@@ -1623,13 +1623,13 @@ describe('bug-2686: review-fix agent worktree isolation', () => {
|
||||
test('agent instructions include worktree cleanup after completion', () => {
|
||||
assert.ok(
|
||||
agentContent.includes('git worktree remove') || agentContent.includes('worktree remove'),
|
||||
'gsd-code-fixer.md must include worktree cleanup (git worktree remove) to avoid leaking tmp directories (#2686)'
|
||||
'msd-code-fixer.md must include worktree cleanup (git worktree remove) to avoid leaking tmp directories (#2686)'
|
||||
);
|
||||
});
|
||||
|
||||
test('agent instructions use a repo-relative worktree path under .claude/worktrees/ (not a hardcoded /tmp path)', () => {
|
||||
// #2647: the original #2686 fix placed the worktree at a hardcoded `/tmp/sv-`
|
||||
// mktemp path to match sibling GSD agents. On Windows/Git Bash that landed
|
||||
// mktemp path to match sibling MSD agents. On Windows/Git Bash that landed
|
||||
// OUTSIDE the project tree — outside the agent session's permission allowlist,
|
||||
// so every Read inside the worktree prompted — and mktemp's MAX_PATH-avoidance
|
||||
// substitute produced an un-removable `C:/mvwtNN` path. The worktree must now
|
||||
@@ -1641,11 +1641,11 @@ describe('bug-2686: review-fix agent worktree isolation', () => {
|
||||
/\bwt\s*=\s*["']?\/tmp\/sv-/.test(agentContent);
|
||||
assert.ok(
|
||||
!hasTmpWorktreePath,
|
||||
'gsd-code-fixer.md must NOT define a worktree variable at a /tmp/sv-... path (#2647 — use a repo-relative .claude/worktrees/ path instead)'
|
||||
'msd-code-fixer.md must NOT define a worktree variable at a /tmp/sv-... path (#2647 — use a repo-relative .claude/worktrees/ path instead)'
|
||||
);
|
||||
assert.ok(
|
||||
/\.claude\/worktrees\//.test(agentContent),
|
||||
'gsd-code-fixer.md must define the worktree under .claude/worktrees/ (repo-relative, gitignored, inside the permission scope) (#2647)'
|
||||
'msd-code-fixer.md must define the worktree under .claude/worktrees/ (repo-relative, gitignored, inside the permission scope) (#2647)'
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1660,11 +1660,11 @@ describe('bug-2686: review-fix agent worktree isolation', () => {
|
||||
const { describe: __foldDescribe } = require('node:test');
|
||||
__foldDescribe("folded:enh-2500-codebase-mapper-arch-rich-format (consolidation epic #1969 B7 #1976)", () => {
|
||||
/**
|
||||
* Enhancement #2500: gsd-codebase-mapper (arch focus) rich architecture output
|
||||
* Enhancement #2500: msd-codebase-mapper (arch focus) rich architecture output
|
||||
*
|
||||
* The codebase/ARCHITECTURE.md produced by gsd-codebase-mapper was a sparse
|
||||
* The codebase/ARCHITECTURE.md produced by msd-codebase-mapper was a sparse
|
||||
* structural inventory — file listings and module relationships. After a major
|
||||
* refactor, research/ARCHITECTURE.md (created at /gsd-new-project) goes stale
|
||||
* refactor, research/ARCHITECTURE.md (created at /msd-new-project) goes stale
|
||||
* with no refresh command. This enhancement enriches the codebase mapper's
|
||||
* arch-focus template to match the richness of the research version:
|
||||
* - ASCII system overview diagram
|
||||
@@ -1681,7 +1681,7 @@ describe('bug-2686: review-fix agent worktree isolation', () => {
|
||||
'use strict';
|
||||
|
||||
// allow-test-rule: source-text-is-the-product (see #2500)
|
||||
// The gsd-codebase-mapper ARCHITECTURE.md template is the instruction set
|
||||
// The msd-codebase-mapper ARCHITECTURE.md template is the instruction set
|
||||
// executed by the LLM at runtime. Testing its text content tests whether the
|
||||
// deployed agent will produce rich architecture docs as required by #2500.
|
||||
|
||||
@@ -1690,14 +1690,14 @@ const assert = require('node:assert/strict');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const AGENT_PATH = path.join(__dirname, '..', 'agents', 'gsd-codebase-mapper.md');
|
||||
const AGENT_PATH = path.join(__dirname, '..', 'agents', 'msd-codebase-mapper.md');
|
||||
|
||||
describe('enh-2500: gsd-codebase-mapper arch focus — rich architecture output', () => {
|
||||
describe('enh-2500: msd-codebase-mapper arch focus — rich architecture output', () => {
|
||||
let agentContent;
|
||||
let archTemplate;
|
||||
|
||||
before(() => {
|
||||
assert.ok(fs.existsSync(AGENT_PATH), 'agents/gsd-codebase-mapper.md must exist');
|
||||
assert.ok(fs.existsSync(AGENT_PATH), 'agents/msd-codebase-mapper.md must exist');
|
||||
agentContent = fs.readFileSync(AGENT_PATH, 'utf-8');
|
||||
|
||||
// Isolate the ARCHITECTURE.md template section from the agent file.
|
||||
|
||||
Reference in New Issue
Block a user