397777089e
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
41 lines
2.6 KiB
JavaScript
41 lines
2.6 KiB
JavaScript
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');
|
||
});
|
||
});
|