a5d30f38a3
Этап 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>
46 lines
2.0 KiB
JavaScript
46 lines
2.0 KiB
JavaScript
import { describe, it, expect } from 'vitest';
|
|
import { readFileSync } from 'node:fs';
|
|
import { givenTokens, loadInitialInputs } from './registry-initial-inputs.mjs';
|
|
import { findHoles, normToken } from './coverage-machine.mjs';
|
|
import { loadRegistry } from './skill-contract-registry.mjs';
|
|
|
|
const VOCAB = 'docs/registry/capability-vocabulary.json';
|
|
const raw = JSON.parse(readFileSync(VOCAB, 'utf8'));
|
|
|
|
describe('registry-initial-inputs — данности задачи (D1)', () => {
|
|
it('givenTokens возвращает ровно токены category:"given"', () => {
|
|
const given = givenTokens(raw);
|
|
expect(Array.isArray(given)).toBe(true);
|
|
expect(given.length).toBeGreaterThan(50); // в словаре v0.6.0 их ~117
|
|
const set = new Set(given);
|
|
for (const t of raw.tokens) {
|
|
if (t.category === 'given') expect(set.has(t.token)).toBe(true);
|
|
else expect(set.has(t.token)).toBe(false);
|
|
}
|
|
});
|
|
|
|
it('givenTokens на пустом/битом словаре → [] (без броска)', () => {
|
|
expect(givenTokens(null)).toEqual([]);
|
|
expect(givenTokens(undefined)).toEqual([]);
|
|
expect(givenTokens({})).toEqual([]);
|
|
expect(givenTokens({ tokens: [] })).toEqual([]);
|
|
});
|
|
|
|
it('loadInitialInputs читает словарь и совпадает с givenTokens', () => {
|
|
const fromFile = loadInitialInputs({ path: VOCAB });
|
|
expect(fromFile).toEqual(givenTokens(raw));
|
|
});
|
|
|
|
it('данности не считаются дырами и сокращают findHoles на полном наборе', () => {
|
|
const reg = loadRegistry({ dir: 'docs/registry/contracts' });
|
|
const given = givenTokens(raw);
|
|
const givenSet = new Set(given.map(normToken));
|
|
const without = findHoles(reg.contracts);
|
|
const withInputs = findHoles(reg.contracts, { initialInputs: given });
|
|
for (const h of withInputs) {
|
|
expect(givenSet.has(normToken(h.need))).toBe(false);
|
|
}
|
|
expect(withInputs.length).toBeLessThan(without.length);
|
|
});
|
|
});
|