Files
brain/tools/seal-to-wall.integration.test.mjs
T

41 lines
2.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, it, expect } from 'vitest';
import { sealArtifact, sealPlan, judgedHashOf, sealableArtifact, sealablePlan } from './seal-orchestration.mjs';
import { decideMode } from './enforce-supreme-gate.mjs';
// Интеграция: печать (seal-orchestration) → стена М2 (enforce-supreme-gate.decideMode).
// Проверяет, что формы, которые ставит печать, стена принимает: совпавшую правку пускает,
// несовпавшую блокирует, шаг с неразрешимым ref блокирует (закрытая дверь C-5).
const KEY = 'k';
const specMd = '## Реш {#dec-a}\nтекст решения';
const planMd = '```steps-json\n[{"op":"Edit","object":"app/Foo.php","ref":"dec-a"}]\n```';
const planMdBadRef = '```steps-json\n[{"op":"Edit","object":"app/Foo.php","ref":"dec-zzz"}]\n```';
const go = (obj) => ({ wired: true, decision: 'GO', judged_hash: judgedHashOf(obj), verdict_id: 'v' });
describe('seal → supreme-gate integration', () => {
const aObj = sealableArtifact(specMd);
const aRes = sealArtifact({ md: specMd, verdict: go(aObj), key: KEY, judgeMode: 'live-block' });
it('артефакт опечатан (печать №1)', () => {
expect(aRes.sealed).toBe(true);
expect(aRes.seal.sections['dec-a']).toBeTruthy();
});
it('совпавшая правка → allow; несовпавшая → block', () => {
const pObj = sealablePlan(planMd);
const pRes = sealPlan({ md: planMd, currentArtifact: aRes.seal, verdict: go(pObj), key: KEY, judgeMode: 'live-block' });
expect(pRes.sealed).toBe(true);
expect(pRes.seal.artifact_id).toBe(aRes.seal.artifact_id); // версии связаны
const base = { frozenPlan: pRes.seal, frozenArtifact: aRes.seal, key: KEY, stepPtr: 0 };
expect(decideMode({ ...base, toolUse: { name: 'Edit', input: { file_path: 'app/Foo.php' } } }).decision).toBe('allow');
expect(decideMode({ ...base, toolUse: { name: 'Edit', input: { file_path: 'app/Other.php' } } }).decision).toBe('block');
});
it('закрытая дверь: ref шага не резолвится в артефакте → block даже на совпавшем действии', () => {
const pObj = sealablePlan(planMdBadRef);
const pRes = sealPlan({ md: planMdBadRef, currentArtifact: aRes.seal, verdict: go(pObj), key: KEY, judgeMode: 'live-block' });
expect(pRes.sealed).toBe(true);
const base = { frozenPlan: pRes.seal, frozenArtifact: aRes.seal, key: KEY, stepPtr: 0 };
expect(decideMode({ ...base, toolUse: { name: 'Edit', input: { file_path: 'app/Foo.php' } } }).decision).toBe('block');
});
});