av-dev-pm: плагин переименован, заведены канон документов и скиллы init/canon/docs
- av-dev-tasks → av-dev-pm; канон определён единственным reference-файлом, который читают все три новых скилла - canon: check/adopt/upgrade плюс docs.py — раскладка, битые ссылки, версия, маркеры долга, сверки миграций и capability с документацией - tasks и session: путь docs/tasks жёсткий, конфиг переехал в docs/.pm.json, слот «Команда учёта задач» убран в пользу вызова скилла, раздел «Стимулы» переписан под совпавших приёмщика и исполнителя
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
---
|
||||
name: session
|
||||
description: Ритуал между спринтами и ведение самого спринта: разбор накопившихся вопросов, разбор прошедшего спринта про процесс, переоценка задач порциями, выбор цели и набор нового спринта с заморозкой. Плюс правила по ходу спринта — что врывается в замороженный набор, чем вопрос отличается от блокера, когда задача выходит из спринта, что считается сделанным и что идёт в доклад. Использовать, когда просят закрыть или начать спринт, собрать набор, разобрать вопросы, провести груминг/переоценку/ретроспективу, решить «что делать дальше» или доложить итоги. Формат и содержимое задач — скилл tasks.
|
||||
---
|
||||
|
||||
# Сессия между спринтами
|
||||
|
||||
Работа идёт спринтами: **набор задач под одну цель, замороженный до конца
|
||||
спринта**. Между спринтами — одна сессия из четырёх шагов. Этот скилл владеет
|
||||
**ритуалом**: как сессия проводится и как спринт ведётся. Форматом и содержимым
|
||||
задач владеет скилл `tasks`, выполнением задачи — пайплайн проекта.
|
||||
|
||||
## Почему не Scrum
|
||||
|
||||
Терминология близка — спринт, груминг, определение готовности, ретроспектива, —
|
||||
и это удобно: не нужно изобретать слова. Но добрая половина Scrum существует
|
||||
ради синхронизации людей, которых здесь нет.
|
||||
|
||||
**Не берём:** тайм-бокс (спринт ограничен объёмом, а не временем), velocity и
|
||||
оценки в очках, ежедневный стендап (стендап — это и есть диалог), планирование
|
||||
отдельно от груминга (владелец беклога один), роль скрам-мастера.
|
||||
|
||||
**Берём:** цель спринта, заморозку набора, определение готовности, груминг —
|
||||
каждое потому, что снимает решение, которое иначе принимается заново каждый раз.
|
||||
**Ретроспективу берём содержанием, но не отдельным ритуалом:** она шаг той же
|
||||
сессии. Процесс личный, синхронизировать некого, а отдельная встреча ради трёх
|
||||
вопросов — та самая плата ритуалом без выгоды.
|
||||
|
||||
## Роли
|
||||
|
||||
**Человек** выбирает цель спринта, разбирает вопросы, держит право на
|
||||
необратимое и на истину в самих данных.
|
||||
|
||||
**Агент — оркестрация.** Он собирает набор под названную цель, ставит задачи,
|
||||
принимает отчёты и докладывает. Кто именно делает задачу — исполнитель, сабагент,
|
||||
пайплайн — дело проекта; сессия про это не знает и знать не должна.
|
||||
|
||||
## Единицы
|
||||
|
||||
- **Цель** — то, ради чего набирается спринт. Файл `[goal]`, перечисленный в
|
||||
`PLAN.md`. Цель постоянна: живёт, пока живёт направление.
|
||||
- **Задача** — то, что мерджится целиком и даёт видимую пользу.
|
||||
- **Вопрос** — решение человека. Не останавливает начатую работу, но **блокирует
|
||||
взятие** задачи в спринт. Живёт внутри файла задачи разделом «Вопросы» и тегом
|
||||
`question`.
|
||||
- **Блокер** — состояние, когда спринт не может продолжаться **ни одной**
|
||||
задачей.
|
||||
- **Спринт** — набор задач под одну цель, замороженный до его конца.
|
||||
|
||||
## Вопрос, блокер, необратимое
|
||||
|
||||
| | Что это | Когда спрашиваем | Что останавливает |
|
||||
| --- | --- | --- | --- |
|
||||
| **Вопрос** | решение человека | на сессии, пачкой | взятие задачи в спринт |
|
||||
| **Блокер** | спринт не может продолжаться ни одной задачей | немедленно | всё |
|
||||
|
||||
Право на **необратимое** — третье и отдельное: что именно необратимо, называет
|
||||
`CLAUDE.md` проекта, и спрашивается оно всегда, независимо от спринта.
|
||||
|
||||
**Блокер определяется исходом, а не одновременностью.** Встали разом или
|
||||
высыпались из спринта по одной — если продолжать нечем, это блокер: спринт
|
||||
распускается (`sprint close --dissolve --reason …`), человек спрашивается
|
||||
немедленно. Иначе спринт, из которого задачи вышли поштучно, выглядел бы штатно
|
||||
завершённым, а вопросы тихо ждали бы сессии.
|
||||
|
||||
**Отличать вопрос от застревания.** Правило про остаток принадлежит управлению
|
||||
задачами: оно решает, **сделана задача или вышла**, а это исход планирования, не
|
||||
исполнения. **Ниже канонический текст; пайплайн проекта на него ссылается, а не
|
||||
пересказывает** — два экземпляра одного правила разъезжаются, и разъезжаются
|
||||
незаметно, потому что расхождение видно только на редком входе.
|
||||
|
||||
> Есть остаток, который доводится без ответа, — задача продолжается, вопрос
|
||||
> записывается в файл. Остатка нет — задача выходит из спринта.
|
||||
|
||||
С двумя оговорками, без которых тест ошибается:
|
||||
|
||||
> **Остаток, который материализует нерешённое** — записывает в хранилище,
|
||||
> журнал, витрину **или наружу** состояние, зависящее от неотвеченного вопроса,
|
||||
> — **не остаток**. Решение поднимается до начала записи: откатить запись
|
||||
> дороже, чем подождать ответ, а иногда невозможно. «Наружу» — часть правила, а
|
||||
> не пример: выкладка, публикация и отправка данных третьей стороне не
|
||||
> откатываются тем более.
|
||||
|
||||
> **Пол для остатка:** остаток, из которого пропала польза, названная в хуке, —
|
||||
> это не сделанная задача, а вышедшая из спринта.
|
||||
|
||||
## Заморозка набора
|
||||
|
||||
**Цель одна.** Набор служит ей; задача, не служащая цели, в спринт не попадает,
|
||||
даже если взять удобно (`sprint take` это и запрещает). **Задача с открытым
|
||||
вопросом в набор не берётся.**
|
||||
|
||||
**Новая работа падает в беклог, а не в идущий спринт.** Решение «врываться или
|
||||
отложить» принимается один раз правилом, а не заново каждый раз. Врывается
|
||||
только два класса:
|
||||
|
||||
1. **Необратимый ущерб** — потеря, порча или утечка данных: то, что не чинится
|
||||
доделкой потом.
|
||||
2. **Сломан общий станок** — красная проверка, на которой стоит определение
|
||||
готовности **всех** задач набора. Это не новая работа, а починка того, на чём
|
||||
делается вся остальная.
|
||||
|
||||
Что в проекте считается необратимым ущербом и что — общим станком, называет
|
||||
`CLAUDE.md` проекта. Не названо — спрашиваем человека, а не решаем сами.
|
||||
|
||||
**Конец спринта** — когда каждая задача набора либо сделана, либо вышла с
|
||||
записанной причиной. Не «все сделаны»: иначе одна застрявшая задача держит
|
||||
спринт бесконечно. Пустой набор закрывается `sprint close` — скрипт не даст
|
||||
закрыть непустой.
|
||||
|
||||
Ведение спринта целиком — исходы задачи, определение готовности, приёмка,
|
||||
доклад — [references/sprint.md](references/sprint.md).
|
||||
|
||||
## Сессия: четыре шага в этом порядке
|
||||
|
||||
Это зависимость, а не список.
|
||||
|
||||
1. **Разбор вопросов.**
|
||||
2. **Разбор прошедшего спринта — про процесс, а не про задачи.**
|
||||
3. **Переоценка задач** порциями.
|
||||
4. **Выбор цели и набор спринта.** Цель называет человек, набор собирает агент и
|
||||
показывает **до старта работ**.
|
||||
|
||||
Процедура каждого шага, размер и отбор порции, храповик на залежавшихся, формат
|
||||
интерактива и доклад — [references/cadence.md](references/cadence.md).
|
||||
|
||||
## Инструмент
|
||||
|
||||
Тот же `tasks.py`, что у скилла `tasks` — оба скилла в одном плагине, путь
|
||||
общий: `tk="$CLAUDE_PLUGIN_ROOT/skills/tasks/scripts/tasks.py"`. Сессии нужны
|
||||
прежде всего:
|
||||
|
||||
```
|
||||
python3 $tk check --dir D # с этого начинается любая сессия
|
||||
python3 $tk list --dir D --questions # шаг 1: что накопилось
|
||||
python3 $tk list --dir D --tag sprint:<слаг> # шаг 3: урожай спринта, первая порция
|
||||
python3 $tk list --dir D --stale # шаг 3: дальше по залежалости
|
||||
python3 $tk list --dir D --goal <слаг> # шаг 4: кандидаты под названную цель
|
||||
python3 $tk sprint start --dir D --goal <слаг> # шаг 4: заводит и слаг спринта
|
||||
python3 $tk sprint take --dir D <слаг> … # шаг 4: набор
|
||||
python3 $tk sprint close --dir D # конец спринта; --dissolve при блокере
|
||||
python3 $tk reopen <слаг> --dir D --reason … # приёмка не сошлась после закрытия
|
||||
```
|
||||
|
||||
`D` — каталог задач проекта; цепочка его разрешения и вызов из чужого контекста
|
||||
описаны в скилле `tasks` («Переносимость»). **Коды выхода** — там же: 1 это
|
||||
дрейф в беклоге, 3 это «каталога нет», и ветвиться на них надо по-разному.
|
||||
|
||||
**Слаг спринта заводит `sprint start`** (по умолчанию — дата) и пишет его в
|
||||
`SPRINT.md`; всё заведённое при открытом спринте помечается `sprint:<слаг>`
|
||||
автоматически. Поэтому «первая порция — урожай прошедшего спринта» работает без
|
||||
чьей-либо памяти.
|
||||
|
||||
Правки задач делаются мутациями (`edit`, `move`, `close`), а не редактором:
|
||||
руками правится только тело файла. Это правило скилла `tasks`, здесь оно не
|
||||
пересказывается.
|
||||
|
||||
## Стимулы, которые процесс создаёт
|
||||
|
||||
Правило, которое можно обойти в свою пользу, будет обойдено.
|
||||
|
||||
**Приёмщик и исполнитель здесь совпадают, и это надо назвать вслух.** Задачу
|
||||
закрывает и двигает по индексам агент-оркестратор — тот же, кто её и сделал.
|
||||
Прежде границу держала механика: моста между плагинами не было, и закрыть задачу
|
||||
пайплайн физически не мог. Теперь мост есть, и защита у трёх обходов ниже —
|
||||
**только текстовая**. Опоры, которые остались настоящими:
|
||||
|
||||
- **отчёт триажа** в `openspec/changes/<id>/review/` — независимый артефакт,
|
||||
написанный ревью, а не исполнителем; по нему сверяют состав прогона и урожай;
|
||||
- **`SPRINT.md` под git** — `git log -p` показывает, что и когда было закрыто;
|
||||
- **`reopen <слаг> --reason`** — закрытие не окончательно. Приёмка человеком на
|
||||
сессии его отменяет, и это штатная операция, а не скандал.
|
||||
|
||||
Известные обходы:
|
||||
|
||||
- **Скрыть блокер** — он останавливает всё и выглядит как провал исполнителя.
|
||||
Защита: тест про остаток плюс прямая запись, что **объявление блокера
|
||||
неудачей не считается**.
|
||||
- **Не записать вопрос** на задаче-кандидате, чтобы не вычеркнуть её из
|
||||
ближайшего набора. Защита: вопросы кандидатов разбираются на той же сессии
|
||||
**вне очереди порции**.
|
||||
- **Занизить критерии приёмки**, раз они пол. Защита ослаблена: правит их тот же,
|
||||
кто по ним отчитывается. Остаётся требование, что расхождение критериев с
|
||||
сутью — **дефект критериев, о котором сообщают, а не молча дорабатывают**, и
|
||||
переоценка на сессии, где критерии видит человек.
|
||||
- **Сжать задачу до остатка** и отчитаться «сделана». Защита ослаблена там же.
|
||||
Пол для остатка — польза, названная в хуке; проверяет его человек при приёмке,
|
||||
и `reopen` — его инструмент.
|
||||
- **Занизить урожай** — не заводить найденное по ходу. Защита: поимённая сверка
|
||||
со **сохранённым отчётом триажа**, а не с прозой исполнителя. Каждая
|
||||
отложенная находка имеет либо слаг, либо строку «не заведена: причина».
|
||||
Нулевой урожай при непустом отчёте виден сразу.
|
||||
|
||||
Стимулы внутри пайплайна задачи (занизить требования к проверке, пропустить
|
||||
проход) принадлежат ему и защищены там же.
|
||||
|
||||
## Слоты проекта
|
||||
|
||||
Сессия не знает ни языка, ни сборки, ни CI. Часть проектного отвечает
|
||||
[канон](../canon/references/canon.md) структурой: разбор процесса (шаг 2) живёт
|
||||
в `docs/review.md`, оракулы и «чем краснеет безусловно» — в семантике гейта в
|
||||
`CLAUDE.md`. Остальное проект **дописывает в `CLAUDE.md`**:
|
||||
|
||||
1. **Пайплайн задачи** — чем задача выполняется и что входит в его определение
|
||||
готовности. Сессия требует только форму: пайплайн пройден + критерии приёмки
|
||||
проверены поимённо.
|
||||
2. **Общий станок** — какая проверка, покраснев, врывается в замороженный
|
||||
спринт.
|
||||
3. **Необратимое** — что спрашивается у человека всегда (тот же слот, что у
|
||||
скилла `tasks`; дом один).
|
||||
4. **Как критерии приёмки переживают удаление файла задачи** — файл удаляется
|
||||
при закрытии, поэтому критерии копируются туда, где их увидит приёмщик
|
||||
(предложение об изменении, описание ветки, тело коммита). Куда именно —
|
||||
решает проект.
|
||||
5. **Ориентир по размеру спринта**, если он замерялся. Умолчание — 5–8 задач, и
|
||||
это **ориентир, а не закон**.
|
||||
|
||||
Числа проекта (сколько задач в спринте, сколько времени на задачу, каков прирост
|
||||
беклога) — предмет шага 2, а не константы этого скилла.
|
||||
|
||||
## Чего этот скилл не делает
|
||||
|
||||
Не пишет код и не выполняет задачи. Не заводит и не переоформляет задачи сам по
|
||||
себе — формат и содержимое ведёт `tasks` (сессия зовёт его операции). Не решает
|
||||
за человека, какая цель следующая. Не двигает набор идущего спринта.
|
||||
@@ -0,0 +1,199 @@
|
||||
# Сессия: четыре шага
|
||||
|
||||
Одна сессия между спринтами. Порядок шагов — **зависимость, а не список**:
|
||||
переоценивать задачи, не разобрав вопросы, значит переоценивать вслепую; набирать
|
||||
спринт, не переоценив, значит набирать из протухшего.
|
||||
|
||||
Начинается сессия с `tasks.py check` (и `check --fix`, если дрейф накопился) —
|
||||
результат идёт строкой в доклад.
|
||||
|
||||
## Шаг 1. Разбор вопросов
|
||||
|
||||
`tasks.py list --questions` — всё, что накопилось. Вопрос это решение человека,
|
||||
и разбирается он **пачкой**, а не по одному в момент возникновения: по одному —
|
||||
это дёрганье, пачкой — это сессия.
|
||||
|
||||
Порядок по каждому вопросу:
|
||||
|
||||
1. **Проверь, не отвечен ли он уже** — решением, документом, соседним
|
||||
изменением, самим ходом прошедшего спринта. Отвеченный вопрос не выносится
|
||||
человеку: это самая частая находка и она не требует ничьего решения.
|
||||
2. **Сформулируй развилку** с вариантами и последствием каждого, рекомендация —
|
||||
первым вариантом.
|
||||
3. **Вынеси пачкой** через `AskUserQuestion`, не больше трёх за раз.
|
||||
4. **Ответ записывается в тело задачи**, тег снимается `edit <slug> --rm-tag
|
||||
question`, **хук переписывается**: «Решено: …» на вопрос «почему это лежит в
|
||||
беклоге» уже не отвечает.
|
||||
|
||||
**Вопросы на задачах-кандидатах разбираются вне очереди порции** — здесь же, на
|
||||
этой сессии, даже если сама задача в порцию переоценки не попала. Иначе правило
|
||||
«задача с открытым вопросом в набор не берётся» создаёт стимул вопрос не
|
||||
записывать, лишь бы не вычеркнуть задачу из ближайшего спринта.
|
||||
|
||||
## Шаг 2. Разбор прошедшего спринта — про процесс, а не про задачи
|
||||
|
||||
Не «что мы сделали» (это доклад спринта, он уже был), а:
|
||||
|
||||
- **что сломалось в процессе и почему не поймали** — промах, доехавший до конца;
|
||||
- **сколько на самом деле заняли задачи** против ожидания;
|
||||
- **какие правила не сработали или сработали не так** — в том числе правила
|
||||
этого плагина;
|
||||
- **какие числа пора пересмотреть** — ориентир по размеру спринта, прирост
|
||||
беклога на одну закрытую задачу, время на задачу. Эта обязанность иначе висит
|
||||
ничья: числа, помеченные как «первый замер», не пересматриваются никогда, если
|
||||
их не пересматривает конкретный шаг.
|
||||
|
||||
**Артефакт обязателен.** Вывод, оставшийся в контексте сессии, не существует:
|
||||
следующая сессия его не увидит. Дом у него один и известен из канона —
|
||||
**`docs/review.md`**: вывод про конвейер и про то, что перестали проверять, идёт
|
||||
в раздел настройки, вывод про воспроизведённый дефект — в журнал. Решение с
|
||||
долгим следом — в `docs/adr/`.
|
||||
|
||||
Отдельным ритуалом ретроспектива не выделяется: процесс личный,
|
||||
синхронизировать некого.
|
||||
|
||||
## Шаг 3. Переоценка задач
|
||||
|
||||
Цель — выкинуть то, что перестало быть задачей, и вернуть остальному честное
|
||||
состояние. Не «пересмотреть всё», а «пересмотреть порцию до конца».
|
||||
|
||||
### Порция и правило остановки
|
||||
|
||||
Тридцать задач за один заход — это усталость и штамповка: последние десять
|
||||
получат «оставить» не потому, что живы, а потому, что сессия затянулась.
|
||||
|
||||
- **5–8 задач за порцию.** Размер обоснован усталостью, а не пропускной
|
||||
способностью, и менять его не надо — **надо брать несколько порций за
|
||||
сессию**.
|
||||
- **Сколько порций:** не меньше `⌈урожай прошедшего спринта / 8⌉`. Урожай — это
|
||||
задачи, заведённые за спринт; при урожае в 15 это две-три порции.
|
||||
- **Отбор порций по порядку:**
|
||||
1. **урожай спринта** — `list --tag sprint:<слаг>`: свежезаведённое ещё не
|
||||
проходило ни одной проверки на нужность. Слаг спринта берётся из
|
||||
`SPRINT.md` (его завёл `sprint start`), тег на задачах проставлен
|
||||
автоматически при заведении — руками не метят и не вспоминают;
|
||||
2. дальше **по залежалости** — `list --stale`;
|
||||
3. по потребности — одна секция целиком, один тег (партия ревью), одна цель
|
||||
(`--goal`), список от пользователя.
|
||||
- **Останавливайся на границе порции**, даже если «ещё чуть-чуть осталось».
|
||||
Между порциями — промежуточный доклад.
|
||||
|
||||
### Что делать с каждой задачей
|
||||
|
||||
Сперва то, что не требует ничьего решения:
|
||||
|
||||
1. **Проверь, не сделано ли уже.** Задача, реализованная попутно в соседнем
|
||||
изменении, — самая частая находка. Смотри код, документацию, историю коммитов
|
||||
по ключевым словам. Удаление «как реализованной» деструктивно и без следа
|
||||
(в `REJECTED.md` реализованные не пишутся), поэтому порог улики жёсткий:
|
||||
`close <slug> --implemented` только имея **конкретный коммит или строку
|
||||
документа**, закрывающие задачу, и ссылка идёт в доклад. Есть лишь косвенные
|
||||
признаки — не удаляй сам, вынеси в пачку вопросов. Сделана частично → задача
|
||||
сжимается до остатка: тело правишь редактором, заголовок и хук — через
|
||||
`edit`.
|
||||
2. **Проверь, не отменена ли решением.** Документ, ADR или архивное изменение
|
||||
мог закрыть вопрос иначе — тогда `close <slug> --reason "<ссылка на
|
||||
решение>"`. Задача закрывается не только коммитом.
|
||||
3. **Проверь пересечения.** Две задачи об одном — содержимое в одну, вторую
|
||||
`close <slug> --reason "слита с <другой-слаг>"`. Смотри **шире порции**:
|
||||
интейк дедуплицирует новое против существующего, но никогда не
|
||||
пересматривает уже лежащее, и две задачи с одной причиной могут лежать рядом
|
||||
месяцами.
|
||||
4. **Пере-кластеризуй по общей причине.** Несколько задач, оказавшихся симптомами
|
||||
одного дефекта, сливаются в одну — это находка, которую интейк дать не мог.
|
||||
5. **Гигиена полей** — протухший хук, вопрос в прозе, снятый ответ, свойство
|
||||
репозитория в рамках, предписание процесса в теле. Список и правила — в
|
||||
скилле `tasks`.
|
||||
|
||||
Затем — то, что решает пользователь:
|
||||
|
||||
6. **Жива ли она вообще.** Контекст мог измениться: ушла зависимость, отпал
|
||||
сценарий, обошли иначе. Здесь и звучит вопрос о выкидывании.
|
||||
7. **Та ли цель.** Приоритетов нет, и «повысить» нечего — вместо повышения
|
||||
**смена цели** (`edit <slug> --goal <другой>`) или включение в ближайший
|
||||
набор. Задача, которой не находится цель, — кандидат на выход: она не попадёт
|
||||
ни в один спринт.
|
||||
8. **Задача ли это по-прежнему.** Не проходит тест «готова к взятию» → `edit
|
||||
<slug> --type idea`, дальше штурм. Разрослась → `edit <slug> --type epic`,
|
||||
дальше декомпозиция.
|
||||
9. **Переоценка по измеренному.** Спринт производит числа — сколько на самом
|
||||
деле стоит такая работа, что оказалось дороже ожидания. Эти числа меняют цену
|
||||
**других** задач, и именно здесь это применяется: задача, чья цена выросла
|
||||
втрое, а польза осталась прежней, — кандидат на выход.
|
||||
|
||||
### Храповик на залежавшихся
|
||||
|
||||
Сильно залежавшаяся задача — сигнал сама по себе: её либо ни разу не собирались
|
||||
делать, либо нечем взять. Измеряй наблюдаемым — датой последней правки из git
|
||||
(`list --stale` ставит такие первыми); счётчик «сколько сессий пережила» нигде
|
||||
не хранится.
|
||||
|
||||
Задача из верхних строк `--stale`, которую и этот заход оставляет без изменений,
|
||||
**либо двигается (меняет цель, идёт в набор, уходит с причиной), либо остаётся с
|
||||
явно записанной причиной**, почему её держим (`move <slug> --section <та же>
|
||||
--reason …`). Молчаливое «оставить как есть» на давно неподвижной задаче — это
|
||||
решение не принимать решение; запись причины превращает его в осознанное и не
|
||||
даёт тому же вопросу всплыть на следующей сессии.
|
||||
|
||||
### Интерактив
|
||||
|
||||
- Вопросы — через `AskUserQuestion`, **не больше трёх за раз**. Порция в 5–8
|
||||
задач обычно даёт больше трёх суждений — тогда веди несколько итераций по ≤3,
|
||||
а не по одному на задачу и не одним перегруженным запросом.
|
||||
- К каждому варианту — **предварительное суждение, рекомендация первым
|
||||
вариантом**: «предлагаю выкинуть, потому что …». Пользователю дешевле
|
||||
возразить, чем судить с нуля.
|
||||
- Всё, что решается фактом (сделано / отменено / дублируется), решай сам и
|
||||
показывай списком в докладе, а не выноси в вопросы.
|
||||
|
||||
Пример одной итерации — три залежавшихся задачи, механику по ним уже разобрали:
|
||||
|
||||
> **Переоценка: 3 залежавшихся (порция по `--stale`)**
|
||||
>
|
||||
> 1. `versii-kachestvo-repaki` — версии и качество одного тайтла
|
||||
> - Выкинуть *(рекомендую)* — помечена «не боль», за полгода ни разу не возникла
|
||||
> - Оставить под целью `nadyozhnost-razdach`
|
||||
> - Перевести под цель `kachestvo-mediateki` — там она первая в очереди
|
||||
> 2. `backup-sqlite` — бэкап базы
|
||||
> - Оставить под текущей целью *(рекомендую)* — не сработала, но риск реальный
|
||||
> - Взять в ближайший набор — без бэкапа ретеншн опасен
|
||||
> - Выкинуть
|
||||
> 3. `guessit-sputnik` — вынести распознавание в сервис-спутник
|
||||
> - Понизить до `[idea]` *(рекомендую)* — не проходит тест «готова к взятию»
|
||||
> - Оставить задачей
|
||||
|
||||
Каждый вариант несёт причину — ту самую, что уедет в `--reason`. Ответы применяй
|
||||
сразу и, если в порции осталось ещё, следующей итерацией показывай следующие ≤3.
|
||||
|
||||
## Шаг 4. Выбор цели и набор спринта
|
||||
|
||||
1. **Покажи состояние целей**: линия `PLAN.md` с обоснованием порядка, кусты, и
|
||||
по каждой цели-кандидату — сколько под ней задач без открытых вопросов
|
||||
(`list --goal <слаг>`). Цель без готовых задач набором не станет: её сперва
|
||||
надо декомпозировать.
|
||||
2. **Цель называет человек.** Это продуктовое решение, а не механика: агент
|
||||
предлагает и объясняет, но не выбирает.
|
||||
3. **Набор собирает агент** — `sprint start --goal <слаг>`, затем `sprint take
|
||||
…`. Скрипт не даст взять чужую цель, идею, эпик, задачу с открытым вопросом
|
||||
или без критериев приёмки.
|
||||
4. **Набор показывается человеку до старта работ.** Показ — это и есть момент
|
||||
заморозки: после него набор не двигается.
|
||||
5. Задача, которой для взятия не хватает только критериев приёмки, дописывается
|
||||
здесь же — 2–5 утверждений, у каждого назван оракул (меньше двух `sprint
|
||||
take` не примет). Но если для критериев нужен ответ человека, это вопрос, и
|
||||
задача в набор не идёт.
|
||||
|
||||
**Размер — ориентир, а не закон:** 5–8 задач. Можно взять больше, можно меньше —
|
||||
набор под цель важнее круглого числа; одна крупная задача спринтом тоже бывает.
|
||||
|
||||
## Доклад сессии
|
||||
|
||||
- Что просмотрено: N из M, сколько порций, по какому признаку отобраны.
|
||||
- Вопросы: разобрано N, из них отвечено без человека N, снято тегов N.
|
||||
- Разбор процесса: что записано и куда.
|
||||
- Изменения списком: удалено как реализованное (со ссылками), ушло без
|
||||
реализации (с причинами), понижено до идей, слито, сменило цель.
|
||||
- Новый спринт: цель, набор со слагами, дата.
|
||||
- **Границы покрытия**: сколько задач не трогали и какие именно секции, теги или
|
||||
цели остались — иначе доклад читается как «беклог разобран».
|
||||
- `tasks.py check` после правок — результат строкой.
|
||||
@@ -0,0 +1,123 @@
|
||||
# Ведение спринта
|
||||
|
||||
Спринт — набор задач под одну цель, замороженный до его конца. Здесь то, что
|
||||
происходит **внутри** спринта: как задача заканчивается, что считается сделанным,
|
||||
кто принимает и что идёт в доклад. Как спринт набирается — шаг 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⌉` порций.
|
||||
- **Границы покрытия** сжатой строкой: что в этом спринте не проверялось вовсе.
|
||||
Reference in New Issue
Block a user