import { describe, it, expect } from 'vitest'; import { decide } from './enforce-coverage-verify.mjs'; describe('enforce-coverage-verify / decide', () => { it('allows turn with no mutating tools (pure conversational)', () => { const r = decide({ toolUses: [{ name: 'Read', input: {} }], assistantText: 'just talking' }); expect(r.block).toBe(false); }); it('blocks mutating turn with no coverage line', () => { const r = decide({ toolUses: [{ name: 'Edit', input: { file_path: 'foo.mjs' } }], assistantText: 'just did some work', }); expect(r.block).toBe(true); expect(r.message).toMatch(/no.*coverage/); }); it('blocks when coverage says skill but Skill tool not invoked', () => { const r = decide({ toolUses: [{ name: 'Edit', input: { file_path: 'foo.mjs' } }], assistantText: 'coverage: skill:superpowers:test-driven-development\nдалее…', }); expect(r.block).toBe(true); expect(r.message).toMatch(/Skill tool was never invoked/); }); it('allows when coverage says skill and Skill tool invoked with matching name', () => { const r = decide({ toolUses: [ { name: 'Skill', input: { skill: 'superpowers:test-driven-development' } }, { name: 'Edit', input: { file_path: 'foo.mjs' } }, ], assistantText: 'coverage: skill:superpowers:test-driven-development\nок', }); expect(r.block).toBe(false); }); it('allows when coverage matches without superpowers: prefix in tool input', () => { const r = decide({ toolUses: [ { name: 'Skill', input: { skill: 'test-driven-development' } }, { name: 'Edit', input: { file_path: 'foo.mjs' } }, ], assistantText: 'coverage: skill:superpowers:test-driven-development', }); expect(r.block).toBe(false); }); it('allows direct coverage', () => { const r = decide({ toolUses: [{ name: 'Edit', input: { file_path: 'memory/foo.md' } }], assistantText: 'coverage: direct:memory-sync', }); expect(r.block).toBe(false); }); it('allows node coverage', () => { const r = decide({ toolUses: [{ name: 'Edit', input: { file_path: 'foo.vue' } }], assistantText: 'coverage: node:#19', }); expect(r.block).toBe(false); }); it('allows when override phrase present', () => { const r = decide({ toolUses: [{ name: 'Edit', input: { file_path: 'foo.mjs' } }], assistantText: 'no coverage', override: { phrase: 'без скилов', suppresses: ['coverage-skill-match'] }, }); expect(r.block).toBe(false); }); });