добавлены плагины av-dev-tasks и av-dev-pipeline
Пара плагинов с намеренно проведённой границей: av-dev-tasks отвечает за то, что делаем и в каком порядке, av-dev-pipeline — за то, как ведём одну задачу. Зависимости между ними нет: управление задачами работает и с ручным исполнением, пайплайн — на проекте с любым учётом задач. - av-dev-tasks — преемник av-dev-backlog: цели вместо приоритетов, спринт под одну цель с заморозкой набора, различение вопроса и блокера, каденция «вопросы — разбор — переоценка — набор». Раскладка docs/tasks с items/, PLAN.md, BACKLOG.md, SPRINT.md, REJECTED.md; проверенное из av-dev-backlog перенесено, не переписано. - av-dev-pipeline — вынос того, что лежало копиями в healthlog и jellybit (3628 строк) и уже разошлось: цикл SDD, конвейер ревью с обязательным триажем, прогон нескольких задач разом. Проектная специфика вынесена в файл-бриф, charter'ы несут метод. Коммит фиксирует состояние на момент ревью: три прохода нашли блокирующие дефекты (нет шага, заводящего бриф; git rebase на занятой worktree ветке; sprint drop пишет наполовину) — они чинятся следующими коммитами. Сохранено как база, от которой видно правки.
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
# Бриф проекта — контракт
|
||||
|
||||
Конвейер общий, а находки — проектные. Проход, не знающий, что в этом проекте
|
||||
нельзя нарушать, чем краснеет гейт и сколько данных реально проходит через узел,
|
||||
выдаёт правдоподобные общие места: их дорого опровергать и нечем подтверждать.
|
||||
|
||||
Поэтому проектная специфика живёт **в одном файле проекта**, а не в charter'ах
|
||||
агентов. Charter описывает **метод** прохода (что он делает и почему именно так),
|
||||
бриф — **предмет** (что здесь дорого, чем это меряется, где лежит).
|
||||
|
||||
Шаблон для заполнения — [brief-template.md](brief-template.md).
|
||||
|
||||
## Где лежит и как находится
|
||||
|
||||
Порядок разрешения пути, одинаковый для скилла и для каждого агента:
|
||||
|
||||
1. путь, названный в задании конвейера (`бриф: <путь>`) — конвейер обязан его
|
||||
передавать каждому проходу;
|
||||
2. `docs/review-brief.md`;
|
||||
3. `.claude/review-brief.md`;
|
||||
4. брифа нет — **деградированный режим** (см. ниже).
|
||||
|
||||
Разрешает путь конвейер, один раз, и дальше передаёт готовым. Агент, получивший
|
||||
путь в задании, сам ничего не ищет.
|
||||
|
||||
## Деградированный режим
|
||||
|
||||
Брифа нет — проходы работают, но их recall падает предсказуемым образом, и это
|
||||
**обязано быть названо**, а не сглажено. Каждый проход без брифа:
|
||||
|
||||
- не присваивает `critical` по основанию «нарушен инвариант проекта» — инвариантов
|
||||
он не знает;
|
||||
- не оперирует числами объёма и потока — формулирует условиями;
|
||||
- пишет в границы покрытия строку: «брифа проекта нет: инварианты, модель угроз и
|
||||
профиль нагрузки неизвестны; находки этих классов не искались».
|
||||
|
||||
Триаж сводит эти строки в одну и выносит в финальный отчёт. Отсутствие брифа —
|
||||
дыра покрытия, а не нейтральное умолчание.
|
||||
|
||||
## Форма
|
||||
|
||||
Markdown. Разделы — заголовки второго уровня с **точными именами** из списка
|
||||
ниже: по ним агенты находят свой кусок. Порядок разделов свободен, лишние разделы
|
||||
допустимы и игнорируются, отсутствующий раздел работает как деградированный режим
|
||||
для тех проходов, которые его читают.
|
||||
|
||||
## Разделы
|
||||
|
||||
### `## Проект` — обязателен
|
||||
|
||||
Абзац: что система делает — и, что важнее, **чего она не делает**. Граница домена
|
||||
нужна архитектурному проходу как критерий: «хранилище, а не аналитика», «единое
|
||||
ядро, тонкие транспорты», «связующий сервис, а не медиатека». Без неё перенос
|
||||
понятия через границу выглядит просто новым кодом.
|
||||
|
||||
Читают: `architecture`, `rubric`, `reimpl`, `specs`.
|
||||
|
||||
### `## Инварианты` — обязателен
|
||||
|
||||
Список того, что нарушать нельзя. Каждый пункт — три вещи:
|
||||
|
||||
- формулировка **как проверяемое свойство**, а не как лозунг: «точка сохраняется
|
||||
дословно: незнакомое поле не отбрасывается», а не «бережно относимся к данным»;
|
||||
- **последствие нарушения** и его обратимость;
|
||||
- **severity по умолчанию** — если это не `critical`, скажи прямо.
|
||||
|
||||
Это единственный раздел, который **цитируется формулировкой**, а не пересказывается
|
||||
ссылкой: по нему присваивается severity, и пересказ здесь стоит неверной оценки.
|
||||
|
||||
Читают: `specs` (режим 1 — отражены ли задетые инварианты в спеке), `code`,
|
||||
`adversary`, `architecture`, `triage` (ранжирование и разметка «развилка»).
|
||||
|
||||
### `## Гейт` — обязателен
|
||||
|
||||
- **Команда** целиком, включая передачу базы диффа (`task gate BASE=<база>`), и
|
||||
как база определяется по умолчанию.
|
||||
- **Где логи** отдельных шагов.
|
||||
- **Что означает каждый исход**: чем гейт краснеет, что предупреждает, что
|
||||
пропускается по составу диффа.
|
||||
- **Шаги, которые красят безусловно, и почему.** Это самая ценная часть раздела:
|
||||
«данные под контролем версий», «структура конфига изменилась, а образец нет»,
|
||||
«миграции не накатываются с нуля» — проход обязан знать, что здесь не бывает
|
||||
«ну это мелочь».
|
||||
- **Чего в гейте намеренно нет** и почему — прогон на живом корпусе, длинный
|
||||
интеграционный тест. У проверки, которую гейт не гоняет, краснота никому не
|
||||
видна; это уезжает в границы покрытия.
|
||||
|
||||
Читает: `gate`.
|
||||
|
||||
### `## Команды` — обязателен
|
||||
|
||||
Что проход имеет право выполнить и чем:
|
||||
|
||||
- **карта проекта для архитектуры** — команда, отдающая пакеты, граф зависимостей
|
||||
и инвентарь концепций (`task review:context`);
|
||||
- **запуск изменения вживую** — чем поднять и как проверить поведение (нужно
|
||||
пайплайну задачи на шаге поведенческой верификации);
|
||||
- **тесты, линт, дополнительные проверки** — и какие из них дорогие;
|
||||
- **что запускать запрещено**: рабочая БД, боевой каталог данных, внешние
|
||||
сервисы. Формулируй запретом с путями, а не «будь осторожен».
|
||||
|
||||
Читают: `architecture`, `gate`, `ops`, `triage`, пайплайн задачи.
|
||||
|
||||
### `## Прод и поток` — обязателен
|
||||
|
||||
Материал для эксплуатационного прохода, и он же — половина ранжирования триажа:
|
||||
|
||||
- где это работает: машина, окружение, что рядом, кто перезапускает;
|
||||
- **внешние зависимости поимённо** и чем каждая отказывает: не только «падает», но
|
||||
и «отвечает медленно», «молчит», «отдаёт мусор». Эксплуатационный проход
|
||||
спрашивает про каждую отдельно, и список зависимостей он взять больше неоткуда;
|
||||
- **кто заметит отказ и когда** — есть ли вообще наблюдатель;
|
||||
- **характер потока**: непрерывный и молчаливый, по запросу, по расписанию; есть
|
||||
ли обратная связь у отправителя;
|
||||
- **измеренные числа с провенансом**: объёмы, размеры тел, темп, размеры таблиц.
|
||||
Число без источника проход обязан превратить в условие — так и напиши, откуда
|
||||
оно;
|
||||
- **что обратимо, а что нет.** Падение, которое лечится повтором, и тихая потеря,
|
||||
которую нечем восстановить, — разные классы, и порядок находок в отчёте зависит
|
||||
от того, какой из них здесь главный.
|
||||
|
||||
Читают: `ops`, `adversary`, `triage`, `reimpl`.
|
||||
|
||||
### `## Модель угроз` — обязателен
|
||||
|
||||
- **что недоверенное** и каким каналом приходит: тело запроса, файл, аргумент
|
||||
команды, ответ внешней системы, содержимое архива;
|
||||
- **из чего строятся пути и ключи** — раскладка файлов на диске, состав
|
||||
координатного ключа записи, имя каталога. Враждебный проход выводит запись за
|
||||
пределы песочницы именно отсюда, и без этого пункта он ищет вслепую;
|
||||
- **что разграничивает доступ** — токены, контуры, права файлов;
|
||||
- **что чувствительнее чего**: если данные дороже секретов, скажи это прямо;
|
||||
- **что вне модели** — перечислить явно. Пустой пункт «вне модели» означает, что
|
||||
враждебный проход выдумает угрозу сам, и находка никогда не будет исправлена.
|
||||
|
||||
Читает: `adversary`.
|
||||
|
||||
### `## Карта` — обязателен
|
||||
|
||||
Где что лежит, путями:
|
||||
|
||||
- актуальные спеки и дельта-спеки предлагаемого изменения;
|
||||
- конвенции прозой — и **какая их часть уже механизирована** правилом (её проход
|
||||
по конвенциям не проверяет);
|
||||
- архитектура и решения; журнал проскочивших дефектов;
|
||||
- **единые точки проекта** — где генерируются идентификаторы и время, где
|
||||
единственный парсер входного формата, где маппинг доменной ошибки в код ответа,
|
||||
где общий путь приёма. Это материал для вопроса «не появился ли второй способ»;
|
||||
если команда карты проекта их выгружает, здесь хватит ссылки на неё;
|
||||
- **нумерованные артефакты** — путь миграций и правило нумерации: батч раздаёт
|
||||
номера заранее, чтобы параллельные задачи не столкнулись файлами;
|
||||
- где ведутся задачи (пайплайн только читает и сообщает исход);
|
||||
- `testdata` и что в них лежит; куда можно писать временное;
|
||||
- **каталоги, которые не трогают вовсе**.
|
||||
|
||||
Читают: все проходы.
|
||||
|
||||
### `## Типовые узлы` — необязателен, но без него рубрика беднеет
|
||||
|
||||
Роды узлов, из которых состоит проект (парсер входного формата, HTTP-обработчик,
|
||||
репозиторий, воркер, клиент внешнего API, CLI-команда, файловое хранилище), и по
|
||||
3–5 **специфичных для рода** проверяемых свойств к каждому.
|
||||
|
||||
Читает: `rubric`. Без раздела рубрика выродится в общие слова и повторит
|
||||
конвенции — то есть станет applicative-проходом, ради отсутствия которого она и
|
||||
существует.
|
||||
|
||||
### `## Триггеры` — необязателен
|
||||
|
||||
Проектная конкретизация правила выбора профиля: какие пути и контракты означают
|
||||
`deep`; что считается «поведением, видимым снаружи»; при каком изменении
|
||||
запускается `reimpl`. Умолчания записаны в самом скилле и работают без этого
|
||||
раздела — но общее правило говорит «изменение публичного контракта», а какой
|
||||
контракт публичный, знает только проект.
|
||||
|
||||
Читают: скилл конвейера, пайплайн задачи.
|
||||
|
||||
### `## Недоступно проверке` — обязателен
|
||||
|
||||
Что не проверит ни один проход и почему: поведение внешних систем и их будущих
|
||||
версий, реальный профиль нагрузки, соответствие сохранённого действительности,
|
||||
завязка внешних потребителей на текущую форму, суждение «а нужна ли эта
|
||||
функциональность».
|
||||
|
||||
Этот раздел целиком уезжает в границы покрытия финального отчёта. Он существует
|
||||
ровно затем, чтобы «критичных проблем не обнаружено» никогда не читалось как
|
||||
«проверено всё».
|
||||
|
||||
Читает: `triage`; каждый проход — свою часть.
|
||||
|
||||
## Правила ведения
|
||||
|
||||
- **Бриф не пересказывает документацию проекта.** Факт, записанный в `CLAUDE.md`
|
||||
или в архитектуре, попадает сюда ссылкой и одной строкой сути. Два дома для
|
||||
одного факта разъезжаются, и разошедшийся бриф хуже отсутствующего: он выглядит
|
||||
актуальным. Исключение одно — раздел инвариантов, он цитируется.
|
||||
- **Числа — с провенансом.** «Тела доходили до 42 МБ (замер, ссылка)». Число без
|
||||
источника проход не имеет права использовать как утверждение.
|
||||
- **Что вне модели — называется явно.** Это относится и к угрозам, и к нагрузке,
|
||||
и к классам находок, которые проект сознательно перестал проверять.
|
||||
- **Бриф подчиняется промоуту.** Свойство, ставшее правилом линтера, из брифа
|
||||
вычёркивается — как и из конвенций, и из charter'ов (см.
|
||||
[promote.md](promote.md), шаг 3).
|
||||
- **Когда обновлять:** сменился гейт; появился новый контур, зависимость или
|
||||
источник входа; журнал ревью получил запись вида «проход не мог этого знать».
|
||||
Планового пересмотра нет.
|
||||
- **Бриф ведёт проект**, а не плагин. Плагин его только читает и никогда не
|
||||
правит.
|
||||
Reference in New Issue
Block a user