b739d5adad
Болезни B (роутер в пустоту) + A (наставник не заворачивал) — лечение Р7/Р8 (Подход 1): наставник — единый мозг-рецензент, зовёт classify() как функцию (3 слоя + граф nodes.yaml + карточки — код не тронут, новый вызыватель), судит спеку+план+выбор скилов, заворачивает NO-GO. - validateMentorVerdict + промпты (план/спека): явное decision GO|NO-GO (поглощённый Р7) - plan-skills.mjs: parsePlanSkills (skills-json) + extractPlanGoal (зеркало extractGoal судьи) - mentor-seam: renderSkillContext; onPlanWrite зовёт classifyImpl (fail-safe: сбой → без скил-сверки) - decideMentorObjection: заворот на decision=NO-GO ИЛИ сломанный вердикт; mentor-GO только на чистом GO - formatMentorObjection доносит суть (recommendation + reasoning + plan_points), GO -> пусто - enforce-mentor main: loadRegistry + classify; счётчик L1 decision-aware (Р7/§3.4) - скил-сверка — только план (gate2); спека (gate1) — по сути + decision - включает redesign согласования L1->L2 (Фазы 0-6, способ B: наставник->судья->печать) - регрессия tools-only 3901 passed + 2 skip (база 3877, +24 теста, 0 регрессий) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
28 lines
1.9 KiB
JavaScript
28 lines
1.9 KiB
JavaScript
import { describe, it, expect } from 'vitest';
|
|
import { isAuthoringWrite, decideMode } from './enforce-supreme-gate.mjs';
|
|
|
|
const newFile = { existsImpl: () => false }; // файла ещё нет на диске
|
|
|
|
describe('M7 Ф8 bootstrap-карвут: авторская запись нового плана/спеки', () => {
|
|
it('Write нового .md в specs/ или plans/ → true', () => {
|
|
expect(isAuthoringWrite({ name: 'Write', input: { file_path: 'docs/superpowers/specs/2026-06-12-x.md' } }, newFile)).toBe(true);
|
|
expect(isAuthoringWrite({ name: 'Write', input: { file_path: 'docs/superpowers/plans/2026-06-12-x.md' } }, newFile)).toBe(true);
|
|
});
|
|
it('перезапись существующего файла → false', () => {
|
|
expect(isAuthoringWrite({ name: 'Write', input: { file_path: 'docs/superpowers/plans/x.md' } }, { existsImpl: () => true })).toBe(false);
|
|
});
|
|
it('код / чужой путь / не-Write → false', () => {
|
|
expect(isAuthoringWrite({ name: 'Write', input: { file_path: 'tools/enforce-supreme-gate.mjs' } }, newFile)).toBe(false);
|
|
expect(isAuthoringWrite({ name: 'Write', input: { file_path: 'app/Foo.php' } }, newFile)).toBe(false);
|
|
expect(isAuthoringWrite({ name: 'Edit', input: { file_path: 'docs/superpowers/plans/x.md' } }, newFile)).toBe(false);
|
|
});
|
|
it('decideMode без плана + авторская запись нового файла → allow', () => {
|
|
const r = decideMode({ toolUse: { name: 'Write', input: { file_path: 'docs/superpowers/plans/__nonexistent_bootstrap_test__.md' } }, frozenPlan: null, key: 'k' });
|
|
expect(r.decision).toBe('allow');
|
|
});
|
|
it('decideMode без плана + запись в код → по-прежнему block (регрессия)', () => {
|
|
const r = decideMode({ toolUse: { name: 'Write', input: { file_path: 'app/Foo.php' } }, frozenPlan: null, key: 'k' });
|
|
expect(r.decision).toBe('block');
|
|
});
|
|
});
|