diff --git a/docs/registry/capability-vocabulary.json b/docs/registry/capability-vocabulary.json index 0f5be6d..04625cb 100644 --- a/docs/registry/capability-vocabulary.json +++ b/docs/registry/capability-vocabulary.json @@ -1,33 +1,239 @@ { - "version": "0.2.0", + "version": "0.3.0", "tokens": [ - {"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."} + { + "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." + }, + { + "token": "root-cause", + "category": "produced", + "label": "корневая причина", + "description": "Найденная корневая причина бага ДО предложения фикса. Выход superpowers:systematic-debugging." + }, + { + "token": "review-response", + "category": "produced", + "label": "выверенный ответ на ревью", + "description": "Технически проверенная реакция на фидбэк код-ревью (не слепое согласие). Выход superpowers:receiving-code-review." + }, + { + "token": "integration-decision", + "category": "produced", + "label": "решение интеграции ветки", + "description": "Решение merge/PR/cleanup для завершённой ветки. Выход superpowers:finishing-a-development-branch." + }, + { + "token": "isolated-worktree", + "category": "produced", + "label": "изолированный worktree", + "description": "Изолированное рабочее пространство (native или git-fallback). Выход superpowers:using-git-worktrees." + }, + { + "token": "parallel-dispatch", + "category": "produced", + "label": "параллельная раздача задач", + "description": "Раздача 2+ независимых задач субагентам. Выход superpowers:dispatching-parallel-agents." + }, + { + "token": "verification-evidence", + "category": "produced", + "label": "доказательство готовности", + "description": "Доказательство (прогон команд) ДО утверждения об успехе. Выход superpowers:verification-before-completion." + }, + { + "token": "skill-discipline", + "category": "produced", + "label": "дисциплина выбора навыков", + "description": "Дисциплина поиска и вызова релевантных навыков ПЕРВЫМ делом. Выход superpowers:using-superpowers." + }, + { + "token": "authored-skill", + "category": "produced", + "label": "созданный навык", + "description": "Навык, построенный TDD-процессом для процесс-документов. Выход superpowers:writing-skills." + }, + { + "token": "worktree-need", + "category": "given", + "label": "нужна изоляция", + "description": "Потребность в изоляции рабочего пространства под фичу. Вход superpowers:using-git-worktrees." + }, + { + "token": "independent-tasks", + "category": "given", + "label": "независимые задачи", + "description": "2+ независимые задачи без общего состояния и последовательных зависимостей. Вход superpowers:dispatching-parallel-agents." + }, + { + "token": "completion-claim", + "category": "given", + "label": "заявление о готовности", + "description": "Заявление о готовности/успехе до коммита или PR. Вход superpowers:verification-before-completion." + }, + { + "token": "task-start", + "category": "given", + "label": "начало задачи", + "description": "Начало любой задачи/разговора. Вход superpowers:using-superpowers." + }, + { + "token": "skill-authoring-intent", + "category": "given", + "label": "намерение создать/править навык", + "description": "Намерение создать или править навык. Вход superpowers:writing-skills." + } ] } diff --git a/docs/registry/contracts/superpowers__brainstorming.contract.json b/docs/registry/contracts/superpowers__brainstorming.contract.json index cd9114b..a26473b 100644 --- a/docs/registry/contracts/superpowers__brainstorming.contract.json +++ b/docs/registry/contracts/superpowers__brainstorming.contract.json @@ -2,10 +2,10 @@ "skill": "superpowers:brainstorming", "kind": "external", "needs": [ - "идея фичи/компонента/изменения поведения до реализации" + "feature-intent" ], "produces": [ - "согласованный дизайн и требования (что и зачем) до кода" + "feature-spec" ], "constraints": [ "под-навык зонтика superpowers (процессный мета-скил)", diff --git a/docs/registry/contracts/superpowers__dispatching-parallel-agents.contract.json b/docs/registry/contracts/superpowers__dispatching-parallel-agents.contract.json index e54004d..28e3e04 100644 --- a/docs/registry/contracts/superpowers__dispatching-parallel-agents.contract.json +++ b/docs/registry/contracts/superpowers__dispatching-parallel-agents.contract.json @@ -2,10 +2,10 @@ "skill": "superpowers:dispatching-parallel-agents", "kind": "external", "needs": [ - "2+ независимые задачи без общего состояния и последовательных зависимостей" + "independent-tasks" ], "produces": [ - "параллельная раздача задач субагентам" + "parallel-dispatch" ], "constraints": [ "под-навык зонтика superpowers (процессный мета-скил)", diff --git a/docs/registry/contracts/superpowers__executing-plans.contract.json b/docs/registry/contracts/superpowers__executing-plans.contract.json index b16ce94..f81bd9e 100644 --- a/docs/registry/contracts/superpowers__executing-plans.contract.json +++ b/docs/registry/contracts/superpowers__executing-plans.contract.json @@ -2,10 +2,10 @@ "skill": "superpowers:executing-plans", "kind": "external", "needs": [ - "написанный план для исполнения с чекпойнтами ревью" + "implementation-plan" ], "produces": [ - "пакетное исполнение задач плана с чекпойнтами" + "completed-change" ], "constraints": [ "под-навык зонтика superpowers (процессный мета-скил)", diff --git a/docs/registry/contracts/superpowers__finishing-a-development-branch.contract.json b/docs/registry/contracts/superpowers__finishing-a-development-branch.contract.json index 0b20cd2..7c2df1f 100644 --- a/docs/registry/contracts/superpowers__finishing-a-development-branch.contract.json +++ b/docs/registry/contracts/superpowers__finishing-a-development-branch.contract.json @@ -2,10 +2,10 @@ "skill": "superpowers:finishing-a-development-branch", "kind": "external", "needs": [ - "реализация завершена, тесты зелёные" + "completed-change" ], "produces": [ - "решение интеграции: merge / PR / cleanup" + "integration-decision" ], "constraints": [ "под-навык зонтика superpowers (процессный мета-скил)", diff --git a/docs/registry/contracts/superpowers__receiving-code-review.contract.json b/docs/registry/contracts/superpowers__receiving-code-review.contract.json index bfd8608..fe39882 100644 --- a/docs/registry/contracts/superpowers__receiving-code-review.contract.json +++ b/docs/registry/contracts/superpowers__receiving-code-review.contract.json @@ -2,10 +2,10 @@ "skill": "superpowers:receiving-code-review", "kind": "external", "needs": [ - "полученная обратная связь код-ревью до внедрения правок" + "code-review-feedback" ], "produces": [ - "техническая проверка фидбэка (не слепое согласие)" + "review-response" ], "constraints": [ "под-навык зонтика superpowers (процессный мета-скил)", diff --git a/docs/registry/contracts/superpowers__requesting-code-review.contract.json b/docs/registry/contracts/superpowers__requesting-code-review.contract.json index 936e62d..186c737 100644 --- a/docs/registry/contracts/superpowers__requesting-code-review.contract.json +++ b/docs/registry/contracts/superpowers__requesting-code-review.contract.json @@ -2,10 +2,10 @@ "skill": "superpowers:requesting-code-review", "kind": "external", "needs": [ - "завершённая задача/фича до мержа" + "completed-change" ], "produces": [ - "запрос ревью, ловящий дефекты до каскада" + "code-review-feedback" ], "constraints": [ "под-навык зонтика superpowers (процессный мета-скил)", diff --git a/docs/registry/contracts/superpowers__subagent-driven-development.contract.json b/docs/registry/contracts/superpowers__subagent-driven-development.contract.json index ca0ef67..d3988cf 100644 --- a/docs/registry/contracts/superpowers__subagent-driven-development.contract.json +++ b/docs/registry/contracts/superpowers__subagent-driven-development.contract.json @@ -2,10 +2,10 @@ "skill": "superpowers:subagent-driven-development", "kind": "external", "needs": [ - "план с независимыми задачами для исполнения в текущей сессии" + "implementation-plan" ], "produces": [ - "исполнение задач плана свежими субагентами + двухстадийное ревью" + "completed-change" ], "constraints": [ "под-навык зонтика superpowers (процессный мета-скил)", diff --git a/docs/registry/contracts/superpowers__systematic-debugging.contract.json b/docs/registry/contracts/superpowers__systematic-debugging.contract.json index 722beaf..b1e6df2 100644 --- a/docs/registry/contracts/superpowers__systematic-debugging.contract.json +++ b/docs/registry/contracts/superpowers__systematic-debugging.contract.json @@ -2,10 +2,10 @@ "skill": "superpowers:systematic-debugging", "kind": "external", "needs": [ - "баг, упавший тест или неожиданное поведение" + "bug-or-failure" ], "produces": [ - "корневая причина, найденная ДО предложения фикса" + "root-cause" ], "constraints": [ "под-навык зонтика superpowers (процессный мета-скил)", diff --git a/docs/registry/contracts/superpowers__test-driven-development.contract.json b/docs/registry/contracts/superpowers__test-driven-development.contract.json index 85ce7b9..38a2849 100644 --- a/docs/registry/contracts/superpowers__test-driven-development.contract.json +++ b/docs/registry/contracts/superpowers__test-driven-development.contract.json @@ -2,10 +2,10 @@ "skill": "superpowers:test-driven-development", "kind": "external", "needs": [ - "фича или багфикс до написания кода" + "feature-or-bugfix" ], "produces": [ - "цикл тест-первый: RED → минимальный код → GREEN → рефактор" + "completed-change" ], "constraints": [ "под-навык зонтика superpowers (процессный мета-скил)", diff --git a/docs/registry/contracts/superpowers__using-git-worktrees.contract.json b/docs/registry/contracts/superpowers__using-git-worktrees.contract.json index d529f4e..cc6723c 100644 --- a/docs/registry/contracts/superpowers__using-git-worktrees.contract.json +++ b/docs/registry/contracts/superpowers__using-git-worktrees.contract.json @@ -2,10 +2,10 @@ "skill": "superpowers:using-git-worktrees", "kind": "external", "needs": [ - "нужна изоляция рабочего пространства под фичу" + "worktree-need" ], "produces": [ - "изолированный worktree (native или git-fallback)" + "isolated-worktree" ], "constraints": [ "под-навык зонтика superpowers (процессный мета-скил)", diff --git a/docs/registry/contracts/superpowers__using-superpowers.contract.json b/docs/registry/contracts/superpowers__using-superpowers.contract.json index 472077f..0702059 100644 --- a/docs/registry/contracts/superpowers__using-superpowers.contract.json +++ b/docs/registry/contracts/superpowers__using-superpowers.contract.json @@ -2,10 +2,10 @@ "skill": "superpowers:using-superpowers", "kind": "external", "needs": [ - "начало любой задачи/разговора" + "task-start" ], "produces": [ - "дисциплина поиска и вызова релевантных навыков ПЕРВЫМ делом" + "skill-discipline" ], "constraints": [ "под-навык зонтика superpowers (процессный мета-скил)", diff --git a/docs/registry/contracts/superpowers__verification-before-completion.contract.json b/docs/registry/contracts/superpowers__verification-before-completion.contract.json index fffe877..6301c80 100644 --- a/docs/registry/contracts/superpowers__verification-before-completion.contract.json +++ b/docs/registry/contracts/superpowers__verification-before-completion.contract.json @@ -2,10 +2,10 @@ "skill": "superpowers:verification-before-completion", "kind": "external", "needs": [ - "заявление о готовности/успехе до коммита или PR" + "completion-claim" ], "produces": [ - "доказательство (прогон команд) ДО любого утверждения об успехе" + "verification-evidence" ], "constraints": [ "под-навык зонтика superpowers (процессный мета-скил)", diff --git a/docs/registry/contracts/superpowers__writing-plans.contract.json b/docs/registry/contracts/superpowers__writing-plans.contract.json index 317cbef..4406ff4 100644 --- a/docs/registry/contracts/superpowers__writing-plans.contract.json +++ b/docs/registry/contracts/superpowers__writing-plans.contract.json @@ -2,10 +2,10 @@ "skill": "superpowers:writing-plans", "kind": "external", "needs": [ - "спека или требования для многошаговой задачи" + "feature-spec" ], "produces": [ - "план реализации из bite-sized TDD-задач без плейсхолдеров" + "implementation-plan" ], "constraints": [ "под-навык зонтика superpowers (процессный мета-скил)", diff --git a/docs/registry/contracts/superpowers__writing-skills.contract.json b/docs/registry/contracts/superpowers__writing-skills.contract.json index 32b74a4..f8859f2 100644 --- a/docs/registry/contracts/superpowers__writing-skills.contract.json +++ b/docs/registry/contracts/superpowers__writing-skills.contract.json @@ -2,10 +2,10 @@ "skill": "superpowers:writing-skills", "kind": "external", "needs": [ - "создание или правка навыка" + "skill-authoring-intent" ], "produces": [ - "навык, построенный TDD-процессом для процесс-документов" + "authored-skill" ], "constraints": [ "под-навык зонтика superpowers (процессный мета-скил)", diff --git a/tools/capability-vocabulary.test.mjs b/tools/capability-vocabulary.test.mjs index 258a8ba..b9f4c6d 100644 --- a/tools/capability-vocabulary.test.mjs +++ b/tools/capability-vocabulary.test.mjs @@ -12,7 +12,8 @@ describe('capability-vocabulary.json — реальный файл словар }); it('фундамент-набор присутствует (A8 + мосты + данности)', () => { - expect(r.tokens.size).toBe(26); + // фундамент = 26 токенов; словарь живой, дорастает per-batch в 2b → >= не == + expect(r.tokens.size).toBeGreaterThanOrEqual(26); // A8-цепочка for (const t of ['running-portal', 'dast-report', 'go-live-verdict']) expect(r.tokens.has(t)).toBe(true); // мосты рабочих цепочек (создают рёбра графа) diff --git a/tools/m3c-coverage-invariants.test.mjs b/tools/m3c-coverage-invariants.test.mjs index 318cb5f..9b4d241 100644 --- a/tools/m3c-coverage-invariants.test.mjs +++ b/tools/m3c-coverage-invariants.test.mjs @@ -14,7 +14,8 @@ describe('Машина 3-C — охват на реальных контракт const wp = JSON.parse(readFileSync(join(cdir, 'superpowers__writing-plans.contract.json'), 'utf8')); const pd = JSON.parse(readFileSync(join(cdir, 'operations-process-doc.contract.json'), 'utf8')); const { contracts } = buildRegistry([{ contract: wp, currentContent: '' }, { contract: pd, currentContent: '' }]); - const r = readinessChecklist({ contracts, requests: ['план реализации из bite-sized TDD-задач без плейсхолдеров'] }); + // этап 2b: writing-plans токенизирован → produces ['implementation-plan']; просьба = токен словаря + const r = readinessChecklist({ contracts, requests: ['implementation-plan'] }); expect(Array.isArray(r.items)).toBe(true); expect(r.items).toHaveLength(4); expect(r.items.find((i) => /просьб/i.test(i.label)).ok).toBe(true); diff --git a/tools/vocab-rollout-superpowers.test.mjs b/tools/vocab-rollout-superpowers.test.mjs new file mode 100644 index 0000000..0705e56 --- /dev/null +++ b/tools/vocab-rollout-superpowers.test.mjs @@ -0,0 +1,35 @@ +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 SP = readdirSync(cdir).filter((f) => f.startsWith('superpowers__') && f.endsWith('.contract.json')); +const entries = SP.map((f) => ({ contract: JSON.parse(readFileSync(join(cdir, f), 'utf8')), currentContent: '' })); + +describe('Phase 2b батч superpowers — замок словаря + рёбра графа', () => { + const { tokens } = loadVocabulary({ path: vocabPath }); + + it('все 14 superpowers-контрактов проходят замок словаря (нет неизвестных токенов)', () => { + expect(SP.length).toBe(14); + const { contracts, errors } = buildRegistry(entries, { vocabTokens: tokens }); + expect(errors).toEqual([]); + expect(contracts.length).toBe(14); + }); + + it('рёбра рабочей цепочки сформированы (brainstorming→writing-plans→executing-plans)', () => { + const { contracts } = buildRegistry(entries, { vocabTokens: tokens }); + const { edges } = buildDependencyGraph(contracts); + const has = (from, to) => edges.some((e) => e.from === from && e.to === to); + expect(has('superpowers:brainstorming', 'superpowers:writing-plans')).toBe(true); // via feature-spec + expect(has('superpowers:writing-plans', 'superpowers:executing-plans')).toBe(true); // via implementation-plan + expect(has('superpowers:test-driven-development', 'superpowers:requesting-code-review')).toBe(true); // via completed-change + expect(has('superpowers:requesting-code-review', 'superpowers:receiving-code-review')).toBe(true); // via code-review-feedback + }); +});