diff --git a/tests/lib/agent-frontmatter.test.mjs b/tests/lib/agent-frontmatter.test.mjs index 9132f40..5340f9e 100644 --- a/tests/lib/agent-frontmatter.test.mjs +++ b/tests/lib/agent-frontmatter.test.mjs @@ -127,3 +127,39 @@ test('non-orchestrator agents do NOT include the Agent tool (no recursive swarmi ); } }); + +// M4 (v5.7.1): examples-relocation invariant. The 34 blocks belong in +// agent BODIES, not in the always-loaded `description:` frontmatter (voyage +// launches its agents by name, so the auto-selection examples are cost without +// function there). This pins the migration: examples cannot regress into +// frontmatter, and cannot be silently lost during the move. +function bodyOf(text) { + // Slice the file content AFTER the closing frontmatter `---`. + // Do NOT split on /^---$/m — a horizontal rule in the body would mis-split. + const m = text.match(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/); + return m ? text.slice(m[0].length) : text; +} + +test('no agents/*.md frontmatter contains an block (M4: examples live in the body)', () => { + for (const f of agentFiles) { + const fm = extractFrontmatter(read(`agents/${f}`)); + assert.ok(fm !== null, `agents/${f}: missing frontmatter`); + assert.equal( + (fm.match(//g) || []).length, + 0, + `agents/${f}: blocks must live in the body, not the always-loaded description: frontmatter (M4)`, + ); + } +}); + +test('agent bodies retain at least 34 blocks (M4: relocation moves, never deletes)', () => { + let total = 0; + for (const f of agentFiles) { + total += (bodyOf(read(`agents/${f}`)).match(//g) || []).length; + } + assert.ok( + total >= 34, + `expected >= 34 blocks across agent bodies (17 agents x 2), got ${total} ` + + `— examples may have been deleted instead of relocated (M4)`, + ); +});