av-dev-pipeline: починены находки ревью, бриф заводится скиллом

- скилл project-brief: бриф собирается из CLAUDE.md, архитектуры, Taskfile
  и конвенций и показывается человеку. Раньше единственная инструкция по
  его созданию лежала внутри шаблона, поэтому деградированный режим был не
  аварийным, а единственным: critical по основанию «нарушен инвариант»
  недостижим ни на одной задаче
- rebase перенесён внутрь worktree задачи: прежняя форма падала на занятой
  ветке, и агент уводил весь батч в провалившиеся с ложной причиной
- контракт брифа дополнен восемью слотами; проверен заполнением на обоих
  проектах, незаполнимых нет. Прецедент healthlog вынут из общего charter'а
  в бриф — там он вмёрз вместе с числами
- шов: пайплайн задачу не закрывает и записи учёта не трогает, урожай
  отдаёт списком, правило остатка — ссылкой на av-dev-tasks
- деградированный абзац во всех девяти проходах, вопрос 9 в ops,
  пространство имён в вызовах, раздел предпосылок
This commit is contained in:
av
2026-08-03 11:45:40 +03:00
parent 20dca29add
commit 0eca206460
18 changed files with 1021 additions and 214 deletions
@@ -0,0 +1,127 @@
---
name: project-brief
description: Заводит или обновляет бриф ревью проекта (docs/review-brief.md) — файл, откуда конвейер ревью берёт инварианты, команду гейта, модель угроз, объёмы, прецеденты и карту проекта. Вызывать, когда брифа нет (это обнаруживают review-pipeline, task-pipeline и task-batch на старте), когда сменился гейт или появилась новая зависимость, и по прямой просьбе завести или обновить бриф.
---
# Заведение брифа проекта
Бриф — **предмет** ревью: что здесь нельзя нарушать, чем краснеет гейт, сколько
данных реально проходит, что необратимо. Без него конвейер работает в
деградированном режиме: `critical` по основанию «нарушен инвариант проекта»
недоступен ни одному проходу, числа объёма не используются, архитектурный проход
теряет свой главный критерий (граница домена) и вырождается в общее мнение.
Поэтому заведение брифа — **шаг, а не документ**. Этот скилл его выполняет.
- Контракт разделов — [контракт брифа](../review-pipeline/references/project-brief.md).
- Форма и образцы заполнения — [шаблон](../review-pipeline/references/brief-template.md).
## Когда вызывается
- **Автоматически**, без спроса: `av-dev-pipeline:review-pipeline`,
`av-dev-pipeline:task-pipeline` и `av-dev-pipeline:task-batch` разрешают путь к
брифу на старте и, не найдя его ни по одному пути, зовут этот скилл. Это не
развилка и не повод остановиться — заведение брифа делается молча, как любая
другая механика.
- **По событию:** сменился гейт; появился новый контур, зависимость или источник
входа; в журнал ревью попала запись вида «проход не мог этого знать»; свойство
промоутнулось в правило линтера (тогда пункт из брифа **вычёркивается**).
- **По просьбе человека.**
Планового пересмотра нет.
## Шаг 1. Убедиться, что брифа действительно нет
Порядок разрешения пути — тот же, что у конвейера:
1. путь, названный в задании;
2. `docs/review-brief.md`;
3. `.claude/review-brief.md`.
Файл есть, но неполон (нет обязательного раздела, раздел пуст, числа без
провенанса) — это **не** заведение с нуля: дозаполняй недостающее и не переписывай
то, что уже выверено. Разошедшийся бриф хуже отсутствующего, но переписанный
поверх выверенного — хуже разошедшегося.
## Шаг 2. Собрать материал из проекта
Бриф **выводится из проекта, а не сочиняется**. Источники по убыванию плотности:
| Раздел брифа | Откуда берётся |
|---|---|
| `## Проект` | `CLAUDE.md` / `AGENTS.md`, паспорт или README — абзац «что это и чего оно не делает» |
| `## Инварианты` | раздел инвариантов `CLAUDE.md`, архитектура, журнал решений; **цитируются формулировкой** |
| `## Гейт` | `Taskfile.yml` / `Makefile` / `justfile` / CI — сама цель гейта, состав её шагов, коды и логи |
| `## Команды` | тот же файл задач: карта проекта, поднять вживую, тесты, дорогое вне гейта, запрещённое |
| `## Прод и поток` | документация по деплою и архитектуре, конфиг и его образец, схема БД, файл наблюдений на живых данных |
| `## Модель угроз` | конфиг (токены, права), раскладка файлов на диске, схема ключей, места приёма недоверенного входа |
| `## Карта` | дерево репозитория: спеки, конвенции, архитектура, журнал ревью, миграции, `testdata`, основная ветка |
| `## Типовые узлы` | дерево пакетов: какие рода узлов реально есть |
| `## Прецеденты` | журнал ревью, архивные отчёты триажа, `git log` по починкам |
| `## Недоступно проверке` | журнал ревью (что решили не проверять) плюс общий список из контракта |
Прочитай `CLAUDE.md` и всё, на что он ссылается, **до** того, как писать первую
строку. Бриф, собранный из одного файла, повторяет его и потому бесполезен.
## Шаг 3. Заполнить
Идёшь по контракту раздел за разделом. Четыре правила ведения, из-за которых
брифы портятся чаще всего:
1. **Не пересказывай документацию.** Факт, записанный в `CLAUDE.md` или в
архитектуре, попадает сюда ссылкой и одной строкой сути. Исключение — раздел
инвариантов: он цитируется дословно, потому что по нему присваивается severity.
2. **Числа — с провенансом.** «Тела доходили до 42 МБ (замер,
`docs/local-research.md`)». Число без источника проход обязан превратить в
условие, то есть оно бесполезно.
3. **Пустой пункт называется пустым.** «Внешних зависимостей нет — смотри на диск
и на СУБД» стоит целого прохода: без этой строки эксплуатационный проход
потратит обязательный вопрос впустую или выдумает зависимость. То же про
угрозы вне модели, про отсутствующие прецеденты, про отсутствие наблюдателя.
4. **Не выдумывай четыре вещи.** Измеренные числа; периметр модели угроз; то, что
в этом проекте необратимо; и **кто обязан гонять дорогую проверку вне гейта**
— всё это из кода не выводится. Не нашёл в документации — **спроси человека на
шаге 4**, а до ответа напиши пункт словом «неизвестно» с пометкой, что он ждёт
ответа. Придуманное число здесь дороже отсутствующего: проход сошлётся на него
как на замер.
5. **Что выведено, а не прочитано, — помечай.** Чаще всего это severity у
инвариантов: проекты редко пишут её рядом с формулировкой, и её приходится
выводить по обратимости последствия. Пометка «выведена по обратимости» стоит
трёх слов и сообщает проходу, чьё это суждение, — а он по ней ставит
`critical`. То же для периметра, восстановленного из конфига, и для чисел, чей
источник по ссылке не подтвердился.
## Шаг 4. Показать человеку
Бриф — единственный файл, который конвейер **читает как истину**, поэтому он
показывается, а не заводится молча:
- покажи готовый файл (или дифф, если это обновление);
- отдельным коротким списком назови, **что выведено из проекта**, а что
**предположено или осталось неизвестным** — по этим строкам человек и правит;
- если на шаге 3 остались вопросы из класса «не выдумывай три вещи», задай их
здесь, разом и с вариантами.
Ответа ждать не обязательно: работа продолжается по заведённому брифу, а
неизвестные пункты честно стоят словом «неизвестно» — проход прочитает его как
деградацию по этому пункту, а не как факт.
**Бриф ведёт проект.** Файл кладётся в репозиторий проекта и коммитится вместе с
той работой, в ходе которой заведён. Плагин его больше не правит — он только
читает.
## Шаг 5. Вернуться в вызвавший шаг
Скажи вызвавшему скиллу путь к брифу — дальше конвейер передаёт его каждому
проходу готовым, и деградированный режим не включается.
## Если завести нельзя
Заведение отменяется ровно в трёх случаях: репозиторий доступен только на чтение;
человек прямо сказал брифа не заводить; проект настолько чужой, что вывести
инварианты неоткуда. Тогда — деградированный режим по контракту: строка в границы
покрытия и запрет на `critical` по основанию «нарушен инвариант проекта».
Во всех остальных случаях бриф заводится. «Задача маленькая, брифа не надо» —
не основание: бриф заводится один раз на проект, а деградированный режим платит
на каждой задаче.