Files
brain/tools/enforce-judge-gate-coverage.test.mjs
T
Дмитрий a5d30f38a3 feat(registry): живой охват 2c — данности, граф, coverage-wiring, врезка в гейт
Этап 2c эпика роутер-реестр: оживление машины охвата как замена цепочкам L.
- registry-initial-inputs.mjs: токены-данности (category:given) для initialInputs.
- registry-graph-health.test.mjs: граф ацикличен, рёбра producer-consumer.
- coverage-wiring.mjs: мост recommended skills -> readinessChecklist -> {cards, ready, holes}; ready=нет-дыр.
- enforce-judge-gate.mjs: coverageCardsFor/coverageGate — карточки + стоп при дыре (инъекция-выкл).
- замок словаря (vocabTokens) на живом пути; гайд по стене: автономность + уроки сессии.
Регрессия: 4375 passed (канонический свод владельца).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 15:18:22 +03:00

48 lines
2.3 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 { coverageCardsFor, coverageGate } from './enforce-judge-gate.mjs';
// D4: чистые функции врезки охвата в гейт судьи. Мост (buildCoverageInput) инъектируется —
// тест герметичен (без I/O). Живой путь main() инъектирует реальный buildCoverageInput.
describe('enforce-judge-gate — врезка охвата (D4)', () => {
it('coverageCardsFor парсит skills-json и зовёт мост → cards/ready/holes', () => {
const content = '```skills-json\n["a","b"]\n```';
let seen = null;
const impl = ({ recommendedSkills }) => {
seen = recommendedSkills;
return { cards: [{ skill: 'a', needs: [], produces: ['x'] }], ready: true, holes: [] };
};
const out = coverageCardsFor({ content, coverageImpl: impl });
expect(seen).toEqual(['a', 'b']);
expect(out.cards).toEqual([{ skill: 'a', needs: [], produces: ['x'] }]);
expect(out.ready).toBe(true);
expect(out.holes).toEqual([]);
});
it('нет skills-json → cards:[], ready:true; мост НЕ зовётся (backward-compat)', () => {
const out = coverageCardsFor({ content: 'тело без навыков', coverageImpl: () => { throw new Error('не должен вызываться'); } });
expect(out.cards).toEqual([]);
expect(out.ready).toBe(true);
});
it('сбой моста → degraded:true (деградация не кирпичит)', () => {
const out = coverageCardsFor({ content: '```skills-json\n["a"]\n```', coverageImpl: () => { throw new Error('boom'); } });
expect(out.degraded).toBe(true);
expect(out.cards).toEqual([]);
});
it('coverageGate: дыра (ready:false) → block с перечнем дыр', () => {
const g = coverageGate({ ready: false, holes: [{ need: 'dast-report', neededBy: 'b' }] });
expect(g.block).toBe(true);
expect(g.reason).toMatch(/dast-report/);
});
it('coverageGate: нет дыр (ready:true) → не block', () => {
expect(coverageGate({ ready: true, holes: [] }).block).toBe(false);
});
it('coverageGate: degraded → не block (сбой охвата печать не стопорит)', () => {
expect(coverageGate({ ready: false, holes: [], degraded: true }).block).toBe(false);
});
});