import { describe, it, expect, beforeAll } from 'vitest'; import { pool } from '../../lib/db/pool.js'; import { resetDb } from '../helpers/db.js'; import { migrateUp } from '../../lib/db/migrate.js'; import { listMcpTools, callMcpTool } from '../../lib/mcp/companion-stdio.js'; // The stdio MCP server must be able to expose Yerin's securityRegistry instead // of Dross's companionRegistry, selected by VOID_TOOL_REGISTRY at launch. describe('MCP registry selection', () => { it('defaults to the companion registry when VOID_TOOL_REGISTRY is unset', () => { const names = listMcpTools({}).map(t => t.name).sort(); expect(names).toEqual(['context', 'propose_change', 'read', 'search']); }); it('selects the security registry when VOID_TOOL_REGISTRY=security', () => { const names = listMcpTools({ VOID_TOOL_REGISTRY: 'security' }).map(t => t.name).sort(); expect(names).toContain('audit_log'); expect(names).toContain('agent_inventory'); expect(names).not.toContain('propose_change'); // Yerin cannot propose mutations }); it('callMcpTool routes to the selected registry', async () => { await resetDb(); await migrateUp(); const out = await callMcpTool('agent_inventory', {}, {}, { VOID_TOOL_REGISTRY: 'security' }); expect(Array.isArray(out.agents)).toBe(true); // an unknown tool for the default registry must not be reachable in security mode await expect(callMcpTool('propose_change', {}, {}, { VOID_TOOL_REGISTRY: 'security' })) .rejects.toThrow(/unknown tool/i); }); }); describe('migration 011 seeds Yerin', () => { it('creates a read-only yerin agent', async () => { await resetDb(); await migrateUp(); const { rows: [y] } = await pool.query(`SELECT * FROM agents WHERE slug='yerin'`); expect(y).toBeTruthy(); expect(y.capabilities).toEqual({ read: true, suggest: false, write: false }); }); });