// tools/mentor-gate-config.test.mjs import { describe, it, expect } from 'vitest'; import { mentorSeamActive, resolveMentorLlmKey, repoRootOf, _internals } from './mentor-gate-config.mjs'; // «Оба строго» (решение владельца 2026-06-12): наставник ест ТОЛЬКО со своего // ROUTER_MENTOR_LLM_KEY — общий ROUTER_LLM_KEY НЕ активирует и НЕ подхватывается. describe('строгий ключ наставника (ROUTER_MENTOR_LLM_KEY)', () => { it('флаг=1 + СВОЙ ключ → активен; общий ROUTER_LLM_KEY НЕ активирует', () => { expect(mentorSeamActive({ env: { ROUTER_MENTOR_SEAM_ENABLED: '1', ROUTER_MENTOR_LLM_KEY: 'mk' } })).toBe(true); expect(mentorSeamActive({ env: { ROUTER_MENTOR_SEAM_ENABLED: '1', ROUTER_LLM_KEY: 'common' } })).toBe(false); }); it('resolveMentorLlmKey: строго свой, общий не фолбэк, нет → null', () => { expect(resolveMentorLlmKey({ env: { ROUTER_MENTOR_LLM_KEY: 'mk', ROUTER_LLM_KEY: 'common' } })).toBe('mk'); expect(resolveMentorLlmKey({ env: { ROUTER_LLM_KEY: 'common' } })).toBe(null); expect(resolveMentorLlmKey({ env: {} })).toBe(null); }); }); // W-2 (sharp-edges 2026-06-12): корень репо для C-3-резолва цитат в gate — из события // хука (event.cwd), НЕ слепо process.cwd() (утверждение «cwd хука = корень» не закреплено). describe('repoRootOf (W-2: корень репо для C-3)', () => { it('event.cwd побеждает; мусор/отсутствие → фолбэк process.cwd()', () => { expect(repoRootOf({ cwd: '/repo/root' })).toBe('/repo/root'); expect(repoRootOf({})).toBe(process.cwd()); expect(repoRootOf(null)).toBe(process.cwd()); expect(repoRootOf({ cwd: '' })).toBe(process.cwd()); expect(repoRootOf({ cwd: 42 })).toBe(process.cwd()); }); }); describe('mentor-gate-config (рубильник SEAM, «оба строго» 2026-06-12)', () => { it('флаг=1 + СВОЙ ключ ROUTER_MENTOR_LLM_KEY → активен', () => { expect(mentorSeamActive({ env: { ROUTER_MENTOR_SEAM_ENABLED: '1', ROUTER_MENTOR_LLM_KEY: 'mk' } })).toBe(true); }); it('нет флага / флаг не "1" / нет ключа → inert (по одному условию)', () => { expect(mentorSeamActive({ env: { ROUTER_MENTOR_LLM_KEY: 'mk' } })).toBe(false); expect(mentorSeamActive({ env: { ROUTER_MENTOR_SEAM_ENABLED: 'true', ROUTER_MENTOR_LLM_KEY: 'mk' } })).toBe(false); expect(mentorSeamActive({ env: { ROUTER_MENTOR_SEAM_ENABLED: '1' } })).toBe(false); expect(mentorSeamActive({ env: {} })).toBe(false); }); it('имя флага не пересекается с судейским ROUTER_MENTOR_JUDGE_ENABLED', () => { expect(_internals.ENABLED_ENV).toBe('ROUTER_MENTOR_SEAM_ENABLED'); expect(mentorSeamActive({ env: { ROUTER_MENTOR_JUDGE_ENABLED: '1', ROUTER_LLM_KEY: 'k' } })).toBe(false); }); }); // T3 (решение владельца 2026-06-12): единый источник «что есть план» для судьи и // наставника — PLAN_PATH_RE экспортируется из enforce-judge-gate. Импорт внизу перед // describe (ESM hoisting). import { PLAN_PATH_RE } from './enforce-judge-gate.mjs'; describe('PLAN_PATH_RE — единый источник «что есть план»', () => { it('матчит docs/superpowers/plans/*.md и НЕ матчит specs', () => { expect(PLAN_PATH_RE.test('docs/superpowers/plans/2026-06-12-x.md')).toBe(true); expect(PLAN_PATH_RE.test('docs\\superpowers\\plans\\x.md')).toBe(true); expect(PLAN_PATH_RE.test('docs/superpowers/specs/x.md')).toBe(false); }); });