From 702a8d704c2ada3a69a87f436d1fb3a537aea00c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Mon, 8 Jun 2026 18:44:20 +0300 Subject: [PATCH] =?UTF-8?q?feat(contracts):=20=D0=BA=D0=B0=D1=80=D1=82?= =?UTF-8?q?=D0=BE=D1=87=D0=BA=D0=B8=20phase-1=20+=20phase-2=20(#10-#30)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 16 карточек: phase-1 (boost, pint, larastan, roave-security, ide-helper, squawk, pg-formatter, pg-partman[dormant], pest) + phase-2 (superpowers[own,зонтик], volar, vue-tsc, eslint-prettier, vitest, histoire, frontend-design). superpowers = own (без source); остальные external (zero-hash + path"" → G4 инертен). m3a 3/3 GREEN. coverage: skill:executing-plans --- docs/registry/contracts/boost.contract.json | 12 ++++++++++++ .../registry/contracts/eslint-prettier.contract.json | 12 ++++++++++++ .../registry/contracts/frontend-design.contract.json | 12 ++++++++++++ docs/registry/contracts/histoire.contract.json | 12 ++++++++++++ docs/registry/contracts/ide-helper.contract.json | 12 ++++++++++++ docs/registry/contracts/larastan.contract.json | 12 ++++++++++++ docs/registry/contracts/pest.contract.json | 12 ++++++++++++ docs/registry/contracts/pg-formatter.contract.json | 12 ++++++++++++ docs/registry/contracts/pg-partman.contract.json | 12 ++++++++++++ docs/registry/contracts/pint.contract.json | 12 ++++++++++++ docs/registry/contracts/roave-security.contract.json | 12 ++++++++++++ docs/registry/contracts/squawk.contract.json | 12 ++++++++++++ docs/registry/contracts/superpowers.contract.json | 11 +++++++++++ docs/registry/contracts/vitest.contract.json | 12 ++++++++++++ docs/registry/contracts/volar.contract.json | 12 ++++++++++++ docs/registry/contracts/vue-tsc.contract.json | 12 ++++++++++++ 16 files changed, 191 insertions(+) create mode 100644 docs/registry/contracts/boost.contract.json create mode 100644 docs/registry/contracts/eslint-prettier.contract.json create mode 100644 docs/registry/contracts/frontend-design.contract.json create mode 100644 docs/registry/contracts/histoire.contract.json create mode 100644 docs/registry/contracts/ide-helper.contract.json create mode 100644 docs/registry/contracts/larastan.contract.json create mode 100644 docs/registry/contracts/pest.contract.json create mode 100644 docs/registry/contracts/pg-formatter.contract.json create mode 100644 docs/registry/contracts/pg-partman.contract.json create mode 100644 docs/registry/contracts/pint.contract.json create mode 100644 docs/registry/contracts/roave-security.contract.json create mode 100644 docs/registry/contracts/squawk.contract.json create mode 100644 docs/registry/contracts/superpowers.contract.json create mode 100644 docs/registry/contracts/vitest.contract.json create mode 100644 docs/registry/contracts/volar.contract.json create mode 100644 docs/registry/contracts/vue-tsc.contract.json diff --git a/docs/registry/contracts/boost.contract.json b/docs/registry/contracts/boost.contract.json new file mode 100644 index 00000000..91291692 --- /dev/null +++ b/docs/registry/contracts/boost.contract.json @@ -0,0 +1,12 @@ +{ + "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)"], + "preview-form": "none", + "defaults": ["read-first; serverить только установленные пакеты (Roster)"], + "key-decisions": ["источник: только dev-БД, не прод"], + "acceptance-criteria": ["запрос/доки отданы из правильного (dev) источника"], + "source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" } +} diff --git a/docs/registry/contracts/eslint-prettier.contract.json b/docs/registry/contracts/eslint-prettier.contract.json new file mode 100644 index 00000000..6924f384 --- /dev/null +++ b/docs/registry/contracts/eslint-prettier.contract.json @@ -0,0 +1,12 @@ +{ + "skill": "eslint-prettier", + "kind": "external", + "needs": ["JS/Vue-код для линта+форматирования"], + "produces": ["исправленный/проверенный JS/Vue по ESLint+Prettier"], + "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": "" } +} diff --git a/docs/registry/contracts/frontend-design.contract.json b/docs/registry/contracts/frontend-design.contract.json new file mode 100644 index 00000000..e6afa74a --- /dev/null +++ b/docs/registry/contracts/frontend-design.contract.json @@ -0,0 +1,12 @@ +{ + "skill": "frontend-design", + "kind": "external", + "needs": ["UI-задача: компонент / паттерн / состояние / a11y-принцип"], + "produces": ["доменное решение UI/UX (компоненты, паттерны, a11y-принципы)"], + "constraints": ["доменная база UI для Vue+Vuetify; обязательный стек-фильтр R6.0", "paired со #19", "технический a11y — за Pa11y, не здесь"], + "preview-form": "mockup", + "defaults": ["срезать React/Tailwind/shadcn → Vue 3 + Vuetify 3; палитра Forest из Brandbook"], + "key-decisions": ["компонент/паттерн под задачу в рамках стека"], + "acceptance-criteria": ["решение в стеке Vue+Vuetify, бренд Forest соблюдён"], + "source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" } +} diff --git a/docs/registry/contracts/histoire.contract.json b/docs/registry/contracts/histoire.contract.json new file mode 100644 index 00000000..8f5eaa3e --- /dev/null +++ b/docs/registry/contracts/histoire.contract.json @@ -0,0 +1,12 @@ +{ + "skill": "histoire", + "kind": "external", + "needs": ["Vue-компонент для каталога stories"], + "produces": ["визуальный каталог stories/variants"], + "constraints": ["каталог компонентов (не Storybook)", "Vuetify через setupFile"], + "preview-form": "sample", + "defaults": ["npm run story"], + "key-decisions": ["какие компоненты/variants в каталоге"], + "acceptance-criteria": ["stories собираются и рендерятся"], + "source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" } +} diff --git a/docs/registry/contracts/ide-helper.contract.json b/docs/registry/contracts/ide-helper.contract.json new file mode 100644 index 00000000..c55993a1 --- /dev/null +++ b/docs/registry/contracts/ide-helper.contract.json @@ -0,0 +1,12 @@ +{ + "skill": "ide-helper", + "kind": "external", + "needs": ["Laravel-проект (facades/модели/хелперы)"], + "produces": ["IDE-заглушки (@mixin IdeHelper*) для autocomplete/type-inference"], + "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": "" } +} diff --git a/docs/registry/contracts/larastan.contract.json b/docs/registry/contracts/larastan.contract.json new file mode 100644 index 00000000..d8c9c2a0 --- /dev/null +++ b/docs/registry/contracts/larastan.contract.json @@ -0,0 +1,12 @@ +{ + "skill": "larastan", + "kind": "external", + "needs": ["PHP-код для статанализа типов"], + "produces": ["отчёт об ошибках типов/сигнатур/undefined-переменных"], + "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": "" } +} diff --git a/docs/registry/contracts/pest.contract.json b/docs/registry/contracts/pest.contract.json new file mode 100644 index 00000000..6dd6fdb5 --- /dev/null +++ b/docs/registry/contracts/pest.contract.json @@ -0,0 +1,12 @@ +{ + "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)"], + "preview-form": "none", + "defaults": ["composer test; --parallel в CI"], + "key-decisions": ["scope: какие тесты, parallel vs serial"], + "acceptance-criteria": ["все тесты зелёные, без регрессий"], + "source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" } +} diff --git a/docs/registry/contracts/pg-formatter.contract.json b/docs/registry/contracts/pg-formatter.contract.json new file mode 100644 index 00000000..dbbfcf56 --- /dev/null +++ b/docs/registry/contracts/pg-formatter.contract.json @@ -0,0 +1,12 @@ +{ + "skill": "pg-formatter", + "kind": "external", + "needs": ["SQL-файл для форматирования"], + "produces": ["отформатированный 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": "" } +} diff --git a/docs/registry/contracts/pg-partman.contract.json b/docs/registry/contracts/pg-partman.contract.json new file mode 100644 index 00000000..b02f8807 --- /dev/null +++ b/docs/registry/contracts/pg-partman.contract.json @@ -0,0 +1,12 @@ +{ + "skill": "pg-partman", + "kind": "external", + "needs": ["расписание партиционирования таблиц"], + "produces": ["авто-создание/удаление partition-таблиц по расписанию"], + "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": "" } +} diff --git a/docs/registry/contracts/pint.contract.json b/docs/registry/contracts/pint.contract.json new file mode 100644 index 00000000..102097bd --- /dev/null +++ b/docs/registry/contracts/pint.contract.json @@ -0,0 +1,12 @@ +{ + "skill": "pint", + "kind": "external", + "needs": ["PHP-код для форматирования"], + "produces": ["отформатированный PHP по PSR-12 + Laravel style"], + "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": "" } +} diff --git a/docs/registry/contracts/roave-security.contract.json b/docs/registry/contracts/roave-security.contract.json new file mode 100644 index 00000000..ca32d11f --- /dev/null +++ b/docs/registry/contracts/roave-security.contract.json @@ -0,0 +1,12 @@ +{ + "skill": "roave-security", + "kind": "external", + "needs": ["composer install/update"], + "produces": ["блок установки пакета с известным CVE"], + "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": "" } +} diff --git a/docs/registry/contracts/squawk.contract.json b/docs/registry/contracts/squawk.contract.json new file mode 100644 index 00000000..d210f4a0 --- /dev/null +++ b/docs/registry/contracts/squawk.contract.json @@ -0,0 +1,12 @@ +{ + "skill": "squawk", + "kind": "external", + "needs": ["SQL-миграция PostgreSQL"], + "produces": ["отчёт об опасных паттернах миграции (блокировки, без CONCURRENTLY, ненадёжный DEFAULT)"], + "constraints": ["линт миграций в pre-commit для database/migrations", "НЕ форматирование (pgFormatter)"], + "preview-form": "none", + "defaults": ["прогон на staged миграциях"], + "key-decisions": ["блокирующая операция vs допустимая"], + "acceptance-criteria": ["0 опасных паттернов в миграции"], + "source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" } +} diff --git a/docs/registry/contracts/superpowers.contract.json b/docs/registry/contracts/superpowers.contract.json new file mode 100644 index 00000000..5a16ecdf --- /dev/null +++ b/docs/registry/contracts/superpowers.contract.json @@ -0,0 +1,11 @@ +{ + "skill": "superpowers", + "kind": "own", + "needs": ["задача разработки, требующая процесса (TDD/debug/plan/review/brainstorm/worktree)"], + "produces": ["дисциплинированный процесс: тест-первый, план, ревью, верификация"], + "constraints": ["мета-процесс (зонтик 14 sub-skills), не доменный решатель", "hard-floor источник (ADR-011)", "paired со #30 Frontend Design"], + "preview-form": "outline", + "defaults": ["skill инвоцируется ПЕРВЫМ для подходящей задачи"], + "key-decisions": ["какой sub-skill под задачу (tdd/debugging/writing-plans/brainstorming/...)"], + "acceptance-criteria": ["процесс-скил применён ДО реализации, дисциплина соблюдена"] +} diff --git a/docs/registry/contracts/vitest.contract.json b/docs/registry/contracts/vitest.contract.json new file mode 100644 index 00000000..4fe439eb --- /dev/null +++ b/docs/registry/contracts/vitest.contract.json @@ -0,0 +1,12 @@ +{ + "skill": "vitest", + "kind": "external", + "needs": ["Vue-компоненты/модули для unit/component-тестов"], + "produces": ["результат прогона Vitest (pass/fail)"], + "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": "" } +} diff --git a/docs/registry/contracts/volar.contract.json b/docs/registry/contracts/volar.contract.json new file mode 100644 index 00000000..1cb66825 --- /dev/null +++ b/docs/registry/contracts/volar.contract.json @@ -0,0 +1,12 @@ +{ + "skill": "volar", + "kind": "external", + "needs": ["открытый .vue-файл в VSCode"], + "produces": ["IntelliSense / go-to-definition / hover / диагностика типов в редакторе"], + "constraints": ["VSCode-расширение (редактор-only)", "НЕ CI type-check (vue-tsc)"], + "preview-form": "none", + "defaults": ["работает в редакторе автоматически"], + "key-decisions": ["нет ручного выбора — редакторная служба"], + "acceptance-criteria": ["навигация/диагностика по .vue работают в редакторе"], + "source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" } +} diff --git a/docs/registry/contracts/vue-tsc.contract.json b/docs/registry/contracts/vue-tsc.contract.json new file mode 100644 index 00000000..145690ee --- /dev/null +++ b/docs/registry/contracts/vue-tsc.contract.json @@ -0,0 +1,12 @@ +{ + "skill": "vue-tsc", + "kind": "external", + "needs": [".vue-компоненты для проверки типов"], + "produces": ["отчёт о несоответствиях типов в шаблонах/script"], + "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": "" } +}