- av-dev-tasks → av-dev-pm; канон определён единственным reference-файлом, который читают все три новых скилла - canon: check/adopt/upgrade плюс docs.py — раскладка, битые ссылки, версия, маркеры долга, сверки миграций и capability с документацией - tasks и session: путь docs/tasks жёсткий, конфиг переехал в docs/.pm.json, слот «Команда учёта задач» убран в пользу вызова скилла, раздел «Стимулы» переписан под совпавших приёмщика и исполнителя
124 lines
11 KiB
Markdown
124 lines
11 KiB
Markdown
# Ведение спринта
|
|
|
|
Спринт — набор задач под одну цель, замороженный до его конца. Здесь то, что
|
|
происходит **внутри** спринта: как задача заканчивается, что считается сделанным,
|
|
кто принимает и что идёт в доклад. Как спринт набирается — шаг 4 в
|
|
[cadence.md](cadence.md).
|
|
|
|
## Наблюдаемые исходы задачи
|
|
|
|
Как они достигаются — дело пайплайна проекта. Сессия знает только исход и его
|
|
след.
|
|
|
|
- **Сделана** — по определению готовности ниже. `close <slug> --implemented`:
|
|
файл и строка удаляются, следом остаётся коммит. **Закрывает владелец спринта
|
|
и только после вердикта приёмки** — см. «Кто и когда закрывает».
|
|
- **Вышла из спринта** — `sprint drop <slug> --reason …`: возвращается в беклог
|
|
с вопросом в файле и **без живого незакоммиченного предложения** — иначе при
|
|
следующем взятии оно столкнётся с новым. Наработки, которые жалко терять,
|
|
переезжают в тело задачи текстом.
|
|
- **Переросла в эпик** — распознаётся **до того, как под неё заведено
|
|
предложение об изменении**, иначе его придётся выбрасывать. Помечается
|
|
`[epic]`, выходит из набора, уходит на декомпозицию; спринт продолжается
|
|
остальными, части в замороженный набор не добавляются.
|
|
- **Отменена решением по ходу** — `close <slug> --reason "<ссылка на решение>"`
|
|
прямо из спринта. Это редкий, но законный исход, и он называется в докладе.
|
|
|
|
**Конец спринта** — когда по каждой задаче набора наступил один из исходов. Не
|
|
«все сделаны»: иначе одна застрявшая задача держит спринт бесконечно. Затем
|
|
`sprint close`.
|
|
|
|
**Урожай заводится при закрытии спринта, а не при закрытии задачи.** Это
|
|
обязанность закрывающего: пройти по спискам находок от исполнителей и завести
|
|
недостающее интейком скилла `tasks` — с дедупликацией и картой человеку. Заводимое
|
|
метится тегом спринта само (`sprint:<слаг>`), поэтому первая порция следующей
|
|
сессии поднимается одной командой `list --tag sprint:<слаг>`. Спринт, закрытый
|
|
без этого шага, оставляет находки жить в отчётах — то есть нигде.
|
|
|
|
**Провал спринта.** Сработал блокер — спринт распускается (`sprint close
|
|
--dissolve --reason …`), недоделанное возвращается в беклог, новый набор
|
|
делается после ответа человека. Спринт не «ждёт»: ждать может человек, а
|
|
замороженный набор, который нельзя двигать, только мешает.
|
|
|
|
## Определение готовности
|
|
|
|
Задача засчитывается сделанной, когда верно **всё**:
|
|
|
|
1. **Пайплайн задачи пройден до конца** — со своим определением готовности, за
|
|
которое отвечает проект: проверки, состав ревью, документация, коммит. Здесь
|
|
оно не пересказывается и не подменяется — **форма фиксирована, содержание
|
|
даёт `CLAUDE.md` проекта**. Пайплайна нет, задача сделана руками — условие
|
|
читается как «проверки проекта зелёные и изменение влито».
|
|
2. **Критерии приёмки проверены поимённо** — каждый со своим оракулом, исход по
|
|
каждому назван. Это единственное, что добавляет управление задачами: пайплайн
|
|
отвечает «сделано по правилам», критерии — «сделано то, что заказывали».
|
|
3. **Находки по ходу отданы списком** — исполнитель обязан их **назвать**
|
|
(каждую, с пометкой «заведена / не заведена: причина»), но **не обязан
|
|
заводить**: заведение интерактивно, оно требует дедупликации против беклога и
|
|
кладбища и решений человека. Обязанность **завести урожай** — на закрытии
|
|
спринта, ниже. Так автономный исполнитель не оказывается одновременно обязан
|
|
завести задачи и не вправе это сделать в одиночку.
|
|
|
|
### Кто и когда закрывает
|
|
|
|
**Задачу закрывает не пайплайн, а владелец спринта — после приёмки.** Порядок:
|
|
|
|
1. пайплайн доводит задачу до коммита и **докладывает исход**; файл задачи он не
|
|
трогает — своей процедуры закрытия у него нет;
|
|
2. приёмщик (не исполнитель) сверяет критерии поимённо и выносит вердикт;
|
|
3. вердикт сошёлся — владелец спринта зовёт `close <slug> --implemented`
|
|
командой учёта задач из `CLAUDE.md` проекта.
|
|
|
|
Обратный порядок ломает приёмку физически: закрытие **удаляет файл**, и
|
|
приёмщику, нашедшему расхождение, возвращать нечего.
|
|
|
|
**Дорога назад существует и обязана быть названа.** Закрыли раньше вердикта, а
|
|
приёмка не сошлась — `tasks.py reopen <slug> --reason "приёмка не сошлась: …"`:
|
|
файл восстанавливается из истории git, строка возвращается в набор идущего
|
|
спринта (или в беклог, если спринта нет), строка кладбища снимается. Тело
|
|
восстанавливается **на момент удаления** — всё, что было дописано позже, живёт
|
|
только в коммите задачи, и это называется в докладе.
|
|
|
|
### Кто и по чему принимает
|
|
|
|
Три условия, без которых пункт про критерии не исполняется никем:
|
|
|
|
1. **Критерии переживают файл задачи.** Файл удаляется при закрытии, поэтому
|
|
критерии копируются туда, где их увидит приёмщик — в предложение об
|
|
изменении, описание ветки, тело коммита. Куда именно, называет `CLAUDE.md`
|
|
проекта. Иначе приёмка проверяет критерии из файла, которого больше нет.
|
|
2. **Принимает не исполнитель.** Отдельный контекст — сабагент или человек, —
|
|
которому дают изменение, отчёт исполнителя и отчёты ревью. Тот же принцип
|
|
декорреляции, на котором стоит любой конвейер проверки: занизивший и
|
|
проверяющий не должны быть одним контекстом.
|
|
3. **Расхождение — дефект критериев.** Приёмщик правит критерии и возвращает
|
|
задачу исполнителю **в этом же спринте**: ответ есть, остаток есть, по тесту
|
|
про остаток это не выход из спринта.
|
|
|
|
## Что врывается в замороженный набор
|
|
|
|
Только два класса — правило и его обоснование в SKILL.md. Здесь механика:
|
|
|
|
- вторжение **не добавляет** задачу в набор: `SPRINT.md` остаётся набором под
|
|
цель. Внеплановая работа делается и называется в докладе отдельной строкой
|
|
«внеплановое: что и почему»;
|
|
- если внеплановое требует больше пары часов, честнее распустить спринт, чем
|
|
делать вид, что набор соблюдается;
|
|
- всё остальное падает в беклог через обычный интейк и ждёт сессии.
|
|
|
|
## Доклад в конце спринта
|
|
|
|
Проверяемые якоря, а не пересказ:
|
|
|
|
- **Цель спринта** и по каждой задаче набора: **хеш коммита**, дословный исход
|
|
проверок проекта, **исход по каждому критерию приёмки**.
|
|
- **Какие развилки решались** и чем обоснованы.
|
|
- **Урожай:** сколько задач заведено, какие вопросы накопились, что вышло из
|
|
спринта и почему, что было внеплановым.
|
|
- **Поимённая сверка урожая** с отчётами ревью: каждая отложенная находка имеет
|
|
либо слаг, либо строку «не заведена: причина». Нулевой урожай при непустом
|
|
отчёте — сигнал, а не благополучие.
|
|
- **Созрела ли порция для сессии.** Решение звать — человека, напоминание —
|
|
обязанность агента: `⌈урожай / 8⌉` порций.
|
|
- **Границы покрытия** сжатой строкой: что в этом спринте не проверялось вовсе.
|