import { describe, it, expect } from 'vitest'; import { buildSealEntry } from './seal-log.mjs'; describe('buildSealEntry — наблюдаемость попыток печати (M7 seal observability)', () => { it('судья no-op (не активен) → kind seal_attempt, judge_active:false, sealed:false, reason', () => { const e = buildSealEntry({ functionName: 'gate1', judgeActive: false }); expect(e.kind).toBe('seal_attempt'); expect(e.judge_active).toBe(false); expect(e.wired).toBe(false); expect(e.seal_attempted).toBe(false); expect(e.sealed).toBe(false); expect(typeof e.reason).toBe('string'); }); it('вердикт не wired (degraded/unavailable) → seal_attempted:false, reason про wired', () => { const e = buildSealEntry({ functionName: 'gate2', judgeActive: true, wired: false, decision: 'GO' }); expect(e.judge_active).toBe(true); expect(e.wired).toBe(false); expect(e.decision).toBe('GO'); expect(e.seal_attempted).toBe(false); expect(e.sealed).toBe(false); expect(e.reason).toMatch(/wired/i); }); it('wired GO + печать встала → seal_attempted:true, sealed:true', () => { const e = buildSealEntry({ functionName: 'gate1', judgeActive: true, wired: true, decision: 'GO', sealResult: { sealed: true, kind: 'artifact' } }); expect(e.wired).toBe(true); expect(e.seal_attempted).toBe(true); expect(e.sealed).toBe(true); expect(e.kind_sealed).toBe('artifact'); }); it('wired GO, но печать НЕ встала → sealed:false + дословный reason из sealResult', () => { const e = buildSealEntry({ functionName: 'gate2', judgeActive: true, wired: true, decision: 'GO', sealResult: { sealed: false, kind: 'plan', reason: 'mentor freeze-gate: нет pass' } }); expect(e.seal_attempted).toBe(true); expect(e.sealed).toBe(false); expect(e.reason).toBe('mentor freeze-gate: нет pass'); }); it('wired NO-GO → печать не положена, seal_attempted:false', () => { const e = buildSealEntry({ functionName: 'gate2', judgeActive: true, wired: true, decision: 'NO-GO' }); expect(e.wired).toBe(true); expect(e.decision).toBe('NO-GO'); expect(e.seal_attempted).toBe(false); expect(e.sealed).toBe(false); expect(e.reason).toMatch(/NO-GO/); }); it('форма стабильна: всегда есть kind/functionName/at-поля', () => { const e = buildSealEntry({}); expect(e.kind).toBe('seal_attempt'); expect('functionName' in e).toBe(true); expect('at' in e).toBe(true); }); it('degraded c причиной → cause/error_type заполнены, reason содержит cause + слово wired', () => { const e = buildSealEntry({ functionName: null, judgeActive: true, wired: false, decision: 'GO', cause: 'transport_error', errorType: 'timeout' }); expect(e.cause).toBe('transport_error'); expect(e.error_type).toBe('timeout'); expect(e.reason).toMatch(/transport_error/); expect(e.reason).toMatch(/wired/i); }); it('at прокидывается значением (не только присутствует)', () => { expect(buildSealEntry({ judgeActive: false, nowMs: 12345 }).at).toBe(12345); }); });