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:
Дмитрий
2026-06-19 10:27:39 +03:00
parent 88fc55b4a5
commit 4dee49e4a1
53 changed files with 1869 additions and 358 deletions
+589 -1
View File
@@ -1,5 +1,5 @@
{
"version": "0.5.0",
"version": "0.6.0",
"tokens": [
{
"token": "running-portal",
@@ -1002,6 +1002,594 @@
"category": "given",
"label": "промпт + тест-кейсы",
"description": "LLM-промпт + кейсы для eval. Вход promptfoo."
},
{
"token": "ui-template-draft",
"category": "produced",
"label": "стартовый UI-шаблон",
"description": "LLM-сгенерированный UI-шаблон. Выход 21st-magic."
},
{
"token": "db-or-docs-result",
"category": "produced",
"label": "результат SQL/Eloquent или docs",
"description": "Результат запроса к dev-БД или релевантная докуменация Laravel. Выход boost."
},
{
"token": "library-docs",
"category": "produced",
"label": "документация библиотеки",
"description": "Актуальная документация библиотеки/SDK. Выход context7."
},
{
"token": "ru-seo-data",
"category": "produced",
"label": "SEO-данные РФ",
"description": "SERP/бэклинки/конкурентный анализ РФ. Выход dataforseo-mcp."
},
{
"token": "semantic-web-results",
"category": "produced",
"label": "семантический веб-поиск",
"description": "Результаты по смыслу + страница по URL. Выход exa-mcp."
},
{
"token": "figma-tokens",
"category": "produced",
"label": "дизайн-токены Figma",
"description": "Извлечённые токены/компоненты/стили. Выход figma-mcp."
},
{
"token": "web-page-content",
"category": "produced",
"label": "содержимое страниц",
"description": "Scrape/crawl/map/extract + web-research. Выход firecrawl-mcp."
},
{
"token": "github-op-result",
"category": "produced",
"label": "результат GitHub-операции",
"description": "Чтение/запись issue/PR/комментария. Выход github-mcp."
},
{
"token": "notebook-result",
"category": "produced",
"label": "результат ноутбука",
"description": "Результат исполнения ячеек. Выход jupyter-mcp."
},
{
"token": "n8n-automation",
"category": "produced",
"label": "автоматизация n8n",
"description": "Автоматизация процесса через n8n. Выход n8n-mcp."
},
{
"token": "api-resources",
"category": "produced",
"label": "API-ресурсы (чтение)",
"description": "Эндпоинты/схемы/параметры как MCP-ресурсы. Выход openapi-mcp."
},
{
"token": "web-answer-cited",
"category": "produced",
"label": "web-ответ с цитатами",
"description": "Ранжированный ответ sonar (search/ask/research/reason). Выход perplexity-mcp."
},
{
"token": "browser-interaction-result",
"category": "produced",
"label": "результат браузера",
"description": "Скриншот/взаимодействие/console+network. Выход playwright-mcp."
},
{
"token": "sql-result",
"category": "produced",
"label": "результат SQL",
"description": "Результат исторического SQL к dev-БД. Выход postgres-mcp."
},
{
"token": "scheduled-social-posts",
"category": "produced",
"label": "запланированные публикации",
"description": "Публикации в 30+ соцсетях (VK/Telegram). Выход postiz."
},
{
"token": "redis-state",
"category": "produced",
"label": "состояние Redis",
"description": "Ключи/очереди/TTL/паттерны (чтение). Выход redis-mcp."
},
{
"token": "sentry-events",
"category": "produced",
"label": "события Sentry",
"description": "События/ошибки/трассировки (чтение). Выход sentry-mcp."
},
{
"token": "telegram-result",
"category": "produced",
"label": "результат Telegram",
"description": "Публикация/редактирование/аналитика канала. Выход telegram-mcp."
},
{
"token": "email-blast-sent",
"category": "produced",
"label": "email-рассылка отправлена",
"description": "Отправка маркетинговой рассылки. Выход unisender-go-mcp."
},
{
"token": "svg-icon",
"category": "produced",
"label": "SVG-иконка",
"description": "Иконка из не-Lucide коллекции (Material/Tabler/Phosphor). Выход universal-icons-mcp."
},
{
"token": "metrika-data",
"category": "produced",
"label": "данные Яндекс.Метрики",
"description": "Визиты/источники/гео/поведение. Выход yandex-metrika-mcp."
},
{
"token": "wordstat-frequency",
"category": "produced",
"label": "частотность Wordstat",
"description": "Частотность РФ-запросов: сезонность/связанные. Выход yandex-wordstat-mcp."
},
{
"token": "spelling-report",
"category": "produced",
"label": "отчёт орфографии",
"description": "Отчёт о неизвестных словах. Выход cspell."
},
{
"token": "cve-dependency-pr",
"category": "produced",
"label": "auto-PR на CVE зависимости",
"description": "Auto-PR при CVE в зависимости. Выход dependabot."
},
{
"token": "layer-violation-report",
"category": "produced",
"label": "отчёт нарушений слоёв",
"description": "Нарушения границ слоёв. Выход deptrac."
},
{
"token": "linted-js-vue",
"category": "produced",
"label": "пролинченный JS/Vue",
"description": "Исправленный/проверенный JS/Vue (ESLint+Prettier). Выход eslint-prettier."
},
{
"token": "secret-leak-findings",
"category": "produced",
"label": "находки утечек секретов",
"description": "Ключи/токены/пароли/DSN. Выход gitleaks."
},
{
"token": "stories-catalog",
"category": "produced",
"label": "каталог stories",
"description": "Визуальный каталог stories/variants. Выход histoire."
},
{
"token": "ide-stubs",
"category": "produced",
"label": "IDE-заглушки",
"description": "@mixin IdeHelper* для autocomplete. Выход ide-helper."
},
{
"token": "php-type-report",
"category": "produced",
"label": "отчёт типов PHP",
"description": "Ошибки типов/сигнатур/undefined. Выход larastan."
},
{
"token": "broken-link-report",
"category": "produced",
"label": "отчёт битых ссылок",
"description": "Битые URL и якоря. Выход lychee."
},
{
"token": "markdown-style-report",
"category": "produced",
"label": "отчёт стиля Markdown",
"description": "Нарушения стиля Markdown. Выход markdownlint."
},
{
"token": "mermaid-diagram",
"category": "produced",
"label": "диаграмма Mermaid",
"description": "Диаграмма в нотации Mermaid/C4. Выход mermaid."
},
{
"token": "runtime-trace",
"category": "produced",
"label": "runtime-трейс",
"description": "Коррелированный request/job/query трейс. Выход nightowl."
},
{
"token": "a11y-violations-report",
"category": "produced",
"label": "отчёт a11y (рантайм)",
"description": "Нарушения WCAG 2.1 AA на странице. Выход pa11y."
},
{
"token": "php-test-result",
"category": "produced",
"label": "результат Pest",
"description": "Pass/fail/assertions PHP-тестов. Выход pest."
},
{
"token": "masked-dump",
"category": "produced",
"label": "маскированный дамп",
"description": "Дамп с маской ПДн (телефоны/имена/email). Выход pg-anonymizer."
},
{
"token": "db-audit-log",
"category": "produced",
"label": "аудит-журнал БД",
"description": "Журнал DDL/DML/DCL операций. Выход pg-audit."
},
{
"token": "formatted-sql",
"category": "produced",
"label": "отформатированный SQL",
"description": "Отступы/регистр/выравнивание. Выход pg-formatter."
},
{
"token": "auto-partitions",
"category": "produced",
"label": "авто-партиции",
"description": "Создание/удаление partition по расписанию. Выход pg-partman."
},
{
"token": "php-quality-metrics",
"category": "produced",
"label": "метрики качества PHP",
"description": "Сложность/архитектура/code style. Выход php-insights."
},
{
"token": "formatted-php",
"category": "produced",
"label": "отформатированный PHP",
"description": "PSR-12 + Laravel style. Выход pint."
},
{
"token": "refactored-php",
"category": "produced",
"label": "рефакторенный PHP",
"description": "Upgrade/dead-code/modernization. Выход rector."
},
{
"token": "composer-cve-block",
"category": "produced",
"label": "блок CVE-пакета",
"description": "Блок установки пакета с известным CVE. Выход roave-security."
},
{
"token": "sast-report",
"category": "produced",
"label": "SAST-отчёт",
"description": "Уязвимости кода (инъекции/XSS/конфиг). Выход semgrep."
},
{
"token": "migration-danger-report",
"category": "produced",
"label": "отчёт опасной миграции",
"description": "Блокировки/без CONCURRENTLY/ненадёжный DEFAULT. Выход squawk."
},
{
"token": "css-style-report",
"category": "produced",
"label": "отчёт стиля CSS",
"description": "Нарушения стиля CSS. Выход stylelint."
},
{
"token": "image-cve-report",
"category": "produced",
"label": "отчёт CVE образа",
"description": "CVE в OS-пакетах и зависимостях образа. Выход trivy."
},
{
"token": "vitest-result",
"category": "produced",
"label": "результат Vitest",
"description": "Pass/fail unit/component. Выход vitest."
},
{
"token": "editor-type-diagnostics",
"category": "produced",
"label": "диагностика в редакторе",
"description": "IntelliSense/go-to-def/hover/типы. Выход volar."
},
{
"token": "vue-type-report",
"category": "produced",
"label": "отчёт типов Vue",
"description": "Несоответствия типов в шаблонах/script. Выход vue-tsc."
},
{
"token": "ui-template-intent",
"category": "given",
"label": "намерение UI-шаблона",
"description": "Компонент/лейаут/форма. Вход 21st-magic."
},
{
"token": "db-or-docs-query",
"category": "given",
"label": "запрос к БД или docs",
"description": "SQL/Eloquent к dev-БД или вопрос по docs Laravel. Вход boost."
},
{
"token": "library-api-question",
"category": "given",
"label": "вопрос по API библиотеки",
"description": "Вопрос по API/доке библиотеки/SDK. Вход context7."
},
{
"token": "ru-seo-question",
"category": "given",
"label": "SEO-вопрос РФ",
"description": "SERP/ключевые/бэклинки РФ. Вход dataforseo-mcp."
},
{
"token": "semantic-search-need",
"category": "given",
"label": "нужен семантический поиск",
"description": "Найти источники по смыслу. Вход exa-mcp."
},
{
"token": "figma-file",
"category": "given",
"label": "Figma-файл",
"description": "Файл с дизайн-токенами/компонентами. Вход figma-mcp."
},
{
"token": "web-read-need",
"category": "given",
"label": "нужно прочитать страницу/сайт",
"description": "Прочитать/обойти/извлечь со страниц. Вход firecrawl-mcp."
},
{
"token": "repo-ref",
"category": "given",
"label": "ссылка на repo/issue/PR",
"description": "Ссылка на repo/issue/PR. Вход github-mcp."
},
{
"token": "github-operation-intent",
"category": "given",
"label": "намерение GitHub-операции",
"description": "Операция чтения/записи. Вход github-mcp."
},
{
"token": "jupyter-notebook",
"category": "given",
"label": "Jupyter-ноутбук",
"description": "Ноутбук для исполнения. Вход jupyter-mcp."
},
{
"token": "n8n-workflow",
"category": "given",
"label": "workflow n8n",
"description": "Workflow для движка n8n. Вход n8n-mcp."
},
{
"token": "openapi-spec",
"category": "given",
"label": "OpenAPI-спецификация",
"description": "OpenAPI/REST-спека интеграции. Вход openapi-mcp."
},
{
"token": "web-research-question",
"category": "given",
"label": "вопрос веб-разведки",
"description": "Актуальные практики/нормы/конкуренты с источниками. Вход perplexity-mcp."
},
{
"token": "browser-target",
"category": "given",
"label": "URL/HTML для браузера",
"description": "URL или HTML-файл для управления. Вход playwright-mcp."
},
{
"token": "browser-action-intent",
"category": "given",
"label": "намерение действия браузера",
"description": "Скриншот/взаимодействие/сетевой трейс. Вход playwright-mcp."
},
{
"token": "historical-sql-query",
"category": "given",
"label": "исторический SQL-запрос",
"description": "Исторический SQL к dev-БД. Вход postgres-mcp."
},
{
"token": "social-content-plan",
"category": "given",
"label": "план публикаций",
"description": "Контент-календарь/план соцсетей. Вход postiz."
},
{
"token": "redis-state-question",
"category": "given",
"label": "вопрос о состоянии Redis",
"description": "Ключи/очереди/TTL. Вход redis-mcp."
},
{
"token": "prod-runtime-error",
"category": "given",
"label": "production runtime ошибка",
"description": "Ошибка для диагностики. Вход sentry-mcp."
},
{
"token": "telegram-action",
"category": "given",
"label": "действие в Telegram",
"description": "Пост/действие в канале. Вход telegram-mcp."
},
{
"token": "email-blast-task",
"category": "given",
"label": "массовая email-рассылка",
"description": "Рассылка через Unisender Go. Вход unisender-go-mcp."
},
{
"token": "svg-icon-need",
"category": "given",
"label": "нужна SVG-иконка",
"description": "Иконка не-Lucide коллекции. Вход universal-icons-mcp."
},
{
"token": "web-analytics-question",
"category": "given",
"label": "вопрос веб-аналитики",
"description": "Аналитика лендинга. Вход yandex-metrika-mcp."
},
{
"token": "keyword-topic",
"category": "given",
"label": "тема для ключевых слов",
"description": "Тема для подбора ключевых. Вход yandex-wordstat-mcp."
},
{
"token": "markdown-files",
"category": "given",
"label": "Markdown-файлы",
"description": "Markdown для проверки. Вход cspell/lychee/markdownlint."
},
{
"token": "project-dictionary",
"category": "given",
"label": "словарь проекта",
"description": "Пользовательский словарь орфографии. Вход cspell."
},
{
"token": "project-dependencies",
"category": "given",
"label": "зависимости проекта",
"description": "Composer/npm зависимости. Вход dependabot."
},
{
"token": "php-layers",
"category": "given",
"label": "PHP-слои",
"description": "Слои для проверки направления зависимостей. Вход deptrac."
},
{
"token": "js-vue-source",
"category": "given",
"label": "JS/Vue-код",
"description": "JS/Vue для линта/тестов. Вход eslint-prettier/vitest."
},
{
"token": "git-diff-or-history",
"category": "given",
"label": "git diff/история",
"description": "Diff или история репозитория. Вход gitleaks."
},
{
"token": "vue-component",
"category": "given",
"label": "Vue-компонент",
"description": "Vue-компонент(ы) для каталога/проверки типов. Вход histoire/vue-tsc."
},
{
"token": "laravel-project",
"category": "given",
"label": "Laravel-проект",
"description": "Facades/модели/хелперы. Вход ide-helper."
},
{
"token": "php-source",
"category": "given",
"label": "PHP-код",
"description": "PHP-код для анализа/форматирования/рефакторинга. Вход larastan/pint/php-insights/rector."
},
{
"token": "diagram-requirement",
"category": "given",
"label": "требование к диаграмме",
"description": "C4/flow/sequence. Вход mermaid."
},
{
"token": "trace-correlation-need",
"category": "given",
"label": "нужна корреляция трасс",
"description": "Сквозная request/job/query корреляция. Вход nightowl."
},
{
"token": "rendered-page",
"category": "given",
"label": "отрендеренная страница",
"description": "Страница/URL для a11y. Вход pa11y."
},
{
"token": "php-tests",
"category": "given",
"label": "PHP-тесты",
"description": "Unit/feature/RLS тесты. Вход pest."
},
{
"token": "db-dump-with-pii",
"category": "given",
"label": "дамп с ПДн",
"description": "Дамп БД с персональными данными. Вход pg-anonymizer."
},
{
"token": "db-operations",
"category": "given",
"label": "операции БД",
"description": "DDL/DML/DCL операции. Вход pg-audit."
},
{
"token": "sql-file",
"category": "given",
"label": "SQL-файл",
"description": "SQL для форматирования. Вход pg-formatter."
},
{
"token": "partition-schedule",
"category": "given",
"label": "расписание партиций",
"description": "Расписание партиционирования таблиц. Вход pg-partman."
},
{
"token": "composer-install",
"category": "given",
"label": "composer install/update",
"description": "Установка/обновление пакетов. Вход roave-security."
},
{
"token": "code-for-sast",
"category": "given",
"label": "код для SAST",
"description": "PHP/JS/Vue для SAST. Вход semgrep."
},
{
"token": "sql-migration",
"category": "given",
"label": "SQL-миграция",
"description": "Миграция PostgreSQL. Вход squawk."
},
{
"token": "css-source",
"category": "given",
"label": "CSS-код",
"description": "CSS в .vue SFC или .css. Вход stylelint."
},
{
"token": "docker-image",
"category": "given",
"label": "Docker-образ",
"description": "Образ для скана. Вход trivy."
},
{
"token": "open-vue-file",
"category": "given",
"label": "открытый .vue в VSCode",
"description": "Открытый .vue для IntelliSense. Вход volar."
}
]
}
@@ -1,12 +1,30 @@
{
"skill": "21st-magic",
"kind": "external",
"needs": ["намерение UI-шаблона (компонент / лейаут / форма)"],
"produces": ["стартовый UI-шаблон (LLM-сгенерированный)"],
"constraints": ["генератор шаблонов через PSR_v1 R14.4 pipeline", "Pa11y проверка обязательна после генерации", "стек-фильтр R6.0"],
"needs": [
"ui-template-intent"
],
"produces": [
"ui-template-draft"
],
"constraints": [
"генератор шаблонов через PSR_v1 R14.4 pipeline",
"Pa11y проверка обязательна после генерации",
"стек-фильтр R6.0"
],
"preview-form": "mockup",
"defaults": ["после генерации — обязательный Pa11y"],
"key-decisions": ["какой шаблон; адаптация под Vue+Vuetify"],
"acceptance-criteria": ["шаблон в стеке Vue+Vuetify, Pa11y 0 нарушений"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"после генерации — обязательный Pa11y"
],
"key-decisions": [
"какой шаблон; адаптация под Vue+Vuetify"
],
"acceptance-criteria": [
"шаблон в стеке Vue+Vuetify, Pa11y 0 нарушений"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+25 -7
View File
@@ -1,12 +1,30 @@
{
"skill": "boost",
"kind": "external",
"needs": ["SQL/Eloquent-запрос к dev-БД или вопрос по docs Laravel/пакета"],
"produces": ["результат SQL/Eloquent или релевантная документация Laravel"],
"constraints": ["MCP к dev-БД через Roster auto-detect", "НЕ подключать к production DB", "заменил PostgreSQL MCP (#1)"],
"needs": [
"db-or-docs-query"
],
"produces": [
"db-or-docs-result"
],
"constraints": [
"MCP к dev-БД через Roster auto-detect",
"НЕ подключать к production DB",
"заменил PostgreSQL MCP (#1)"
],
"preview-form": "none",
"defaults": ["read-first; serverить только установленные пакеты (Roster)"],
"key-decisions": ["источник: только dev-БД, не прод"],
"acceptance-criteria": ["запрос/доки отданы из правильного (dev) источника"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"read-first; serverить только установленные пакеты (Roster)"
],
"key-decisions": [
"источник: только dev-БД, не прод"
],
"acceptance-criteria": [
"запрос/доки отданы из правильного (dev) источника"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+24 -7
View File
@@ -1,12 +1,29 @@
{
"skill": "context7",
"kind": "external",
"needs": ["вопрос по API/доке конкретной библиотеки/SDK"],
"produces": ["актуальная документация библиотеки/SDK"],
"constraints": ["первый выбор для доков известной библиотеки", "WebFetch — fallback на URL; WebSearch — без знания библиотеки"],
"needs": [
"library-api-question"
],
"produces": [
"library-docs"
],
"constraints": [
"первый выбор для доков известной библиотеки",
"WebFetch — fallback на URL; WebSearch — без знания библиотеки"
],
"preview-form": "none",
"defaults": ["resolve-library-id → query-docs"],
"key-decisions": ["какая библиотека/тема"],
"acceptance-criteria": ["актуальная дока по API получена"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"resolve-library-id → query-docs"
],
"key-decisions": [
"какая библиотека/тема"
],
"acceptance-criteria": [
"актуальная дока по API получена"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+26 -7
View File
@@ -1,12 +1,31 @@
{
"skill": "cspell",
"kind": "external",
"needs": ["Markdown-текст для проверки орфографии", "пользовательский словарь проекта"],
"produces": ["отчёт о неизвестных словах"],
"constraints": ["ru/en орфография .md с пользовательским словарём", "НЕ стиль (markdownlint)", "НЕ грамматика"],
"needs": [
"markdown-files",
"project-dictionary"
],
"produces": [
"spelling-report"
],
"constraints": [
"ru/en орфография .md с пользовательским словарём",
"НЕ стиль (markdownlint)",
"НЕ грамматика"
],
"preview-form": "none",
"defaults": ["учитывать cspell-words.txt"],
"key-decisions": ["новый валидный термин → в словарь, а не подавлять находку"],
"acceptance-criteria": ["0 неизвестных слов вне словаря"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"учитывать cspell-words.txt"
],
"key-decisions": [
"новый валидный термин → в словарь, а не подавлять находку"
],
"acceptance-criteria": [
"0 неизвестных слов вне словаря"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,29 @@
{
"skill": "dataforseo-mcp",
"kind": "external",
"needs": ["SEO-вопрос по РФ (SERP/ключевые/бэклинки)"],
"produces": ["SEO-данные РФ: SERP-позиции, бэклинки, конкурентный анализ"],
"constraints": ["DEFERRED — платный, pending Б-1", "комплементарен Wordstat #79"],
"needs": [
"ru-seo-question"
],
"produces": [
"ru-seo-data"
],
"constraints": [
"DEFERRED — платный, pending Б-1",
"комплементарен Wordstat #79"
],
"preview-form": "none",
"defaults": ["при платном аккаунте"],
"key-decisions": ["какие SEO-данные нужны"],
"acceptance-criteria": ["SEO-данные РФ получены (при доступе)"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"при платном аккаунте"
],
"key-decisions": [
"какие SEO-данные нужны"
],
"acceptance-criteria": [
"SEO-данные РФ получены (при доступе)"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,29 @@
{
"skill": "dependabot",
"kind": "external",
"needs": ["Composer/npm-зависимости"],
"produces": ["auto-PR при обнаружении CVE в зависимости"],
"constraints": ["авто-PR через .github/dependabot.yml", "НЕ блок install (Roave)"],
"needs": [
"project-dependencies"
],
"produces": [
"cve-dependency-pr"
],
"constraints": [
"авто-PR через .github/dependabot.yml",
"НЕ блок install (Roave)"
],
"preview-form": "none",
"defaults": ["настройка через .github/dependabot.yml"],
"key-decisions": ["принять/отклонить предложенное обновление"],
"acceptance-criteria": ["CVE-зависимости имеют открытый update-PR"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"настройка через .github/dependabot.yml"
],
"key-decisions": [
"принять/отклонить предложенное обновление"
],
"acceptance-criteria": [
"CVE-зависимости имеют открытый update-PR"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+25 -7
View File
@@ -1,12 +1,30 @@
{
"skill": "deptrac",
"kind": "external",
"needs": ["PHP-слои для проверки направления зависимостей"],
"produces": ["отчёт о нарушениях границ слоёв"],
"constraints": ["граф слоёв по app/deptrac.yaml; lefthook job 10", "НЕ типовой анализ (Larastan)", "НЕ декларативный ADR (adr-judge)"],
"needs": [
"php-layers"
],
"produces": [
"layer-violation-report"
],
"constraints": [
"граф слоёв по app/deptrac.yaml; lefthook job 10",
"НЕ типовой анализ (Larastan)",
"НЕ декларативный ADR (adr-judge)"
],
"preview-form": "none",
"defaults": ["конфиг 13 слоёв, консервативный ruleset"],
"key-decisions": ["допустимые направления зависимостей"],
"acceptance-criteria": ["0 нарушений границ слоёв"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"конфиг 13 слоёв, консервативный ruleset"
],
"key-decisions": [
"допустимые направления зависимостей"
],
"acceptance-criteria": [
"0 нарушений границ слоёв"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,30 @@
{
"skill": "eslint-prettier",
"kind": "external",
"needs": ["JS/Vue-код для линта+форматирования"],
"produces": ["исправленный/проверенный JS/Vue по ESLint+Prettier"],
"constraints": ["связка lint+format JS/Vue", "НЕ CSS (Stylelint)", "НЕ типы (vue-tsc)"],
"needs": [
"js-vue-source"
],
"produces": [
"linted-js-vue"
],
"constraints": [
"связка lint+format JS/Vue",
"НЕ CSS (Stylelint)",
"НЕ типы (vue-tsc)"
],
"preview-form": "none",
"defaults": ["flat-config + plugin-vue; config-prettier разводит конфликты"],
"key-decisions": ["scope: staged-файлы vs весь js/vue"],
"acceptance-criteria": ["0 ESLint-ошибок, формат единообразен"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"flat-config + plugin-vue; config-prettier разводит конфликты"
],
"key-decisions": [
"scope: staged-файлы vs весь js/vue"
],
"acceptance-criteria": [
"0 ESLint-ошибок, формат единообразен"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+25 -7
View File
@@ -1,12 +1,30 @@
{
"skill": "exa-mcp",
"kind": "external",
"needs": ["нужно найти источники по смыслу, которые keyword-поиск пропускает"],
"produces": ["семантически близкие результаты веб-поиска (web_search_exa) + страница по URL (web_fetch_exa)"],
"constraints": ["READ-ONLY MCP, живой веб", "платный API, ключ EXA_API_KEY только в env", "обнаружение источников, НЕ ранжированный ответ (perplexity #87) и НЕ глубокое чтение (firecrawl #89)"],
"needs": [
"semantic-search-need"
],
"produces": [
"semantic-web-results"
],
"constraints": [
"READ-ONLY MCP, живой веб",
"платный API, ключ EXA_API_KEY только в env",
"обнаружение источников, НЕ ранжированный ответ (perplexity #87) и НЕ глубокое чтение (firecrawl #89)"
],
"preview-form": "none",
"defaults": ["семантическое обнаружение источников по смыслу"],
"key-decisions": ["web_search_exa vs web_fetch_exa; глубина выдачи"],
"acceptance-criteria": ["найдены концептуально релевантные источники по смыслу запроса"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"семантическое обнаружение источников по смыслу"
],
"key-decisions": [
"web_search_exa vs web_fetch_exa; глубина выдачи"
],
"acceptance-criteria": [
"найдены концептуально релевантные источники по смыслу запроса"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,29 @@
{
"skill": "figma-mcp",
"kind": "external",
"needs": ["Figma-файл с дизайн-токенами/компонентами"],
"produces": ["извлечённые дизайн-токены/компоненты/стили"],
"constraints": ["DEFERRED — нет Figma-аккаунта; источник — статический handoff Платона", "extract-only, code-gen за Frontend Design (#30)"],
"needs": [
"figma-file"
],
"produces": [
"figma-tokens"
],
"constraints": [
"DEFERRED — нет Figma-аккаунта; источник — статический handoff Платона",
"extract-only, code-gen за Frontend Design (#30)"
],
"preview-form": "none",
"defaults": ["на поддерживаемом источнике: extract-only"],
"key-decisions": ["какие токены извлекать"],
"acceptance-criteria": ["токены извлечены из Figma-источника (когда доступен)"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"на поддерживаемом источнике: extract-only"
],
"key-decisions": [
"какие токены извлекать"
],
"acceptance-criteria": [
"токены извлечены из Figma-источника (когда доступен)"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,30 @@
{
"skill": "firecrawl-mcp",
"kind": "external",
"needs": ["нужно прочитать страницу целиком / обойти сайт / извлечь структурированное со страниц"],
"produces": ["содержимое страниц и обхода (scrape/batch_scrape/map/search/crawl/extract) + автономный web-research (firecrawl_agent)"],
"constraints": ["READ-ONLY (read-тяжёлый) MCP, живой веб", "платный API, ключ FIRECRAWL_API_KEY только в env", "глубокое чтение/обход, НЕ ранжированный ответ (perplexity #87) и НЕ наш REST-спек (openapi #47)"],
"needs": [
"web-read-need"
],
"produces": [
"web-page-content"
],
"constraints": [
"READ-ONLY (read-тяжёлый) MCP, живой веб",
"платный API, ключ FIRECRAWL_API_KEY только в env",
"глубокое чтение/обход, НЕ ранжированный ответ (perplexity #87) и НЕ наш REST-спек (openapi #47)"
],
"preview-form": "none",
"defaults": ["scrape одной страницы целиком в markdown"],
"key-decisions": ["scrape vs crawl vs extract vs agent; глубина обхода"],
"acceptance-criteria": ["получено полное/структурированное содержимое целевой страницы или обхода"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"scrape одной страницы целиком в markdown"
],
"key-decisions": [
"scrape vs crawl vs extract vs agent; глубина обхода"
],
"acceptance-criteria": [
"получено полное/структурированное содержимое целевой страницы или обхода"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,30 @@
{
"skill": "github-mcp",
"kind": "external",
"needs": ["ссылка на repo/issue/PR", "намерение операции"],
"produces": ["результат чтения или записи issue/PR/комментария"],
"constraints": ["внешний MCP — операции через GitHub API", "НЕ локальный git-флоу (это git/PowerShell)"],
"needs": [
"repo-ref",
"github-operation-intent"
],
"produces": [
"github-op-result"
],
"constraints": [
"внешний MCP — операции через GitHub API",
"НЕ локальный git-флоу (это git/PowerShell)"
],
"preview-form": "none",
"defaults": ["read-first перед мутацией"],
"key-decisions": ["scope операции: чтение или запись"],
"acceptance-criteria": ["операция отражена в GitHub и подтверждена ответом API"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"read-first перед мутацией"
],
"key-decisions": [
"scope операции: чтение или запись"
],
"acceptance-criteria": [
"операция отражена в GitHub и подтверждена ответом API"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+24 -7
View File
@@ -1,12 +1,29 @@
{
"skill": "gitleaks",
"kind": "external",
"needs": ["git diff или история репозитория"],
"produces": ["находки утечек секретов (ключи/токены/пароли/DSN)"],
"constraints": ["сканирует секреты в diff/истории через lefthook pre-commit/pre-push", "НЕ SAST-уязвимости кода (Semgrep)"],
"needs": [
"git-diff-or-history"
],
"produces": [
"secret-leak-findings"
],
"constraints": [
"сканирует секреты в diff/истории через lefthook pre-commit/pre-push",
"НЕ SAST-уязвимости кода (Semgrep)"
],
"preview-form": "none",
"defaults": ["protect --staged на pre-commit; полная история на pre-push"],
"key-decisions": ["реальный секрет vs тестовая фикстура (false-positive)"],
"acceptance-criteria": ["0 утечек секретов в diff/истории"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"protect --staged на pre-commit; полная история на pre-push"
],
"key-decisions": [
"реальный секрет vs тестовая фикстура (false-positive)"
],
"acceptance-criteria": [
"0 утечек секретов в diff/истории"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+24 -7
View File
@@ -1,12 +1,29 @@
{
"skill": "histoire",
"kind": "external",
"needs": ["Vue-компонент для каталога stories"],
"produces": ["визуальный каталог stories/variants"],
"constraints": ["каталог компонентов (не Storybook)", "Vuetify через setupFile"],
"needs": [
"vue-component"
],
"produces": [
"stories-catalog"
],
"constraints": [
"каталог компонентов (не Storybook)",
"Vuetify через setupFile"
],
"preview-form": "sample",
"defaults": ["npm run story"],
"key-decisions": ["какие компоненты/variants в каталоге"],
"acceptance-criteria": ["stories собираются и рендерятся"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"npm run story"
],
"key-decisions": [
"какие компоненты/variants в каталоге"
],
"acceptance-criteria": [
"stories собираются и рендерятся"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,29 @@
{
"skill": "ide-helper",
"kind": "external",
"needs": ["Laravel-проект (facades/модели/хелперы)"],
"produces": ["IDE-заглушки (@mixin IdeHelper*) для autocomplete/type-inference"],
"constraints": ["генерация stubs для IDE", "НЕ влияет на рантайм"],
"needs": [
"laravel-project"
],
"produces": [
"ide-stubs"
],
"constraints": [
"генерация stubs для IDE",
"НЕ влияет на рантайм"
],
"preview-form": "none",
"defaults": ["ide-helper:generate + models -W -M -N"],
"key-decisions": ["когда перегенерировать (после изменения моделей)"],
"acceptance-criteria": ["autocomplete/type-inference покрывают facades+модели"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"ide-helper:generate + models -W -M -N"
],
"key-decisions": [
"когда перегенерировать (после изменения моделей)"
],
"acceptance-criteria": [
"autocomplete/type-inference покрывают facades+модели"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,28 @@
{
"skill": "jupyter-mcp",
"kind": "external",
"needs": ["Jupyter-ноутбук для исполнения"],
"produces": ["результат исполнения ячеек ноутбука"],
"constraints": ["DEFERRED — нет Python ML-окружения на native-Windows"],
"needs": [
"jupyter-notebook"
],
"produces": [
"notebook-result"
],
"constraints": [
"DEFERRED — нет Python ML-окружения на native-Windows"
],
"preview-form": "none",
"defaults": ["на поддерживаемой среде с Python ML"],
"key-decisions": ["какие ячейки исполнять"],
"acceptance-criteria": ["ноутбук исполнен, результаты получены (на поддерживаемой среде)"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"на поддерживаемой среде с Python ML"
],
"key-decisions": [
"какие ячейки исполнять"
],
"acceptance-criteria": [
"ноутбук исполнен, результаты получены (на поддерживаемой среде)"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+25 -7
View File
@@ -1,12 +1,30 @@
{
"skill": "larastan",
"kind": "external",
"needs": ["PHP-код для статанализа типов"],
"produces": ["отчёт об ошибках типов/сигнатур/undefined-переменных"],
"constraints": ["типовой анализ PHPStan+Laravel", "НЕ стиль (Pint)", "НЕ граф слоёв (deptrac)"],
"needs": [
"php-source"
],
"produces": [
"php-type-report"
],
"constraints": [
"типовой анализ PHPStan+Laravel",
"НЕ стиль (Pint)",
"НЕ граф слоёв (deptrac)"
],
"preview-form": "none",
"defaults": ["уровень + baseline проекта"],
"key-decisions": ["новая ошибка vs baseline-долг"],
"acceptance-criteria": ["0 новых ошибок типов сверх baseline"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"уровень + baseline проекта"
],
"key-decisions": [
"новая ошибка vs baseline-долг"
],
"acceptance-criteria": [
"0 новых ошибок типов сверх baseline"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+24 -7
View File
@@ -1,12 +1,29 @@
{
"skill": "lychee",
"kind": "external",
"needs": ["Markdown-файлы со ссылками"],
"produces": ["отчёт о битых URL и якорях"],
"constraints": ["внутренние + внешние ссылки и якоря .md", "НЕ стиль/орфография"],
"needs": [
"markdown-files"
],
"produces": [
"broken-link-report"
],
"constraints": [
"внутренние + внешние ссылки и якоря .md",
"НЕ стиль/орфография"
],
"preview-form": "none",
"defaults": ["проверять и внутренние якоря, и внешние URL"],
"key-decisions": ["внешний временно недоступный vs реально битый — различать"],
"acceptance-criteria": ["0 битых ссылок/якорей"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"проверять и внутренние якоря, и внешние URL"
],
"key-decisions": [
"внешний временно недоступный vs реально битый — различать"
],
"acceptance-criteria": [
"0 битых ссылок/якорей"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,30 @@
{
"skill": "markdownlint",
"kind": "external",
"needs": ["Markdown-файлы для линта"],
"produces": ["отчёт о нарушениях стиля Markdown"],
"constraints": ["внешний CLI — стиль .md (заголовки/таблицы/пробелы/переносы)", "НЕ орфография (cspell)", "НЕ ссылки (lychee)"],
"needs": [
"markdown-files"
],
"produces": [
"markdown-style-report"
],
"constraints": [
"внешний CLI — стиль .md (заголовки/таблицы/пробелы/переносы)",
"НЕ орфография (cspell)",
"НЕ ссылки (lychee)"
],
"preview-form": "none",
"defaults": ["авто-fix где возможно (--fix), кроме корневого CLAUDE.md"],
"key-decisions": ["scope: какие .md в проверке"],
"acceptance-criteria": ["0 нарушений стиля по правилам markdownlint"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"авто-fix где возможно (--fix), кроме корневого CLAUDE.md"
],
"key-decisions": [
"scope: какие .md в проверке"
],
"acceptance-criteria": [
"0 нарушений стиля по правилам markdownlint"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+24 -7
View File
@@ -1,12 +1,29 @@
{
"skill": "mermaid",
"kind": "external",
"needs": ["требование к диаграмме (C4 / flow / sequence / ...)"],
"produces": ["диаграмма в нотации Mermaid/C4"],
"constraints": ["вендоренный скил; диаграммы в docs/architecture/", "НЕ фиксация решения (adr-kit)"],
"needs": [
"diagram-requirement"
],
"produces": [
"mermaid-diagram"
],
"constraints": [
"вендоренный скил; диаграммы в docs/architecture/",
"НЕ фиксация решения (adr-kit)"
],
"preview-form": "diagram",
"defaults": ["C4: context/container/component"],
"key-decisions": ["тип и уровень диаграммы"],
"acceptance-criteria": ["диаграмма рендерится и отражает систему"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"C4: context/container/component"
],
"key-decisions": [
"тип и уровень диаграммы"
],
"acceptance-criteria": [
"диаграмма рендерится и отражает систему"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+24 -7
View File
@@ -1,12 +1,29 @@
{
"skill": "n8n-mcp",
"kind": "external",
"needs": ["workflow для движка n8n"],
"produces": ["автоматизация процесса через n8n"],
"constraints": ["DEFERRED — n8n не в стеке; движок процессов = очередь Laravel", "принятие n8n — отдельное архитектурное решение"],
"needs": [
"n8n-workflow"
],
"produces": [
"n8n-automation"
],
"constraints": [
"DEFERRED — n8n не в стеке; движок процессов = очередь Laravel",
"принятие n8n — отдельное архитектурное решение"
],
"preview-form": "none",
"defaults": ["на среде с n8n"],
"key-decisions": ["принятие n8n как движка — отдельный ADR"],
"acceptance-criteria": ["workflow исполняется в n8n (когда принят)"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"на среде с n8n"
],
"key-decisions": [
"принятие n8n как движка — отдельный ADR"
],
"acceptance-criteria": [
"workflow исполняется в n8n (когда принят)"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+24 -7
View File
@@ -1,12 +1,29 @@
{
"skill": "nightowl",
"kind": "external",
"needs": ["сквозная корреляция request/job/query трассировок"],
"produces": ["коррелированный runtime-трейс (self-hosted)"],
"constraints": ["DEFERRED — нет pcntl/posix на native-Windows; pending Б-1/Linux", "ADR-013 BT7 НЕ Sentry #34 (трейс vs ошибки), BT8 НЕ Pail/Boost"],
"needs": [
"trace-correlation-need"
],
"produces": [
"runtime-trace"
],
"constraints": [
"DEFERRED — нет pcntl/posix на native-Windows; pending Б-1/Linux",
"ADR-013 BT7 НЕ Sentry #34 (трейс vs ошибки), BT8 НЕ Pail/Boost"
],
"preview-form": "none",
"defaults": ["на Linux-среде с pcntl/posix"],
"key-decisions": ["scope корреляции трассировок"],
"acceptance-criteria": ["request/job/query скоррелированы в трейс (на поддерживаемой среде)"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"на Linux-среде с pcntl/posix"
],
"key-decisions": [
"scope корреляции трассировок"
],
"acceptance-criteria": [
"request/job/query скоррелированы в трейс (на поддерживаемой среде)"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,29 @@
{
"skill": "openapi-mcp",
"kind": "external",
"needs": ["OpenAPI/REST-спецификация интеграции"],
"produces": ["эндпоинты/схемы/параметры как MCP-ресурсы (чтение)"],
"constraints": ["READ-ONLY интроспекция спеки", "НЕ генерация кода"],
"needs": [
"openapi-spec"
],
"produces": [
"api-resources"
],
"constraints": [
"READ-ONLY интроспекция спеки",
"НЕ генерация кода"
],
"preview-form": "none",
"defaults": ["read-only через .mcp.json"],
"key-decisions": ["какой эндпоинт/схему смотреть"],
"acceptance-criteria": ["структура API понята из спеки"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"read-only через .mcp.json"
],
"key-decisions": [
"какой эндпоинт/схему смотреть"
],
"acceptance-criteria": [
"структура API понята из спеки"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+25 -7
View File
@@ -1,12 +1,30 @@
{
"skill": "pa11y",
"kind": "external",
"needs": ["отрендеренная веб-страница / URL"],
"produces": ["отчёт о нарушениях доступности WCAG 2.1 AA"],
"constraints": ["единственный технический SoT a11y в проекте", "НЕ через Lighthouse", "НЕ визуальный смок (Playwright)"],
"needs": [
"rendered-page"
],
"produces": [
"a11y-violations-report"
],
"constraints": [
"единственный технический SoT a11y в проекте",
"НЕ через Lighthouse",
"НЕ визуальный смок (Playwright)"
],
"preview-form": "none",
"defaults": ["проверять контраст / alt / роли / фокус-порядок по WCAG 2.1 AA"],
"key-decisions": ["какие страницы/URL в a11y-прогоне"],
"acceptance-criteria": ["0 нарушений WCAG 2.1 AA на проверяемых страницах"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"проверять контраст / alt / роли / фокус-порядок по WCAG 2.1 AA"
],
"key-decisions": [
"какие страницы/URL в a11y-прогоне"
],
"acceptance-criteria": [
"0 нарушений WCAG 2.1 AA на проверяемых страницах"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,30 @@
{
"skill": "perplexity-mcp",
"kind": "external",
"needs": ["вопрос веб-разведки: актуальные практики/нормы/конкуренты — нужен ответ-с-источниками"],
"produces": ["ранжированный web-ответ с цитатами (sonar): search/ask/research/reason"],
"constraints": ["READ-ONLY MCP, живой веб", "платный API (sonar-*), ключ PERPLEXITY_API_KEY только в env — без авто-расхода без нужды", "НЕ SDK-доки (context7 #60); НЕ внутренний граф проекта (graphify #86)"],
"needs": [
"web-research-question"
],
"produces": [
"web-answer-cited"
],
"constraints": [
"READ-ONLY MCP, живой веб",
"платный API (sonar-*), ключ PERPLEXITY_API_KEY только в env — без авто-расхода без нужды",
"НЕ SDK-доки (context7 #60); НЕ внутренний граф проекта (graphify #86)"
],
"preview-form": "none",
"defaults": ["ранжированный ответ-с-источниками, не сырой список ссылок"],
"key-decisions": ["search vs ask vs research vs reason; глубина (reasoning_effort)"],
"acceptance-criteria": ["получен ответ с цитируемыми источниками по запросу веб-разведки"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"ранжированный ответ-с-источниками, не сырой список ссылок"
],
"key-decisions": [
"search vs ask vs research vs reason; глубина (reasoning_effort)"
],
"acceptance-criteria": [
"получен ответ с цитируемыми источниками по запросу веб-разведки"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+24 -7
View File
@@ -1,12 +1,29 @@
{
"skill": "pest",
"kind": "external",
"needs": ["PHP-тесты (unit/feature/RLS)"],
"produces": ["результат прогона тестов (pass/fail/assertions)"],
"constraints": ["Pest 4: unit/feature/RLS/parallel/browser/stress/mutation", "НЕ Vue-тесты (Vitest)"],
"needs": [
"php-tests"
],
"produces": [
"php-test-result"
],
"constraints": [
"Pest 4: unit/feature/RLS/parallel/browser/stress/mutation",
"НЕ Vue-тесты (Vitest)"
],
"preview-form": "none",
"defaults": ["composer test; --parallel в CI"],
"key-decisions": ["scope: какие тесты, parallel vs serial"],
"acceptance-criteria": ["все тесты зелёные, без регрессий"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"composer test; --parallel в CI"
],
"key-decisions": [
"scope: какие тесты, parallel vs serial"
],
"acceptance-criteria": [
"все тесты зелёные, без регрессий"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,29 @@
{
"skill": "pg-anonymizer",
"kind": "external",
"needs": ["дамп БД с персональными данными"],
"produces": ["маскированный дамп (телефоны/имена/email)"],
"constraints": ["загрузка по требованию LOAD 'anon' (не db-wide preload)", "на проде liderra.ru"],
"needs": [
"db-dump-with-pii"
],
"produces": [
"masked-dump"
],
"constraints": [
"загрузка по требованию LOAD 'anon' (не db-wide preload)",
"на проде liderra.ru"
],
"preview-form": "sample",
"defaults": ["маски по требованию для выгрузок"],
"key-decisions": ["какие поля маскировать"],
"acceptance-criteria": ["ПДн в выгрузке замаскированы"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"маски по требованию для выгрузок"
],
"key-decisions": [
"какие поля маскировать"
],
"acceptance-criteria": [
"ПДн в выгрузке замаскированы"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+24 -7
View File
@@ -1,12 +1,29 @@
{
"skill": "pg-audit",
"kind": "external",
"needs": ["DDL/DML/DCL операции БД"],
"produces": ["аудит-журнал операций на уровне БД"],
"constraints": ["pgaudit.log=ddl,role,write; log_parameter=off (ПДн не логируются)", "на проде liderra.ru; закрывает 152-ФЗ"],
"needs": [
"db-operations"
],
"produces": [
"db-audit-log"
],
"constraints": [
"pgaudit.log=ddl,role,write; log_parameter=off (ПДн не логируются)",
"на проде liderra.ru; закрывает 152-ФЗ"
],
"preview-form": "none",
"defaults": ["журнал в /var/log/postgresql"],
"key-decisions": ["scope логируемых операций"],
"acceptance-criteria": ["аудит-журнал БД ведётся, ПДн не в логах"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"журнал в /var/log/postgresql"
],
"key-decisions": [
"scope логируемых операций"
],
"acceptance-criteria": [
"аудит-журнал БД ведётся, ПДн не в логах"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,29 @@
{
"skill": "pg-formatter",
"kind": "external",
"needs": ["SQL-файл для форматирования"],
"produces": ["отформатированный SQL (отступы/регистр/выравнивание)"],
"constraints": ["форматирование SQL по хуку на db/schema.sql", "НЕ линт опасных паттернов (squawk)"],
"needs": [
"sql-file"
],
"produces": [
"formatted-sql"
],
"constraints": [
"форматирование SQL по хуку на db/schema.sql",
"НЕ линт опасных паттернов (squawk)"
],
"preview-form": "none",
"defaults": ["стандарт pgFormatter"],
"key-decisions": ["scope: какой SQL форматировать"],
"acceptance-criteria": ["SQL приведён к стандарту pgFormatter"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"стандарт pgFormatter"
],
"key-decisions": [
"scope: какой SQL форматировать"
],
"acceptance-criteria": [
"SQL приведён к стандарту pgFormatter"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,29 @@
{
"skill": "pg-partman",
"kind": "external",
"needs": ["расписание партиционирования таблиц"],
"produces": ["авто-создание/удаление partition-таблиц по расписанию"],
"constraints": ["dormant — недоступно на native-Windows PG", "заменён Artisan partitions:create-months"],
"needs": [
"partition-schedule"
],
"produces": [
"auto-partitions"
],
"constraints": [
"dormant — недоступно на native-Windows PG",
"заменён Artisan partitions:create-months"
],
"preview-form": "none",
"defaults": ["на поддерживаемой среде — по расписанию; на dev заменён ручным cron'ом"],
"key-decisions": ["окно/гранулярность партиций"],
"acceptance-criteria": ["партиции созданы/удалены по расписанию (на поддерживаемой среде)"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"на поддерживаемой среде — по расписанию; на dev заменён ручным cron'ом"
],
"key-decisions": [
"окно/гранулярность партиций"
],
"acceptance-criteria": [
"партиции созданы/удалены по расписанию (на поддерживаемой среде)"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,29 @@
{
"skill": "php-insights",
"kind": "external",
"needs": ["PHP-код для метрик качества"],
"produces": ["метрики: сложность, архитектура, code style score"],
"constraints": ["on-demand/CI, не блокирует; пороги 78/79/73", "ADR-013 BT4 НЕ Pint/Larastan; уникум — оси complexity+architecture"],
"needs": [
"php-source"
],
"produces": [
"php-quality-metrics"
],
"constraints": [
"on-demand/CI, не блокирует; пороги 78/79/73",
"ADR-013 BT4 НЕ Pint/Larastan; уникум — оси complexity+architecture"
],
"preview-form": "none",
"defaults": ["composer insights; baseline-пороги"],
"key-decisions": ["какие оси/пороги важны"],
"acceptance-criteria": ["метрики не ниже baseline-порогов"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"composer insights; baseline-пороги"
],
"key-decisions": [
"какие оси/пороги важны"
],
"acceptance-criteria": [
"метрики не ниже baseline-порогов"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+24 -7
View File
@@ -1,12 +1,29 @@
{
"skill": "pint",
"kind": "external",
"needs": ["PHP-код для форматирования"],
"produces": ["отформатированный PHP по PSR-12 + Laravel style"],
"constraints": ["только форматирование стиля", "НЕ статанализ типов (Larastan)"],
"needs": [
"php-source"
],
"produces": [
"formatted-php"
],
"constraints": [
"только форматирование стиля",
"НЕ статанализ типов (Larastan)"
],
"preview-form": "none",
"defaults": ["применять Laravel preset"],
"key-decisions": ["scope: staged-файлы vs весь php"],
"acceptance-criteria": ["0 расхождений со стилем Pint"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"применять Laravel preset"
],
"key-decisions": [
"scope: staged-файлы vs весь php"
],
"acceptance-criteria": [
"0 расхождений со стилем Pint"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,31 @@
{
"skill": "playwright-mcp",
"kind": "external",
"needs": ["URL или HTML-файл для управления", "намерение: скриншот / взаимодействие / сетевой трейс"],
"produces": ["скриншот / результат взаимодействия / снимок console+network"],
"constraints": ["внешний MCP — управляет headless-браузером", "НЕ a11y-проверка (это Pa11y)", "НЕ замена unit/e2e-тестам"],
"needs": [
"browser-target",
"browser-action-intent"
],
"produces": [
"browser-interaction-result"
],
"constraints": [
"внешний MCP — управляет headless-браузером",
"НЕ a11y-проверка (это Pa11y)",
"НЕ замена unit/e2e-тестам"
],
"preview-form": "sample",
"defaults": ["read-first: снять снимок/состояние страницы до действия"],
"key-decisions": ["что проверяем: визуал, взаимодействие или сетевой трейс"],
"acceptance-criteria": ["ожидаемое состояние страницы подтверждено снимком/снапшотом"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"read-first: снять снимок/состояние страницы до действия"
],
"key-decisions": [
"что проверяем: визуал, взаимодействие или сетевой трейс"
],
"acceptance-criteria": [
"ожидаемое состояние страницы подтверждено снимком/снапшотом"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,28 @@
{
"skill": "postgres-mcp",
"kind": "external",
"needs": ["исторический SQL-запрос к dev-БД"],
"produces": ["результат SQL (исторически)"],
"constraints": ["historic — заменён Laravel Boost (#10); не используется"],
"needs": [
"historical-sql-query"
],
"produces": [
"sql-result"
],
"constraints": [
"historic — заменён Laravel Boost (#10); не используется"
],
"preview-form": "none",
"defaults": ["заменён Boost #10"],
"key-decisions": ["использовать Boost #10 вместо этого узла"],
"acceptance-criteria": ["SQL-запросы идут через Boost #10, не через этот узел"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"заменён Boost #10"
],
"key-decisions": [
"использовать Boost #10 вместо этого узла"
],
"acceptance-criteria": [
"SQL-запросы идут через Boost #10, не через этот узел"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+24 -7
View File
@@ -1,12 +1,29 @@
{
"skill": "postiz",
"kind": "external",
"needs": ["контент-календарь / план публикаций в соцсети"],
"produces": ["запланированные публикации в 30+ соцсетях (VK/Telegram)"],
"constraints": ["self-host AGPL-3.0 без дистрибуции (ADR-015 MKT7)", "покрывает VK-постинг"],
"needs": [
"social-content-plan"
],
"produces": [
"scheduled-social-posts"
],
"constraints": [
"self-host AGPL-3.0 без дистрибуции (ADR-015 MKT7)",
"покрывает VK-постинг"
],
"preview-form": "outline",
"defaults": ["контент-календарь, self-host"],
"key-decisions": ["каналы и расписание публикаций"],
"acceptance-criteria": ["публикации запланированы по календарю"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"контент-календарь, self-host"
],
"key-decisions": [
"каналы и расписание публикаций"
],
"acceptance-criteria": [
"публикации запланированы по календарю"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+24 -7
View File
@@ -1,12 +1,29 @@
{
"skill": "rector",
"kind": "external",
"needs": ["PHP-код для авто-рефакторинга/version-upgrade"],
"produces": ["трансформированный PHP (upgrade/dead-code/modernization)"],
"constraints": ["вручную/CI, не блокирует коммит", "ADR-013: BT1 НЕ Pint (трансформация vs формат), BT2 комплементарен Larastan, BT3 НЕ deptrac"],
"needs": [
"php-source"
],
"produces": [
"refactored-php"
],
"constraints": [
"вручную/CI, не блокирует коммит",
"ADR-013: BT1 НЕ Pint (трансформация vs формат), BT2 комплементарен Larastan, BT3 НЕ deptrac"
],
"preview-form": "dry-run",
"defaults": ["dry-run baseline; conservative ruleset"],
"key-decisions": ["какие правила трансформации"],
"acceptance-criteria": ["код трансформирован, тесты зелёные"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"dry-run baseline; conservative ruleset"
],
"key-decisions": [
"какие правила трансформации"
],
"acceptance-criteria": [
"код трансформирован, тесты зелёные"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,29 @@
{
"skill": "redis-mcp",
"kind": "external",
"needs": ["вопрос о состоянии Redis/Memurai (ключи/очереди/TTL)"],
"produces": ["состояние Redis (чтение): ключи, очереди, TTL, паттерны"],
"constraints": ["READ-ONLY MCP к Redis/Memurai", "НЕ prod-ошибки (Sentry MCP)"],
"needs": [
"redis-state-question"
],
"produces": [
"redis-state"
],
"constraints": [
"READ-ONLY MCP к Redis/Memurai",
"НЕ prod-ошибки (Sentry MCP)"
],
"preview-form": "none",
"defaults": ["read-only инспекция кэша/очередей"],
"key-decisions": ["что инспектировать: кэш, очередь, race"],
"acceptance-criteria": ["состояние кэша/очереди/race локализовано"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"read-only инспекция кэша/очередей"
],
"key-decisions": [
"что инспектировать: кэш, очередь, race"
],
"acceptance-criteria": [
"состояние кэша/очереди/race локализовано"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,29 @@
{
"skill": "roave-security",
"kind": "external",
"needs": ["composer install/update"],
"produces": ["блок установки пакета с известным CVE"],
"constraints": ["conflict-список CVE на install/update", "НЕ SAST кода (Semgrep)"],
"needs": [
"composer-install"
],
"produces": [
"composer-cve-block"
],
"constraints": [
"conflict-список CVE на install/update",
"НЕ SAST кода (Semgrep)"
],
"preview-form": "none",
"defaults": ["срабатывает автоматически на composer"],
"key-decisions": ["нет ручного выбора — автоматический conflict-гейт"],
"acceptance-criteria": ["установка с известным CVE заблокирована"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"срабатывает автоматически на composer"
],
"key-decisions": [
"нет ручного выбора — автоматический conflict-гейт"
],
"acceptance-criteria": [
"установка с известным CVE заблокирована"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+25 -7
View File
@@ -1,12 +1,30 @@
{
"skill": "semgrep",
"kind": "external",
"needs": ["PHP/JS/Vue-код для SAST"],
"produces": ["отчёт об уязвимостях кода (инъекции, небезопасная конфигурация, XSS)"],
"constraints": ["SAST бинарь + MCP", "НЕ секреты в diff (gitleaks)", "НЕ глубокий on-demand аудит (Trail of Bits)"],
"needs": [
"code-for-sast"
],
"produces": [
"sast-report"
],
"constraints": [
"SAST бинарь + MCP",
"НЕ секреты в diff (gitleaks)",
"НЕ глубокий on-demand аудит (Trail of Bits)"
],
"preview-form": "none",
"defaults": ["npm run sast"],
"key-decisions": ["scope скана; реальная уязвимость vs false-positive"],
"acceptance-criteria": ["0 уязвимостей высокого риска"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"npm run sast"
],
"key-decisions": [
"scope скана; реальная уязвимость vs false-positive"
],
"acceptance-criteria": [
"0 уязвимостей высокого риска"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,30 @@
{
"skill": "sentry-mcp",
"kind": "external",
"needs": ["production runtime ошибка для диагностики"],
"produces": ["события/ошибки/трассировки из Sentry (чтение)"],
"constraints": ["READ-ONLY MCP к self-hosted Sentry", "pending активации Б-1", "НЕ Redis-состояние (Redis MCP)"],
"needs": [
"prod-runtime-error"
],
"produces": [
"sentry-events"
],
"constraints": [
"READ-ONLY MCP к self-hosted Sentry",
"pending активации Б-1",
"НЕ Redis-состояние (Redis MCP)"
],
"preview-form": "none",
"defaults": ["read-only диагностика"],
"key-decisions": ["какое событие/трассировку смотреть"],
"acceptance-criteria": ["причина prod-ошибки локализована по событию Sentry"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"read-only диагностика"
],
"key-decisions": [
"какое событие/трассировку смотреть"
],
"acceptance-criteria": [
"причина prod-ошибки локализована по событию Sentry"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+24 -7
View File
@@ -1,12 +1,29 @@
{
"skill": "squawk",
"kind": "external",
"needs": ["SQL-миграция PostgreSQL"],
"produces": ["отчёт об опасных паттернах миграции (блокировки, без CONCURRENTLY, ненадёжный DEFAULT)"],
"constraints": ["линт миграций в pre-commit для database/migrations", "НЕ форматирование (pgFormatter)"],
"needs": [
"sql-migration"
],
"produces": [
"migration-danger-report"
],
"constraints": [
"линт миграций в pre-commit для database/migrations",
"НЕ форматирование (pgFormatter)"
],
"preview-form": "none",
"defaults": ["прогон на staged миграциях"],
"key-decisions": ["блокирующая операция vs допустимая"],
"acceptance-criteria": ["0 опасных паттернов в миграции"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"прогон на staged миграциях"
],
"key-decisions": [
"блокирующая операция vs допустимая"
],
"acceptance-criteria": [
"0 опасных паттернов в миграции"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,30 @@
{
"skill": "stylelint",
"kind": "external",
"needs": ["CSS-код в .vue SFC или .css-файлах"],
"produces": ["отчёт о нарушениях стиля CSS"],
"constraints": ["CSS в .vue SFC + css-файлы", "НЕ JS/TS (ESLint)", "НЕ a11y (Pa11y)"],
"needs": [
"css-source"
],
"produces": [
"css-style-report"
],
"constraints": [
"CSS в .vue SFC + css-файлы",
"НЕ JS/TS (ESLint)",
"НЕ a11y (Pa11y)"
],
"preview-form": "none",
"defaults": ["порядок свойств + именование по конфигу проекта"],
"key-decisions": ["scope: staged-файлы vs весь css"],
"acceptance-criteria": ["0 нарушений стиля CSS"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"порядок свойств + именование по конфигу проекта"
],
"key-decisions": [
"scope: staged-файлы vs весь css"
],
"acceptance-criteria": [
"0 нарушений стиля CSS"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,29 @@
{
"skill": "telegram-mcp",
"kind": "external",
"needs": ["пост/действие в Telegram-канале"],
"produces": ["публикация/редактирование/аналитика Telegram-канала"],
"constraints": ["выделенный аккаунт через SESSION_STRING (только .env)", "ADR-015 MKT8"],
"needs": [
"telegram-action"
],
"produces": [
"telegram-result"
],
"constraints": [
"выделенный аккаунт через SESSION_STRING (только .env)",
"ADR-015 MKT8"
],
"preview-form": "none",
"defaults": ["выделенный аккаунт, SESSION_STRING в .env"],
"key-decisions": ["канал и контент поста"],
"acceptance-criteria": ["пост опубликован / аналитика получена"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"выделенный аккаунт, SESSION_STRING в .env"
],
"key-decisions": [
"канал и контент поста"
],
"acceptance-criteria": [
"пост опубликован / аналитика получена"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+24 -7
View File
@@ -1,12 +1,29 @@
{
"skill": "trivy",
"kind": "external",
"needs": ["Docker-образ для скана"],
"produces": ["отчёт о CVE в OS-пакетах и зависимостях образа"],
"constraints": ["скан Docker-образов в CI перед push в registry", "НЕ скан кода (Semgrep)"],
"needs": [
"docker-image"
],
"produces": [
"image-cve-report"
],
"constraints": [
"скан Docker-образов в CI перед push в registry",
"НЕ скан кода (Semgrep)"
],
"preview-form": "none",
"defaults": ["trivy image перед push в Yandex Container Registry"],
"key-decisions": ["порог severity для блока"],
"acceptance-criteria": ["0 критичных CVE в образе"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"trivy image перед push в Yandex Container Registry"
],
"key-decisions": [
"порог severity для блока"
],
"acceptance-criteria": [
"0 критичных CVE в образе"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,29 @@
{
"skill": "unisender-go-mcp",
"kind": "external",
"needs": ["массовая email-рассылка через Unisender Go"],
"produces": ["отправка маркетинговой email-рассылки"],
"constraints": ["DEFERRED — нет upstream MCP, нужна своя обёртка", "ADR-015 MKT5: маркетинговые рассылки НЕ транзакционный email; 152-ФЗ согласия cross-ref #77/#71"],
"needs": [
"email-blast-task"
],
"produces": [
"email-blast-sent"
],
"constraints": [
"DEFERRED — нет upstream MCP, нужна своя обёртка",
"ADR-015 MKT5: маркетинговые рассылки НЕ транзакционный email; 152-ФЗ согласия cross-ref #77/#71"
],
"preview-form": "none",
"defaults": ["при наличии обёртки"],
"key-decisions": ["сегмент и согласия рассылки"],
"acceptance-criteria": ["рассылка отправлена с соблюдением 152-ФЗ согласий (при наличии обёртки)"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"при наличии обёртки"
],
"key-decisions": [
"сегмент и согласия рассылки"
],
"acceptance-criteria": [
"рассылка отправлена с соблюдением 152-ФЗ согласий (при наличии обёртки)"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,29 @@
{
"skill": "universal-icons-mcp",
"kind": "external",
"needs": ["потребность в SVG-иконке (не-Lucide коллекция)"],
"produces": ["SVG-иконка из коллекции (Material/Tabler/Phosphor/...)"],
"constraints": ["только не-Lucide коллекции (ADR-006: Lucide → lucide-vue-next)", "raw-SVG, не компонент"],
"needs": [
"svg-icon-need"
],
"produces": [
"svg-icon"
],
"constraints": [
"только не-Lucide коллекции (ADR-006: Lucide → lucide-vue-next)",
"raw-SVG, не компонент"
],
"preview-form": "sample",
"defaults": ["для Lucide использовать lucide-vue-next, не этот MCP"],
"key-decisions": ["коллекция и конкретная иконка"],
"acceptance-criteria": ["иконка вставлена из не-Lucide коллекции корректно"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"для Lucide использовать lucide-vue-next, не этот MCP"
],
"key-decisions": [
"коллекция и конкретная иконка"
],
"acceptance-criteria": [
"иконка вставлена из не-Lucide коллекции корректно"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+24 -7
View File
@@ -1,12 +1,29 @@
{
"skill": "vitest",
"kind": "external",
"needs": ["Vue-компоненты/модули для unit/component-тестов"],
"produces": ["результат прогона Vitest (pass/fail)"],
"constraints": ["тесты Vue (jsdom, @vue/test-utils, Pinia)", "НЕ PHP-тесты (Pest)"],
"needs": [
"js-vue-source"
],
"produces": [
"vitest-result"
],
"constraints": [
"тесты Vue (jsdom, @vue/test-utils, Pinia)",
"НЕ PHP-тесты (Pest)"
],
"preview-form": "none",
"defaults": ["npm run test:vue"],
"key-decisions": ["scope тестов"],
"acceptance-criteria": ["все Vue-тесты зелёные"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"npm run test:vue"
],
"key-decisions": [
"scope тестов"
],
"acceptance-criteria": [
"все Vue-тесты зелёные"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+24 -7
View File
@@ -1,12 +1,29 @@
{
"skill": "volar",
"kind": "external",
"needs": ["открытый .vue-файл в VSCode"],
"produces": ["IntelliSense / go-to-definition / hover / диагностика типов в редакторе"],
"constraints": ["VSCode-расширение (редактор-only)", "НЕ CI type-check (vue-tsc)"],
"needs": [
"open-vue-file"
],
"produces": [
"editor-type-diagnostics"
],
"constraints": [
"VSCode-расширение (редактор-only)",
"НЕ CI type-check (vue-tsc)"
],
"preview-form": "none",
"defaults": ["работает в редакторе автоматически"],
"key-decisions": ["нет ручного выбора — редакторная служба"],
"acceptance-criteria": ["навигация/диагностика по .vue работают в редакторе"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"работает в редакторе автоматически"
],
"key-decisions": [
"нет ручного выбора — редакторная служба"
],
"acceptance-criteria": [
"навигация/диагностика по .vue работают в редакторе"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+24 -7
View File
@@ -1,12 +1,29 @@
{
"skill": "vue-tsc",
"kind": "external",
"needs": [".vue-компоненты для проверки типов"],
"produces": ["отчёт о несоответствиях типов в шаблонах/script"],
"constraints": ["полный type-check только в CI", "НЕ редакторная служба (Volar)"],
"needs": [
"vue-component"
],
"produces": [
"vue-type-report"
],
"constraints": [
"полный type-check только в CI",
"НЕ редакторная служба (Volar)"
],
"preview-form": "none",
"defaults": ["прогон в CI"],
"key-decisions": ["scope проверки типов"],
"acceptance-criteria": ["0 ошибок типов vue-tsc"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"прогон в CI"
],
"key-decisions": [
"scope проверки типов"
],
"acceptance-criteria": [
"0 ошибок типов vue-tsc"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,29 @@
{
"skill": "yandex-metrika-mcp",
"kind": "external",
"needs": ["вопрос веб-аналитики лендинга"],
"produces": ["данные Яндекс.Метрики (визиты/источники/гео/демография/поведение)"],
"constraints": ["READ-ONLY MCP; активен при живом лендинге (Б-1)", "НЕ подбор ключевых слов (Wordstat #79)"],
"needs": [
"web-analytics-question"
],
"produces": [
"metrika-data"
],
"constraints": [
"READ-ONLY MCP; активен при живом лендинге (Б-1)",
"НЕ подбор ключевых слов (Wordstat #79)"
],
"preview-form": "none",
"defaults": ["read-only чтение метрик"],
"key-decisions": ["какие метрики смотреть"],
"acceptance-criteria": ["аналитика лендинга получена из Метрики"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"read-only чтение метрик"
],
"key-decisions": [
"какие метрики смотреть"
],
"acceptance-criteria": [
"аналитика лендинга получена из Метрики"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
@@ -1,12 +1,29 @@
{
"skill": "yandex-wordstat-mcp",
"kind": "external",
"needs": ["тема для подбора ключевых слов"],
"produces": ["частотность запросов РФ (Wordstat): сезонность, связанные фразы"],
"constraints": ["только Wordstat (5 read-only tools); Direct-мутации отключены (ADR-015)", "НЕ веб-аналитика (Метрика #78)"],
"needs": [
"keyword-topic"
],
"produces": [
"wordstat-frequency"
],
"constraints": [
"только Wordstat (5 read-only tools); Direct-мутации отключены (ADR-015)",
"НЕ веб-аналитика (Метрика #78)"
],
"preview-form": "none",
"defaults": ["только Wordstat-модуль"],
"key-decisions": ["набор ключевых фраз"],
"acceptance-criteria": ["ключевые слова подобраны с частотностью РФ"],
"source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" }
"defaults": [
"только Wordstat-модуль"
],
"key-decisions": [
"набор ключевых фраз"
],
"acceptance-criteria": [
"ключевые слова подобраны с частотностью РФ"
],
"source": {
"version": "n/a",
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
"path": ""
}
}
+40
View File
@@ -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);
});
});