Files
msd-core/tests/code-review-agent-skills.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

71 lines
3.4 KiB
JavaScript

// allow-test-rule: source-text-is-the-product
// The agent_skills injection for the review-family workflows lives as text in
// the workflow .md files — that text IS what the orchestrating runtime loads
// and executes. There is no intermediate runtime that parses these workflows
// into a prompt we could assert on structurally, so the deployed contract is
// the workflow text itself.
//
// Regression guard for #991: code-review.md / code-review-fix.md /
// eval-review.md were the lone outliers among ~20 workflows that never
// injected the project-configured agent_skills into the subagents they spawn.
// Subagents do not inherit the orchestrator's auto-loaded context, so this
// injection is the ONLY channel for reviewer/fixer/auditor rule context.
const { test, describe } = require('node:test');
const assert = require('node:assert/strict');
const fs = require('fs');
const path = require('path');
const { escapeRegex: escapeRe } = require('../msd-core/bin/lib/pattern.cjs');
const WORKFLOWS_DIR = path.join(__dirname, '..', 'msd-core', 'workflows');
// Workflow file -> EVERY subagent type it spawns and must inject skills for.
// A workflow can spawn more than one agent type: code-review-fix.md spawns the
// fixer (twice) AND re-spawns the reviewer in its --auto loop, so it must
// inject skills for BOTH. Listing every spawned type here is what catches a
// partially-fixed workflow (the gap Codex flagged on the first pass at #991).
const REVIEW_FAMILY = [
{ file: 'code-review.md', agentTypes: ['msd-code-reviewer'] },
{ file: 'code-review-fix.md', agentTypes: ['msd-code-fixer', 'msd-code-reviewer'] },
{ file: 'eval-review.md', agentTypes: ['msd-eval-auditor'] },
];
const cases = REVIEW_FAMILY.flatMap(({ file, agentTypes }) =>
agentTypes.map((agentType) => ({ file, agentType })),
);
describe('agent_skills injection — review-family workflows (#991)', () => {
for (const { file, agentType } of cases) {
test(`${file} queries + injects agent_skills for every ${agentType} spawn`, () => {
const content = fs.readFileSync(path.join(WORKFLOWS_DIR, file), 'utf8');
// 1. Must query the project-configured skills for this agent type, using
// the same `msd_run query agent-skills <type>` idiom as the ~20
// sibling workflows (plan-phase, execute-phase, secure-phase, ...).
const assignRe = new RegExp(
'([A-Z][A-Z0-9_]*)=\\$\\(\\s*msd_run query agent-skills ' + escapeRe(agentType) + '\\s*\\)',
);
const m = content.match(assignRe);
assert.ok(
m,
`${file}: missing \`VAR=$(msd_run query agent-skills ${agentType})\` — configured agent_skills are never queried (#991)`,
);
const varName = m[1];
// 2. The queried block must be interpolated into the spawn prompt for
// EVERY spawn of this agent type. code-review-fix.md spawns the fixer
// twice (initial + auto-iteration re-spawn); both must inject, or a
// spawn runs under-equipped.
const interpolations = content.split('${' + varName + '}').length - 1;
const spawnCount = (
content.match(new RegExp('subagent_type=["\']' + escapeRe(agentType) + '["\']', 'g')) || []
).length;
assert.ok(
interpolations >= Math.max(1, spawnCount),
`${file}: \${${varName}} is interpolated ${interpolations}x but ${agentType} is spawned ${spawnCount}x — every spawn must inject the skills block (#991)`,
);
});
}
});