import assert from 'node:assert/strict'; import test from 'node:test'; import { loadScenarioCatalog } from './catalog.mjs'; import { CORE_SCENARIO_IDS, selectImpactScenarios } from './impact.mjs'; test('docs-only changes use the compact core gate', async () => { const catalog = await loadScenarioCatalog(); const selection = selectImpactScenarios({ catalog, changedPaths: ['AGENTS.md', 'docs/local-dev.md'], }); assert.equal(selection.strategy, 'core'); assert.deepEqual(selection.selected_ids, catalog .map((scenario) => scenario.id) .filter((id) => CORE_SCENARIO_IDS.includes(id))); assert.equal(selection.unmapped_paths.length, 0); }); test('domain changes select the domain and dependency closure', async () => { const catalog = await loadScenarioCatalog(); const selection = selectImpactScenarios({ catalog, changedPaths: ['memory-v2-lifecycle.mjs'], }); assert.equal(selection.strategy, 'impact'); assert.deepEqual(selection.impact_groups, ['CHAT', 'MEM']); assert.equal(selection.selected_ids.includes('MEM-16'), true); assert.equal(selection.selected_ids.includes('CHAT-15'), true); assert.equal(selection.selected_ids.includes('BILL-07'), false); }); test('critical and unmapped runtime paths fail closed to the full gate', async () => { const catalog = await loadScenarioCatalog(); const critical = selectImpactScenarios({ catalog, changedPaths: ['server.mjs'], }); assert.equal(critical.strategy, 'full'); assert.equal(critical.selected_total, catalog.length); assert.deepEqual(critical.full_gate_reasons, ['critical_path:server.mjs']); const unknown = selectImpactScenarios({ catalog, changedPaths: ['new-runtime-kernel.mjs'], }); assert.equal(unknown.strategy, 'full'); assert.deepEqual(unknown.unmapped_paths, ['new-runtime-kernel.mjs']); assert.equal(unknown.selected_total, catalog.length); });