Files
portal/docs/superpowers/specs/2026-05-24-controller-offload-agents-design.md
T
Дмитрий 5c1e177237 docs(spec): controller-offload agents design (normative-sync + prod-deploy-validator)
Spec for two specialized AI agents to offload the main controller:
- #1 normative-sync: applies 4-file normative sync (Pravila/PSR/Tooling/CLAUDE.md)
  after a completed task. ~20 invocations/week, saves ~70K controller tokens
  per episode. Model: Sonnet 4.6.
- #2 prod-deploy-validator: 8-check pre-flight before liderra.ru deploy.
  ~5-7 invocations/week. Driven by 24.05 03:46 UTC 18-min portal incident
  (quirk 107 — config:cache not under www-data). Model: Sonnet 4.6.

Based on brainstorming session 24.05 with measured frequencies from
MEMORY.md + CLAUDE.md §6 + push history 16-24.05.

Precedents: pest-parallel-debugger, rls-reviewer project agents.

Also: +7 cspell-words entries for the new spec.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 15:11:43 +03:00

266 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Спек: два специализированных ИИ-помощника для разгрузки главного исполнителя
**Версия:** 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: <slug>
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` после первой недели использования (что работает / что нет)