feat(registry): фундамент-словарь capability-токенов (этап 2a, роутер-реестр)
Phase 2a эпика «роутер-реестр» (спека v2 §3, OPEN-1): расширен docs/registry/capability-vocabulary.json 10 -> 26 токенов. - A8-цепочка (10) сохранена. - 9 токенов-мостов рабочих цепочек (создают рёбра графа producer<->consumer): feature-spec, implementation-plan, completed-change, code-review-feedback, raw-research, ui-design, marketing-draft, content-framework, close-entries. - 7 токенов-данностей задачи (-> initialInputs в 2c): feature-intent, feature-or-bugfix, bug-or-failure, ui-task, user-understanding-need, marketing-content-task, close-source-data. - Тест формы на реальном файле (validateVocabulary ok + счётчик + ключевые токены). Атомарные produce-токены ~144 контрактов добавляются в 2b (словарь живой). Структурная разведка подтверждена графом проекта (graphify, правило 14): coverage-machine не подключён к живому enforce-judge-gate (работа 2c), два реестра (контрактный community 92 / узловой community 20). Регрессия: 4367 passed, exit 0 (5 чужих node:test исключены). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,15 +1,33 @@
|
||||
{
|
||||
"version": "0.1.0",
|
||||
"version": "0.2.0",
|
||||
"tokens": [
|
||||
{"token": "running-portal", "label": "работающий портал (DAST-цель)", "description": "Запущенный веб-портал как цель динамической проверки."},
|
||||
{"token": "laravel-config", "label": "конфигурация Laravel", "description": "Конфиг приложения Laravel (заголовки, debug, права)."},
|
||||
{"token": "pii-inventory-task", "label": "задача аудита ПДн", "description": "Запрос на аудит персональных данных по 152-ФЗ."},
|
||||
{"token": "portal-pre-launch", "label": "портал перед публикацией", "description": "Портал на стадии подготовки к выходу в интернет."},
|
||||
{"token": "dast-report", "label": "отчёт DAST", "description": "Результат динамической атаки на живой портал (инъекции/XSS/обход входа/IDOR)."},
|
||||
{"token": "cve-exposure-scan", "label": "скан CVE/экспозиции", "description": "Результат проверки известных уязвимостей и небезопасной внешней экспозиции."},
|
||||
{"token": "laravel-config-audit", "label": "аудит конфигурации Laravel", "description": "Результат проверки безопасности конфигурации Laravel."},
|
||||
{"token": "pii-152fz-audit", "label": "аудит ПДн/152-ФЗ", "description": "Результат аудита персональных данных на соответствие 152-ФЗ."},
|
||||
{"token": "stride-model", "label": "STRIDE-модель угроз", "description": "Карта attack surface и приоритеты защиты перед публикацией."},
|
||||
{"token": "go-live-verdict", "label": "вердикт go-live", "description": "Сводный вердикт GO/NO-GO по безопасности перед публикацией."}
|
||||
{"token": "running-portal", "category": "given", "label": "работающий портал (DAST-цель)", "description": "Запущенный веб-портал как цель динамической проверки."},
|
||||
{"token": "laravel-config", "category": "given", "label": "конфигурация Laravel", "description": "Конфиг приложения Laravel (заголовки, debug, права)."},
|
||||
{"token": "pii-inventory-task", "category": "given", "label": "задача аудита ПДн", "description": "Запрос на аудит персональных данных по 152-ФЗ."},
|
||||
{"token": "portal-pre-launch", "category": "given", "label": "портал перед публикацией", "description": "Портал на стадии подготовки к выходу в интернет."},
|
||||
{"token": "dast-report", "category": "produced", "label": "отчёт DAST", "description": "Результат динамической атаки на живой портал (инъекции/XSS/обход входа/IDOR)."},
|
||||
{"token": "cve-exposure-scan", "category": "produced", "label": "скан CVE/экспозиции", "description": "Результат проверки известных уязвимостей и небезопасной внешней экспозиции."},
|
||||
{"token": "laravel-config-audit", "category": "produced", "label": "аудит конфигурации Laravel", "description": "Результат проверки безопасности конфигурации Laravel."},
|
||||
{"token": "pii-152fz-audit", "category": "produced", "label": "аудит ПДн/152-ФЗ", "description": "Результат аудита персональных данных на соответствие 152-ФЗ."},
|
||||
{"token": "stride-model", "category": "produced", "label": "STRIDE-модель угроз", "description": "Карта attack surface и приоритеты защиты перед публикацией."},
|
||||
{"token": "go-live-verdict", "category": "produced", "label": "вердикт go-live", "description": "Сводный вердикт GO/NO-GO по безопасности перед публикацией."},
|
||||
|
||||
{"token": "feature-spec", "category": "bridge", "label": "спека/требования фичи", "description": "Согласованный дизайн+требования или PRD до плана. Выход brainstorming / product-management:write-spec; вход writing-plans."},
|
||||
{"token": "implementation-plan", "category": "bridge", "label": "план реализации", "description": "Пошаговый план bite-sized задач. Выход writing-plans; вход executing-plans / subagent-driven-development."},
|
||||
{"token": "completed-change", "category": "bridge", "label": "завершённая правка", "description": "Готовое изменение кода до ревью/мержа. Выход test-driven-development; вход requesting-code-review / finishing-a-development-branch."},
|
||||
{"token": "code-review-feedback", "category": "bridge", "label": "фидбэк код-ревью", "description": "Замечания ревью до внедрения правок. Выход requesting-code-review; вход receiving-code-review."},
|
||||
{"token": "raw-research", "category": "bridge", "label": "сырой research", "description": "Интервью/опросы/тикеты/тесты до синтеза. Выход design-plugin:user-research; вход design-plugin:research-synthesis / product-management:synthesize-research."},
|
||||
{"token": "ui-design", "category": "bridge", "label": "решение UI/UX", "description": "Доменное UI/UX-решение (компоненты/паттерны/a11y). Выход frontend-design; вход design-plugin:design-handoff."},
|
||||
{"token": "marketing-draft", "category": "bridge", "label": "драфт маркетинг-контента", "description": "Черновик контента с форматированием. Выход marketing-plugin:draft-content; вход marketing-plugin:brand-review."},
|
||||
{"token": "content-framework", "category": "bridge", "label": "фреймворк контента", "description": "Шаблоны/фреймворки контента под канал. Выход marketing-plugin:content-creation; вход marketing-plugin:draft-content."},
|
||||
{"token": "close-entries", "category": "bridge", "label": "проводки close", "description": "Подготовленные проводки month-end (accruals/prepaid/depreciation). Выход finance-plugin:journal-entry-prep; вход finance-plugin:close-management."},
|
||||
|
||||
{"token": "feature-intent", "category": "given", "label": "идея фичи", "description": "Замысел фичи/компонента/изменения поведения до проработки. Вход brainstorming / product-management:write-spec."},
|
||||
{"token": "feature-or-bugfix", "category": "given", "label": "фича или багфикс", "description": "Задача на реализацию до написания кода. Вход test-driven-development."},
|
||||
{"token": "bug-or-failure", "category": "given", "label": "баг/падение", "description": "Баг, упавший тест или неожиданное поведение. Вход systematic-debugging."},
|
||||
{"token": "ui-task", "category": "given", "label": "UI-задача", "description": "Задача по интерфейсу: компонент/паттерн/состояние/a11y-принцип. Вход frontend-design / UI-пула."},
|
||||
{"token": "user-understanding-need", "category": "given", "label": "потребность понять пользователей", "description": "Запрос на исследование пользователей. Вход design-plugin:user-research."},
|
||||
{"token": "marketing-content-task", "category": "given", "label": "маркетинг-контент-задача", "description": "Задача создания маркетингового контента под канал. Вход marketing-plugin:content-creation."},
|
||||
{"token": "close-source-data", "category": "given", "label": "данные для close", "description": "Накопления/prepaid/амортизация для month-end. Вход finance-plugin:journal-entry-prep."}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,29 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import fs from 'node:fs';
|
||||
import { validateVocabulary, loadVocabulary, unknownTokens } from './capability-vocabulary.mjs';
|
||||
|
||||
describe('capability-vocabulary.json — реальный файл словаря (этап 2a)', () => {
|
||||
const raw = JSON.parse(fs.readFileSync('docs/registry/capability-vocabulary.json', 'utf8'));
|
||||
const r = validateVocabulary(raw);
|
||||
|
||||
it('форма валидна → ok, без ошибок', () => {
|
||||
expect(r.errors).toEqual([]);
|
||||
expect(r.ok).toBe(true);
|
||||
});
|
||||
|
||||
it('фундамент-набор присутствует (A8 + мосты + данности)', () => {
|
||||
expect(r.tokens.size).toBe(26);
|
||||
// A8-цепочка
|
||||
for (const t of ['running-portal', 'dast-report', 'go-live-verdict']) expect(r.tokens.has(t)).toBe(true);
|
||||
// мосты рабочих цепочек (создают рёбра графа)
|
||||
for (const t of ['feature-spec', 'implementation-plan', 'completed-change', 'code-review-feedback', 'raw-research', 'ui-design', 'marketing-draft', 'content-framework', 'close-entries'])
|
||||
expect(r.tokens.has(t)).toBe(true);
|
||||
// данности задачи (→ initialInputs в 2c)
|
||||
for (const t of ['feature-intent', 'feature-or-bugfix', 'bug-or-failure', 'ui-task'])
|
||||
expect(r.tokens.has(t)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('validateVocabulary — форма словаря', () => {
|
||||
const good = { version: '0.1.0', tokens: [
|
||||
{ token: 'dast-report', label: 'отчёт DAST', description: 'результат динамики' },
|
||||
|
||||
Reference in New Issue
Block a user