Files
brain/tools/m2-supreme-invariants.test.mjs
T

32 lines
1.8 KiB
JavaScript

// tools/m2-supreme-invariants.test.mjs
import { describe, it, expect } from 'vitest';
import { freezePlan, verifyFrozenPlan } from './plan-lock.mjs';
import { decide, isSeed } from './enforce-supreme-gate.mjs';
const KEY = 'm2-key';
const steps = [{ n: 1, op: 'Write', object: 'tools/foo.mjs', intent: 'i' }];
describe('Машина 2 — инварианты стены', () => {
it('без замороженного плана любое мутирующее действие блокируется', () => {
const r = decide({ toolUse: { name: 'Write', input: { file_path: 'tools/foo.mjs' } }, frozenPlan: null, key: KEY });
expect(r.decision).toBe('block');
});
it('подмена шага в плане ломает печать → блок', () => {
const p = freezePlan({ steps, key: KEY, nowMs: 1 });
const tampered = { ...p, steps: [{ ...p.steps[0], object: 'tools/evil.mjs' }] };
expect(verifyFrozenPlan(tampered, KEY)).toBe(false);
const r = decide({ toolUse: { name: 'Write', input: { file_path: 'tools/evil.mjs' } }, frozenPlan: tampered, key: KEY });
expect(r.decision).toBe('block');
});
it('семя загрузки проходит без плана (стену можно построить)', () => {
expect(isSeed({ name: 'Skill', input: { skill: 'writing-plans' } })).toBe(true);
const r = decide({ toolUse: { name: 'Skill', input: { skill: 'writing-plans' } }, frozenPlan: null, key: KEY });
expect(r.decision).toBe('allow');
});
it('действие строго по шагу валидного плана проходит', () => {
const p = freezePlan({ steps, key: KEY, nowMs: 1 });
const r = decide({ toolUse: { name: 'Write', input: { file_path: 'tools/foo.mjs' } }, frozenPlan: p, key: KEY });
expect(r.decision).toBe('allow');
});
});