diff --git a/cspell-words.txt b/cspell-words.txt index 54260597..06fab03a 100644 --- a/cspell-words.txt +++ b/cspell-words.txt @@ -1710,3 +1710,12 @@ FNS # Hole #2 partitioning (23.05.2026) партиционировать дёшева + +# Controller-offload agents spec (24.05.2026) +синков +эскалировать +эскалирует +митигации +Версионная +квирках +NTFS diff --git a/docs/superpowers/specs/2026-05-24-controller-offload-agents-design.md b/docs/superpowers/specs/2026-05-24-controller-offload-agents-design.md new file mode 100644 index 00000000..3a2db9e1 --- /dev/null +++ b/docs/superpowers/specs/2026-05-24-controller-offload-agents-design.md @@ -0,0 +1,265 @@ +# Спек: два специализированных ИИ-помощника для разгрузки главного исполнителя + +**Версия:** v1.0 от 24.05.2026 +**Статус:** Draft — pre-implementation +**Источник:** brainstorming-сессия 24.05.2026 (memory: MEMORY.md + CLAUDE.md §6 + push-история 16-24.05) +**Связано:** Pravila §15 (параллельные сессии), §16 (brain governance), CLAUDE.md §3.6, project-скилы `pest-parallel-debugger` / `rls-reviewer` (прецеденты узко-специализированных проектных агентов) + +--- + +## 1. Контекст и проблема + +За 8 дней (16-24.05.2026) главный исполнитель (Opus 4.7) совершил повторяющиеся операции двух типов: + +1. **Синк 4 нормативных файлов** (Pravila / PSR_v1 / Tooling / CLAUDE.md) — 26 эпизодов (v2.3→v2.27). После каждой задачи приходится править шапки, cross-refs §0, footer-счётчики, §9-changelog в 4 местах. Низкая когнитивная нагрузка, высокая частота, error-prone (известны 2 эпизода версионной коллизии параллельных веток — A11 v2.10 и discovery v2.13). + +2. **Pre-flight перед выкатом на боевой liderra.ru** — ~10 выкатов с 22.05 по 24.05. 24.05 в 03:46 UTC случился живой 18-минутный инцидент (портал лёг полностью) из-за пропущенной проверки `bootstrap/cache/config.php` под `www-data` (квирк 107). Корень — pre-flight чек-лист в голове, не формализован. + +Оба класса — идеальные кандидаты на отдельных ИИ-помощников: ограниченный вход/выход, повторяющийся, требует понимать смысл (не просто regex), но не творчества. + +--- + +## 2. Цели и измеримые KPI + +| Метрика | Цель | +|---------|------| +| Сокращение токенов главного исполнителя на нормативный синк | -90% (с ~70К до ~5К на эпизод) | +| Сокращение токенов главного исполнителя на pre-flight выката | -85% (с ~25К до ~3К на эпизод) | +| Доля автоматизированных синков от общего числа | ≥80% (некоторые требуют ручного — major-bump решения, новые off-phase подкатегории) | +| Live-инциденты из-за пропущенных pre-flight проверок | 0 за квартал (текущий baseline: 1 инцидент за 3 дня) | +| Цена операции (USD) | синк: $0.30/эпизод (было $0.60); выкат: $0.20/эпизод (было $0.35) | + +--- + +## 3. Агент №1: `normative-sync` + +### 3.1. Назначение + +Применить нормативный синк 4 файлов (Pravila / PSR_v1 / Tooling / CLAUDE.md) после завершённой задачи, на основе brief'а главного исполнителя или git-diff. + +### 3.2. Когда зовётся + +- После завершения off-phase tooling integration (~3-5/неделю) +- После выпуска brain governance артефактов (схема v2/v3, новый контролёр, новый skill) +- После принятого ADR +- После любого эпизода, который меняет cross-ref пространство нормативки + +Главный исполнитель решает зовёт или нет — агент не активируется автоматически. + +### 3.3. Входной brief (минимум) + +- Тема эпизода в одной строчке (например: «закрыли C1 marketing — 10 новых узлов #74-83, 18-я off-phase подкатегория marketing-tooling») +- Опционально: явные version-bump targets (если minor/major решение нетривиальное) +- Опционально: ADR-номер если есть + +### 3.4. Процедура (10 шагов) + +1. **Pre-flight per Pravila §15.2:** `git fetch && git log HEAD..origin/main --oneline` — если есть unpushed коммиты от параллельной сессии в 8-файловом списке, остановиться и эскалировать. +2. **Контекст:** прочитать `git diff HEAD~N..HEAD --stat` чтобы понять scope. +3. **Чтение нормативки:** Pravila / PSR_v1 / Tooling / CLAUDE.md (только релевантные секции — §0, §9 / §10 history, footer-счётчики). +4. **Вычисление новых версий** по правилам: + - minor (+0.01): добавили узел / методический параграф / cross-ref / запись в §9 + - major (+1.0): убрали правило / архитектурная инверсия / снят hard-rule +5. **Шапки:** обновить дату + версию в шапках 4 файлов. +6. **§0 cross-refs (CLAUDE.md):** обновить строки таблицы версий Pravila/PSR/Tooling до новых номеров. +7. **Footer-счётчики (если добавился узел):** Tooling §0 (КАНОН СЧЁТЧИКОВ) + CLAUDE.md §3.3 footer + §1 row 2b + §3 title. PSR_v1 R10.1 если добавился plugin/skill. +8. **§9 / История версий записи:** один абзац в каждом из 4 файлов по шаблону «vX.Y от ДД.ММ — тема. Изменения: ... Связано: ...». +9. **lefthook cross-ref-checker (C2):** `lefthook run cross-ref-checker || npx lefthook run cross-ref-checker` — если красный, итерация. +10. **Выход:** не коммитит. Отдаёт diff + краткий рапорт «синк готов, версии bumped X→Y, cross-refs verified, lefthook C2 green, добавил §9 в 4 файлах». + +### 3.5. Модель и инструменты + +- **Модель:** Sonnet 4.6 (Pravila §15.1 — для git-операций обязательно Sonnet/Opus, не Haiku) +- **Tools:** Read, Edit, Grep, Glob, Bash, TodoWrite +- **Skills:** + - `superpowers:verification-before-completion` — перед итоговым рапортом убедиться что cross-ref-checker зелёный + +### 3.6. Что зашиваем в system prompt + +- Структура 4 файлов (где шапка / §0 cross-refs / footer-счётчики / §9-changelog) +- Правила version-bump (minor vs major) +- Pravila §15.2 8-файловый список + pre-flight протокол +- Pravila §5 п.10 worktree-эксцепшн (когда прямой Edit, когда `claude-md-management:claude-md-improver`) +- Tooling §0 «КАНОН СЧЁТЧИКОВ» (отсюда и только отсюда числа) +- Шаблон §9-записи (дата, тема, изменения, cross-refs, канал, прецедент) +- Стиль changelog (примеры — последние 5 записей из CLAUDE.md §9) + +### 3.7. Границы (out of scope) + +- Не правит код, миграции, схему БД +- Не пишет ADR (только цитирует уже принятый) +- Не правит саму карту `docs/automation-graph.html` (если в эпизоде менялась карта — это отдельная задача главного исполнителя) +- Не коммитит, не пушит — только готовит diff +- Не принимает решения о major bump — если не уверен, эскалирует на главного исполнителя + +### 3.8. Риски и митигации + +| Риск | Митигация | +|------|-----------| +| Версионная коллизия с параллельной веткой | Pre-flight §15.2 на шаге 1 — STOP при unpushed коммитах от других | +| Drift cross-ref (4 файла указывают друг на друга со старыми версиями) | lefthook cross-ref-checker (C2) на шаге 9 | +| Неправильный bump (minor вместо major) | Решение minor по умолчанию; major только при явном указании в brief'е или при удалении правила | +| Пропуск footer-счётчика | Чек-лист TodoWrite внутри агента (8 пунктов структурных правок) | +| Самовольное добавление «improvements» в несвязанные секции | Жёсткое scope-правило в system prompt: «правишь только шапки, §0, footer, §9; всё остальное — STOP» | + +### 3.9. Что отдаёт + +- 4 изменённых файла в рабочем дереве (uncommitted) +- Рапорт ~10 строк: «синк завершён, версии X→Y, cross-refs verified, lefthook C2 green, добавлены §9 в [файлы], затронуто [N] секций» +- Список любых эскалаций («нужен ручной выбор major/minor», «обнаружена коллизия с веткой Y», «cross-ref-checker красный после 3 итераций») + +--- + +## 4. Агент №2: `prod-deploy-validator` + +### 4.1. Назначение + +Pre-flight checklist перед выкатом на боевой `liderra.ru`. Возвращает вердикт `GO / NO-GO` с конкретной причиной. + +### 4.2. Когда зовётся + +Перед каждым выкатом — главный исполнитель просит «проверь готовность боевого». ~5-7 раз в неделю в активные периоды. + +### 4.3. Входной brief (минимум) + +- Что планируется выкатить (commit hash или короткое описание) +- Опционально: явный список файлов в патче (если выкат через scp, не через git) + +### 4.4. 8 проверок + +| # | Проверка | Команда | Зелёный = | Красный = | +|---|----------|---------|-----------|-----------| +| **П1** | `bootstrap/cache/config.php` владельца | `ssh liderra "stat -c '%U %Y' app/bootstrap/cache/config.php; stat -c '%Y' app/.env"` | владелец `www-data` И mtime ≥ mtime .env | владелец не www-data ИЛИ старее .env (квирк 107) | +| **П2** | `.env` line endings | `ssh liderra "file app/.env; md5sum app/.env"` | `ASCII text` (без CRLF) | `with CRLF line terminators` (квирк 105) | +| **П3** | Свободное место | `ssh liderra "df -h /"` | использовано ≤ 85% | > 85% | +| **П4** | Последний бэкап БД | `ssh liderra "ls -lt /var/backups/db/ \| head -2"` | mtime ≤ 24 часов назад | > 24 часов или пусто | +| **П5** | Health очереди | `ssh liderra "pgrep -fa queue:work; tail -50 app/storage/logs/laravel.log \| grep -ic -e failed -e error"` | `queue:work` процесс активен И ≤ 5 ошибок в последних 50 строках laravel.log | процесс мёртв ИЛИ > 5 ошибок | +| **П6** | nginx config | `ssh liderra "sudo nginx -t"` | `syntax is ok` + `test is successful` | любое иное | +| **П7** | fail2ban активен | `ssh liderra "sudo systemctl is-active fail2ban"` | `active` | `inactive` / `failed` | +| **П8** | Pending миграции | `ssh liderra "cd app && php artisan migrate:status \| grep -c Pending"` | 0 ИЛИ список к выкату согласован с brief'ом | необъявленные pending | + +### 4.5. Процедура (5 шагов) + +1. Принять brief — что выкатываем. +2. Запустить 8 проверок последовательно (параллельность по SSH не даёт большого выигрыша, sequential проще для отладки). +3. Собрать результаты в таблицу из 8 строк. +4. Применить решающее правило: + - Все 8 зелёных → **GO** + список smoke-команд для пост-выкатной проверки + - Хоть одна красная → **NO-GO** + причина + ссылка на квирк memory + что делать чтобы исправить + - Любая «не смог проверить» (SSH-таймаут, неожиданный формат) → **NO-GO с эскалацией** («нужен человек, агент не угадывает») +5. Опционально (если brief содержит `--post-smoke`): после выката повторить smoke-проверки (HTTP 200 на главной, миграция применилась, очередь жива). + +### 4.6. Модель и инструменты + +- **Модель:** Sonnet 4.6 +- **Tools:** Bash, Read, Grep +- **Skills:** + - `superpowers:verification-before-completion` — перед итоговым GO убедиться что все 8 проверок прогнаны (не одна пропущена) + +### 4.7. Что зашиваем в system prompt + +- 8 точных команд + ожидаемые форматы вывода +- Память о квирках 104-108 (с MEMORY.md цитатами): + - 104: stale `bootstrap/cache/config.php` переживает .env-фикс + - 105: scp Windows→Linux кладёт CRLF в .env → sqlite-fallback → 500 + - 106: `queue:work --timeout` default 60s убивает worker сам себя + - 107: `config:cache` НЕ из-под www-data → кэширует defaults → 500 (24.05 03:46 UTC) + - 108: NTFS junction для worktree node_modules +- Шаблон отчёта (таблица + вердикт + smoke-команды) +- SSH-настройки (читает из `~/.ssh/config`, никаких паролей в system prompt) + +### 4.8. Границы (out of scope) + +- Сам выкат не делает (только проверяет готовность). Выкат — главный исполнитель. +- Не трогает базу данных (только smoke-чтение). +- Не меняет конфиги на боевом. +- Не угадывает: если вывод команды не соответствует шаблону — NO-GO с эскалацией, не «возможно нормально». + +### 4.9. Риски и митигации + +| Риск | Митигация | +|------|-----------| +| Новый квирк, которого нет в его памяти | Любой неожиданный output → автоматически NO-GO + эскалация. Через 1-2 эпизода добавляю в его system prompt. | +| SSH-таймаут / сеть лежит | Жёсткий timeout 30 сек на проверку. Если 2+ проверки таймнули — отчёт «не смог проверить, выкат на свой риск». | +| Что-то не покрыто 8 проверками | Со временем расширяю список. Агент сам границы не двигает. | +| Ложно-положительный GO (агент пропустил проблему) | Я смотрю отчёт перед нажатием. Агент не выкатывает сам — только сообщает. | + +### 4.10. Что отдаёт + +- Таблица 8 строк с green/red статусом каждой проверки +- Вердикт **GO** или **NO-GO** +- Если NO-GO — конкретная причина + ссылка на квирк memory + что нужно сделать +- Если GO — список smoke-команд для пост-выкатной проверки + +--- + +## 5. Общие архитектурные решения + +### 5.1. Где живут определения агентов + +Project-local в `.claude/agents/normative-sync.md` и `.claude/agents/prod-deploy-validator.md` — по образцу `.claude/agents/pest-parallel-debugger.md` и `.claude/agents/rls-reviewer.md` (прецеденты узко-специализированных проектных агентов). + +### 5.2. Frontmatter каждого агента + +```yaml +--- +name: +description: <когда зовётся — для триггер-классификации> +tools: <ограниченный список> +model: claude-sonnet-4-6 +--- +``` + +### 5.3. Скилы которые **не** даём ни одному из этих агентов + +- `brainstorming`, `writing-plans`, `executing-plans` — это исполнители, не проектировщики +- `test-driven-development`, `frontend-design`, `mcp-builder` — не их scope +- `superpowers:dispatching-parallel-agents` — они листовые, не дирижируют + +### 5.4. Subagent-driven git-safety (Pravila §15.1) + +Оба агента работают с git (один правит файлы → git diff отдаёт; второй делает SSH но не git). Главный исполнитель ВСЕ ЕЩЁ обязан верифицировать commit-базу (`git rev-parse HEAD`) ПОСЛЕ каждого вызова `normative-sync`-агента, до коммита его diff'а. + +### 5.5. Привязка к Brain governance (Pravila §16) + +- Stop-hook будет писать routing_decision и для этих агентов (provenance `user_directed_method` — главный исполнитель явно их позвал) +- `task_classification` маппинг (tools/observer-classification-map.json) расширить: `normative_sync` → узел `agent:normative-sync`; `prod_deploy_validation` → узел `agent:prod-deploy-validator`. После добавления — missed-activation детектор будет ловить случаи когда я делаю синк сам вместо вызова агента. + +--- + +## 6. Что вне scope этого спека + +- Создание агента «#3 разборщик карты наблюдателя» (отложен — частота 1-2/неделю, ROI ниже) +- Создание агента «off-phase tooling integrator» (отброшен — слишком broad для одного агента) +- Автоматическое добавление в `task_classification` маппинг (это отдельная задача brain governance) +- Замена существующих агентов `pest-parallel-debugger` / `rls-reviewer` (они работают, не трогаем) +- Какие-либо изменения нормативки (Pravila / PSR / Tooling / CLAUDE.md) для регистрации этих агентов — это произойдёт ВО ВРЕМЯ первого использования каждого агента (тогда сами агенты впишут себя в footer-счётчик, классическая dogfooding-проверка) + +--- + +## 7. Открытые вопросы + +- **OQ-1:** Должны ли агенты иметь доступ к `mcp__redis__*` / `mcp__laravel-boost__*` для расширенных pre-flight проверок? **Решение по умолчанию:** нет, минимальный tools-set; расширим если понадобится после первой недели использования. +- **OQ-2:** Нужно ли запускать `normative-sync` через TaskOutput с фоновым режимом (агент работает в фоне, я делаю что-то другое)? **Решение по умолчанию:** нет, синхронный вызов (1-2 мин ожидания не критично). +- **OQ-3:** Должен ли `prod-deploy-validator` уметь делать сам бэкап БД если П4 красная? **Решение по умолчанию:** нет, только отчёт. Действия — главный исполнитель. + +--- + +## 8. Прецеденты в проекте + +- **`.claude/agents/pest-parallel-debugger.md`** — узко-специализированный диагностический агент для Pest-quirks 72/73/77. Прецедент проектного агента с tools-restriction. +- **`.claude/agents/rls-reviewer.md`** — узко-специализированный review-агент для RLS на миграциях. Прецедент агента с явным «when to invoke». +- **`docs/superpowers/specs/2026-05-19-brain-governance-design.md`** — прецедент спека на инфраструктурное изменение через спек → план → реализация. + +--- + +## 9. Следующий шаг + +После согласования этого спека — `superpowers:writing-plans` создаст implementation plan с задачами: + +1. Написать `.claude/agents/normative-sync.md` (system prompt + tools + frontmatter) +2. Написать `.claude/agents/prod-deploy-validator.md` (то же) +3. Smoke-тест №1 на dry-run (свежий синк, например post-billing-v2-spec-c) +4. Smoke-тест №2 на dry-run (pre-flight перед следующим выкатом) +5. Расширить `tools/observer-classification-map.json` двумя классификациями +6. Запись в memory `feedback_specialized_agents.md` после первой недели использования (что работает / что нет)