feat(registry): токенизация needs/produces — группа tools/MCP, ЭТАП 2b ЗАВЕРШЁН (роутер-реестр)
Phase 2b группа C (финал): 51 атомарный инструмент (MCP-серверы + линтеры/ тулинг) переведены на токены словаря. Словарь +98, всего 265 токенов, v0.6.0. ИТОГ ЭТАПА 2b: ВСЕ 153 контракта needs/produces на токенах словаря. - замок словаря проходит на полном наборе (0 unknown) — готовность к 2d; - граф ожил: A8-цепочка, superpowers, knowledge-work, кросс-плагинные мосты (write-spec->writing-plans, frontend-design->design-handoff). Тест: финальный замок-тест всего реестра (153 контракта + рёбра графа). Регрессия 4373 passed, exit 0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { readFileSync, readdirSync } from 'node:fs';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { dirname, join } from 'node:path';
|
||||
import { buildRegistry } from './skill-contract-registry.mjs';
|
||||
import { loadVocabulary } from './capability-vocabulary.mjs';
|
||||
import { buildDependencyGraph } from './coverage-machine.mjs';
|
||||
|
||||
const here = dirname(fileURLToPath(import.meta.url));
|
||||
const cdir = join(here, '..', 'docs', 'registry', 'contracts');
|
||||
const vocabPath = join(here, '..', 'docs', 'registry', 'capability-vocabulary.json');
|
||||
|
||||
const FILES = readdirSync(cdir).filter((f) => f.endsWith('.contract.json'));
|
||||
const entries = FILES.map((f) => ({ contract: JSON.parse(readFileSync(join(cdir, f), 'utf8')), currentContent: '' }));
|
||||
|
||||
describe('Phase 2b ИТОГ — весь реестр проходит замок словаря (готовность к 2d)', () => {
|
||||
const { tokens } = loadVocabulary({ path: vocabPath });
|
||||
|
||||
it('ВСЕ контракты needs/produces — только токены словаря (0 unknown)', () => {
|
||||
const { contracts, errors } = buildRegistry(entries, { vocabTokens: tokens });
|
||||
expect(errors).toEqual([]);
|
||||
expect(contracts.length).toBe(FILES.length);
|
||||
expect(FILES.length).toBe(153);
|
||||
});
|
||||
|
||||
it('граф непуст: рёбра рабочих цепочек существуют на полном наборе', () => {
|
||||
const { contracts } = buildRegistry(entries, { vocabTokens: tokens });
|
||||
const { edges } = buildDependencyGraph(contracts);
|
||||
expect(edges.length).toBeGreaterThan(0);
|
||||
const has = (from, to) => edges.some((e) => e.from === from && e.to === to);
|
||||
// A8-цепочка (нужды security-go-live кормятся пятью проверками)
|
||||
expect(has('owasp-zap', 'security-go-live')).toBe(true);
|
||||
expect(has('nuclei', 'security-go-live')).toBe(true);
|
||||
// superpowers
|
||||
expect(has('superpowers:writing-plans', 'superpowers:executing-plans')).toBe(true);
|
||||
// кросс-плагинный мост
|
||||
expect(has('frontend-design', 'design-plugin:design-handoff')).toBe(true);
|
||||
expect(has('product-management:write-spec', 'superpowers:writing-plans')).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user