From a67d2014fadc15331bf5f5a7476b5cb72e5d2abe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Mon, 8 Jun 2026 12:21:12 +0300 Subject: [PATCH] =?UTF-8?q?test(m7-phase4b):=20decomposition=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BA=D1=80=D1=8B=D1=82=20existenceCheck=20=D0=93=D0=B5?= =?UTF-8?q?=D0=B9=D1=82-1=20=D1=87=D0=B5=D1=80=D0=B5=D0=B7=20=D0=B6=D1=83?= =?UTF-8?q?=D1=80=D0=BD=D0=B0=D0=BB=20(=C2=A75=20coverage-map)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Proof покрытия: обещанный планировочный навык, не вызванный по журналу (extractSkillCalls), → existenceCheck.missingSkills непуст → NO-GO. Доказывает, что Гейт-1 М4 ловит скрытое дробление через журнал-факт ДО retire no-op enforce-decomposition-detector (Ф8). Live-wiring «обещанные навыки ← журнал» в judge-gate — Фаза 7. 39/39 GREEN (примитивы уже построены). --- tools/judge-gate-floor.test.mjs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tools/judge-gate-floor.test.mjs b/tools/judge-gate-floor.test.mjs index 4614ff3e..4f3b1053 100644 --- a/tools/judge-gate-floor.test.mjs +++ b/tools/judge-gate-floor.test.mjs @@ -244,3 +244,34 @@ describe('greenSignaturesValid (5.4, Δ5): green засчитан только expect(greenSignaturesValid({ greenRuns: [run], key: undefined }).ok).toBe(false); }); }); + +import { extractSkillCalls as extractSkillCalls4b } from './enforce-skill-journaler.mjs'; + +// М7 Фаза 4b §5 coverage-map: decomposition (скрытое дробление) ловит Гейт-1 existenceCheck +// через ЖУРНАЛ (обещанные навыки ← extractSkillCalls), не текст. Proof покрытия ДО retire +// no-op enforce-decomposition-detector (Ф8); live-wiring «обещанные ← журнал» в judge-gate — Ф7. +describe('existenceCheck как decomposition look-ahead через журнал (М7 Фаза 4b §4.2)', () => { + const journal = [ + { payload: { op: 'Skill', object: 'superpowers:test-driven-development' } }, + { payload: { op: 'Edit', object: 'foo.mjs' } }, + ]; + it('promised planning skill НЕ вызван (по журналу) → existenceCheck ловит (missingSkills непуст)', () => { + const invoked = extractSkillCalls4b(journal); + const r = existenceCheck({ + questions: [{ id: 'q1', answered: true }], + skillsPromised: ['superpowers:writing-plans'], + skillsInvoked: invoked, + }); + expect(r.ok).toBe(false); + expect(r.missingSkills).toContain('superpowers:writing-plans'); + }); + it('promised skill вызван (в журнале) → existenceCheck ok', () => { + const invoked = extractSkillCalls4b(journal); + const r = existenceCheck({ + questions: [{ id: 'q1', answered: true }], + skillsPromised: ['superpowers:test-driven-development'], + skillsInvoked: invoked, + }); + expect(r.ok).toBe(true); + }); +});