import { describe, it, expect } from 'vitest'; import { commitGrantOpenForSession } from './commit-grant.mjs'; import { freezePlan } from './plan-lock.mjs'; import { classifyGitCommand } from './shell-content-rules.mjs'; describe('D2 критерий §5 — канал коммита под ревью (сквозной)', () => { const K = 'k-d2e2e'; const plan = freezePlan({ steps: [{ op: 'Write', object: 'tools/x.mjs' }], judgeMode: 'live-block', key: K, nowMs: 1 }); it('опечатанный план + commit: → git commit allow', () => { const open = commitGrantOpenForSession('S', { loadGrantsImpl: () => [{ action: `commit:${plan.plan_id}`, ts: 1 }], loadPlanImpl: () => plan, keyImpl: () => K, verifyImpl: () => true }); expect(open).toBe(true); expect(classifyGitCommand('git commit -m x', { commitGrantOpen: open }).result).toBe('allow'); }); it('грант на ЧУЖОЙ хеш → git commit block (default-deny держит)', () => { const open = commitGrantOpenForSession('S', { loadGrantsImpl: () => [{ action: 'commit:OTHER', ts: 1 }], loadPlanImpl: () => plan, keyImpl: () => K, verifyImpl: () => true }); expect(open).toBe(false); expect(classifyGitCommand('git commit -m x', { commitGrantOpen: open }).result).toBe('block'); }); it('force-push блокируется даже под открытым commit-грантом (качество держит)', () => { const open = commitGrantOpenForSession('S', { loadGrantsImpl: () => [{ action: `commit:${plan.plan_id}`, ts: 1 }], loadPlanImpl: () => plan, keyImpl: () => K, verifyImpl: () => true }); expect(classifyGitCommand('git push --force', { commitGrantOpen: open }).result).toBe('block'); }); }); describe('commitGrantOpenForSession (D2 — gated: нет гранта → план не грузим)', () => { const K = 'k-cg'; it('нет commit-грантов → false, план НЕ грузится', () => { let planLoaded = false; const r = commitGrantOpenForSession('S', { loadGrantsImpl: () => [], loadPlanImpl: () => { planLoaded = true; return null; }, keyImpl: () => K, verifyImpl: () => true }); expect(r).toBe(false); expect(planLoaded).toBe(false); }); it('грант на хеш + sealed live-block план → true', () => { const plan = freezePlan({ steps: [{ op: 'Write', object: 'a.mjs' }], judgeMode: 'live-block', key: K, nowMs: 1 }); const r = commitGrantOpenForSession('S', { loadGrantsImpl: () => [{ action: `commit:${plan.plan_id}`, ts: 1 }], loadPlanImpl: () => plan, keyImpl: () => K, verifyImpl: () => true }); expect(r).toBe(true); }); it('грант на ЧУЖОЙ хеш → false', () => { const plan = freezePlan({ steps: [{ op: 'Write', object: 'a.mjs' }], judgeMode: 'live-block', key: K, nowMs: 1 }); expect(commitGrantOpenForSession('S', { loadGrantsImpl: () => [{ action: 'commit:OTHER', ts: 1 }], loadPlanImpl: () => plan, keyImpl: () => K, verifyImpl: () => true })).toBe(false); }); it('judge_mode не live-block → false', () => { const plan = freezePlan({ steps: [{ op: 'Write', object: 'a.mjs' }], judgeMode: 'shadow', key: K, nowMs: 1 }); expect(commitGrantOpenForSession('S', { loadGrantsImpl: () => [{ action: `commit:${plan.plan_id}`, ts: 1 }], loadPlanImpl: () => plan, keyImpl: () => K, verifyImpl: () => true })).toBe(false); }); it('печать невалидна (verifyImpl→false) → false', () => { const plan = freezePlan({ steps: [{ op: 'Write', object: 'a.mjs' }], judgeMode: 'live-block', key: K, nowMs: 1 }); expect(commitGrantOpenForSession('S', { loadGrantsImpl: () => [{ action: `commit:${plan.plan_id}`, ts: 1 }], loadPlanImpl: () => plan, keyImpl: () => K, verifyImpl: () => false })).toBe(false); }); it('нет плана → false', () => { expect(commitGrantOpenForSession('S', { loadGrantsImpl: () => [{ action: 'commit:x', ts: 1 }], loadPlanImpl: () => null, keyImpl: () => K, verifyImpl: () => true })).toBe(false); }); });