Files
brain/tools/seal-wiring.test.mjs
T

53 lines
2.6 KiB
JavaScript

import { describe, it, expect } from 'vitest';
import { runJudgeTurn } from './enforce-judge-gate.mjs';
const specEv = { tool_name: 'Write', session_id: 't', tool_input: { file_path: 'docs/superpowers/specs/x.md', content: '## Раздел {#k}\nтело раздела' } };
const goStub = async () => JSON.stringify({ slots: { completeness: 'ok достаточно', premortem: 'ok достаточно', goal_advocate: 'ok достаточно', correctness: 'ok достаточно' }, objections: [] });
describe('runJudgeTurn — наблюдаемость печати (seal-log wiring)', () => {
it('wired GO + печать встала → seal_attempt sealed:true, functionName gate1', async () => {
const calls = [];
await runJudgeTurn(specEv, {
mode: 'live-block', judgeActiveImpl: () => true, apiKey: 'x', transport: goStub,
onWiredSeal: () => ({ sealed: true, kind: 'artifact' }),
sealLogImpl: (e) => calls.push(e), logImpl: () => {}, warnImpl: () => {},
});
expect(calls.length).toBe(1);
expect(calls[0].kind).toBe('seal_attempt');
expect(calls[0].functionName).toBe('gate1');
expect(calls[0].sealed).toBe(true);
});
it('судья не активен → judge_active:false, sealed:false, reason про неактивность', async () => {
const calls = [];
await runJudgeTurn(specEv, {
mode: 'live-block', judgeActiveImpl: () => false,
sealLogImpl: (e) => calls.push(e), logImpl: () => {}, warnImpl: () => {},
});
expect(calls.length).toBe(1);
expect(calls[0].judge_active).toBe(false);
expect(calls[0].sealed).toBe(false);
expect(calls[0].reason).toMatch(/не актив/);
});
it('wired GO, печать НЕ встала → дословный reason из sealResult', async () => {
const calls = [];
await runJudgeTurn(specEv, {
mode: 'live-block', judgeActiveImpl: () => true, apiKey: 'x', transport: goStub,
onWiredSeal: () => ({ sealed: false, kind: 'artifact', reason: 'judged_hash mismatch (SD-1/TOCTOU)' }),
sealLogImpl: (e) => calls.push(e), logImpl: () => {}, warnImpl: () => {},
});
expect(calls[0].sealed).toBe(false);
expect(calls[0].reason).toBe('judged_hash mismatch (SD-1/TOCTOU)');
});
it('запись НЕ плана/спеки → seal-log НЕ пишется', async () => {
const calls = [];
await runJudgeTurn({ tool_name: 'Write', tool_input: { file_path: 'tools/foo.mjs', content: 'x' } }, {
mode: 'live-block', judgeActiveImpl: () => true,
sealLogImpl: (e) => calls.push(e), logImpl: () => {}, warnImpl: () => {},
});
expect(calls.length).toBe(0);
});
});