Files
msd-core/tests/agent-marker-documentation-guard.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

150 lines
5.8 KiB
JavaScript

// docs-guard-exempt: docs/reference/workflow-fragments.md is cited only in a comment as a prior example; this file reads agents/*.md, never docs/.
'use strict';
// allow-test-rule: source-text-is-the-product see #2995 — parses the literal text of shipped
// agent .md files, which IS the deployed contract that composeWorkflow consumes at install time.
/**
* agent-marker-documentation-guard.test.cjs — 50-test-matrix.md rows 11 and 12
* (issue #2995, epic #1671 Phase 6.4).
*
* #2930 scoped `composeWorkflow` to `msd-core/workflows/` for one specific
* reason: a document that merely DOCUMENTS the marker syntax with an UNFENCED
* example is indistinguishable from a real marker, so the composer would treat
* it as one and drop that line from the emitted artifact. `docs/reference/
* workflow-fragments.md` was named as the live instance of that class.
*
* #2995 widens the composed scope to `agents/`, which makes the class reachable
* for agent files for the first time. These two rows are the guard.
*/
const { test } = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const { parseWorkflowSections, composeWorkflow } = require('../msd-core/bin/lib/workflow-fragments.cjs');
const AGENTS_DIR = path.join(__dirname, '..', 'agents');
// ─── Row 11: a FENCED marker example is literal, not a marker ─────────────────
test('row 11 — a fenced marker example in an agent survives composition verbatim', () => {
const doc = [
'---',
'name: msd-example',
'---',
'',
'# Example agent',
'',
'To gate a section, write:',
'',
'```markdown',
'<!-- msd:section id="demo" when="always" -->',
'body',
'<!-- /msd:section -->',
'```',
'',
'That is the whole grammar.',
'',
].join('\n');
const sections = parseWorkflowSections(doc, 'agents/msd-example.md');
assert.deepStrictEqual(
sections.filter((s) => s.explicit).map((s) => s.id),
[],
'a fenced example must produce NO explicit section — it is documentation, not a marker',
);
const composed = composeWorkflow(doc, { sourcePath: 'agents/msd-example.md' });
assert.equal(
composed,
doc,
'a document whose only marker-shaped lines are fenced must compose byte-identically',
);
});
// ─── Row 12: no shipped agent carries a marker-shaped line outside a fence ────
//
// This is the guard that makes row 11's protection load-bearing. If someone adds
// an UNFENCED marker example to an agent as documentation, the composer parses it
// as a real marker and silently swallows the line at emit. Parsing every shipped
// agent and requiring zero EXPLICIT sections catches that at test time instead of
// in a user's installed tree.
//
// It is deliberately an equality-to-empty assertion rather than a count: when the
// per-agent manifest family that would make agent gating admissible eventually
// lands, this test must be revisited on purpose, not silently satisfied.
test('row 12 — no shipped agent carries an unfenced msd:section marker', () => {
const offenders = [];
for (const name of fs.readdirSync(AGENTS_DIR).sort()) {
if (!name.endsWith('.md')) continue;
const rel = path.posix.join('agents', name);
const content = fs.readFileSync(path.join(AGENTS_DIR, name), 'utf8');
const explicit = parseWorkflowSections(content, rel).filter((s) => s.explicit);
if (explicit.length > 0) offenders.push(`${rel}: ${explicit.map((s) => s.id).join(', ')}`);
}
assert.deepStrictEqual(
offenders,
[],
'An agent carries a msd:section marker outside a fence. If it is DOCUMENTATION, fence it — ' +
'the composer cannot tell an unfenced example from a real marker and will drop the line ' +
'from the emitted agent. If it is meant as real gating, it will not work: ' +
'gen-section-manifest.cjs scans only msd-core/workflows/, so an agent atom has no consumer ' +
'and evaluates false forever (see ADR-1671, "the grammar does NOT extend to agents/").\n' +
`Offenders:\n ${offenders.join('\n ')}`,
);
});
// ─── Row 12b: the guard is not vacuous — a whole-line unfenced marker IS a marker ──
//
// Refined by a real failure: the grammar is WHOLE-LINE only. An open marker placed
// INLINE inside a sentence is NOT recognised as an open — so the hazard row 12
// guards against is specifically an unfenced marker on its OWN line, which is
// exactly how a documentation example is normally written.
test('row 12b — a whole-line unfenced marker in agent prose is detected as a real marker', () => {
const doc = [
'---',
'name: msd-example',
'---',
'',
'To open a section, write:',
'',
'<!-- msd:section id="demo" when="always" -->',
'body',
'<!-- /msd:section -->',
'',
].join('\n');
const explicit = parseWorkflowSections(doc, 'agents/msd-example.md').filter((s) => s.explicit);
assert.deepStrictEqual(
explicit.map((s) => s.id),
['demo'],
'a whole-line UNFENCED marker must parse as a real marker — this is precisely why row 12 ' +
'exists; if this assertion ever fails, row 12 is guarding against nothing',
);
});
// ─── Row 12c: an INLINE marker-shaped span is not a marker ───────────────────
test('row 12c — an inline marker-shaped span mid-sentence is not treated as an open marker', () => {
const doc = [
'---',
'name: msd-example',
'---',
'',
'Write <!-- msd:section id="demo" when="always" --> to open a section.',
'',
].join('\n');
const explicit = parseWorkflowSections(doc, 'agents/msd-example.md').filter((s) => s.explicit);
assert.deepStrictEqual(
explicit.map((s) => s.id),
[],
'an inline marker-shaped span is prose, not a marker — the grammar is whole-line only',
);
});