спринт без цели: цель стала необязательной, но не молчаливой

Цель была обязательной во всех трёх местах сразу: sprint start требовал слаг,
check считал ошибкой набор без названной цели, sprint take отказывал задаче под
чужой целью. Модель описывала только спринт развития — а спринт бывает под
багфикс, под техдолг, под здоровье проекта: такой набор собран по
работоспособности, а не по направлению, и цели у него нет не по недосмотру.

Обходной путь существовал и был хуже прямого: завести цель-пустышку «Здоровье
проекта» и вешать под неё fix-ы. Тогда ROADMAP.md — документ про то, что
приложение умеет, — обрастает строками про то, что оно не ломается, а тег goal:
перестаёт значить направление.

Теперь sprint start принимает --goal <слаг> ИЛИ --no-goal, и голое отсутствие
обоих — отказ с объяснением. Причина в стимуле: цель называет человек, и это
единственный продуктовый вопрос всей сессии. Разреши мы заводить спринт просто
без флага — забытый флаг, лень спросить и осознанное решение стали бы
неотличимы на выходе, а дешевле всего из трёх агенту именно не спрашивать. Тот
же обход записан в «Стимулы» скилла session вместе с защитой.

В спринте без цели цель не проверяется вовсе: набор берёт что угодно готовое к
взятию, включая задачи под разными целями. Правило «набор служит одной цели» не
ослаблено, оно просто не применяется — целей там не больше одной, их ноль.
Взамен машинной проверки остаётся показ набора человеку до заморозки, и в
cadence.md сказано прямо: у бесцельного спринта это единственная проверка
состава. Доклад обязан называть спринт бесцельным и объяснять, чем он был.

Признак «спринт идёт» разъехался с целью и переехал на слаг: слаг есть у любого
спринта, потому что без него нечем проставить sprint:<слаг>, то есть нечем
собрать урожай. На sprint_started() переведены sprint take, блок здоровья check
и reopen. Поле «Цель» в шапке остаётся и у бесцельного набора — пишется прозой
без ссылки: «цели нет» и «цель потерялась» обязаны различаться.

Побочно выправлен reopen: он возвращает задачу в набор идущего спринта тем же
тестом, что и sprint take (мешает только чужая цель). Прежде тест был уже —
совпадение целей, — и задача без цели, реопенутая при спринте с целью, уезжала
в беклог вопреки прозе скилла.

Тема 39 в DECISIONS.md, следствия 145-147.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
av
2026-08-07 09:19:29 +03:00
co-authored by Claude Opus 5
parent 4386eb3e1c
commit 37394444e8
7 changed files with 217 additions and 69 deletions
+29 -12
View File
@@ -1,12 +1,12 @@
---
name: session
description: "Ритуал между спринтами и ведение самого спринта: разбор накопившихся вопросов, разбор прошедшего спринта про процесс, переоценка задач порциями, выбор цели и набор нового спринта с заморозкой. Плюс правила по ходу спринта — что врывается в замороженный набор, чем вопрос отличается от блокера, когда задача выходит из спринта, что считается сделанным и что идёт в доклад. Использовать, когда просят закрыть или начать спринт, собрать набор, разобрать вопросы, провести груминг/переоценку/ретроспективу, решить «что делать дальше» или доложить итоги, а также когда вернулись к проекту после перерыва и надо понять, где остановились. Формат и содержимое задач — скилл tasks."
description: "Ритуал между спринтами и ведение самого спринта: разбор накопившихся вопросов, разбор прошедшего спринта про процесс, переоценка задач порциями, выбор цели (или решение, что спринт без цели) и набор нового спринта с заморозкой. Плюс правила по ходу спринта — что врывается в замороженный набор, чем вопрос отличается от блокера, когда задача выходит из спринта, что считается сделанным и что идёт в доклад. Использовать, когда просят закрыть или начать спринт, собрать набор, разобрать вопросы, провести груминг/переоценку/ретроспективу, решить «что делать дальше» или доложить итоги, а также когда вернулись к проекту после перерыва и надо понять, где остановились. Формат и содержимое задач — скилл tasks."
---
# Сессия между спринтами
Работа идёт спринтами: **набор задач под одну цель, замороженный до конца
спринта**. Между спринтами — одна сессия из четырёх шагов. Этот скилл владеет
Работа идёт спринтами: **набор задач, замороженный до конца спринта** — обычно
под одну цель, но бывает и без неё. Между спринтами — одна сессия из четырёх шагов. Этот скилл владеет
**ритуалом**: как сессия проводится и как спринт ведётся. Форматом и содержимым
задач владеет скилл `tasks`, выполнением задачи — пайплайн проекта.
@@ -28,8 +28,8 @@ description: "Ритуал между спринтами и ведение са
## Роли
**Человек** выбирает цель спринта, разбирает вопросы, держит право на
необратимое и на истину в самих данных.
**Человек** выбирает цель спринта**или решает, что этот спринт без цели**, —
разбирает вопросы, держит право на необратимое и на истину в самих данных.
**Агент — оркестрация.** Он собирает набор под названную цель, ставит задачи,
принимает отчёты и докладывает. Кто именно делает задачу — исполнитель, сабагент,
@@ -47,7 +47,10 @@ description: "Ритуал между спринтами и ведение са
`question`.
- **Блокер** — состояние, когда спринт не может продолжаться **ни одной**
задачей.
- **Спринт** — набор задач под одну цель, замороженный до его конца.
- **Спринт** — набор задач, замороженный до его конца. Под одной целью — или
**без цели вовсе**, законно: багфикс, техдолг, спринт здоровья. Такой набор
собран по работоспособности, а не по направлению, и заводится явно
(`sprint start --no-goal`).
## Вопрос, блокер, необратимое
@@ -88,9 +91,17 @@ description: "Ритуал между спринтами и ведение са
## Заморозка набора
**Цель одна.** Набор служит ей; задача, не служащая цели, в спринт не попадает,
даже если взять удобно (`sprint take` это и запрещает). **Задача с открытым
вопросом в набор не берётся.**
**Целей не больше одной.** Названа цель — набор служит ей: задача под чужой
целью в спринт не попадает, даже если взять удобно (`sprint take` это и
запрещает). **Задача с открытым вопросом в набор не берётся** — это верно всегда.
**Спринт без цели — законный случай, а не недосмотр.** Багфикс, техдолг,
здоровье: работа на работоспособность, а не на направление. Цель не названа —
сверять нечего, и в такой набор идёт что угодно готовое к взятию, в том числе
задачи под разными целями. Заводится он **явно**, `sprint start --no-goal`:
забытый флаг и решение человека иначе неотличимы, а это решение продуктовое.
Взамен проверки цели остаётся доклад — спринт без цели **называется таковым и
объясняется** одной строкой.
**Новая работа падает в беклог, а не в идущий спринт.** Решение «врываться или
отложить» принимается один раз правилом, а не заново каждый раз. Врывается
@@ -122,8 +133,8 @@ description: "Ритуал между спринтами и ведение са
судьи документов канона на весь канон разом, раз в спринт: `doc-consistency`
(документы между собой) и `doc-code-drift` (документы против кода).
3. **Переоценка задач** порциями.
4. **Выбор цели и набор спринта.** Цель называет человек, набор собирает агент и
показывает **до старта работ**.
4. **Выбор цели и набор спринта.** Цель называет человек — либо называет, что
этот спринт без цели; набор собирает агент и показывает **до старта работ**.
Рёбра подписаны тем, что ломается при их нарушении:
@@ -155,7 +166,7 @@ flowchart TD
1. `tasks.py check` — блок здоровья скажет состояние спринта, число готовых к
взятию и залежавшихся; при расхождении раскладки `--fix`.
2. Прочитать `SPRINT.md`: цель, состав, дата начала.
2. Прочитать `SPRINT.md`: цель (или запись, что её нет), состав, дата начала.
3. **Развилка, и решает её человек.** Набор всё ещё твой — продолжай спринт, ни
сессии, ни переоценки не нужно, они между спринтами. Взялся перечитывать,
зачем эти задачи собраны вместе, — набор протух:
@@ -183,6 +194,7 @@ 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 start --dir D --no-goal # шаг 4: набор без цели, явным флагом
python3 $tk sprint take --dir D <слаг> … # шаг 4: набор
python3 $tk sprint close --dir D # конец спринта; --dissolve при блокере
python3 $tk reopen <слаг> --dir D --reason … # приёмка не сошлась после закрытия
@@ -239,6 +251,11 @@ python3 $tk reopen <слаг> --dir D --reason … # приёмка не со
- **Сжать задачу до остатка** и отчитаться «сделана». Защита ослаблена там же.
Пол для остатка — польза, названная в «зачем»; проверяет его человек при приёмке,
и `reopen` — его инструмент.
- **Объявить спринт без цели**, чтобы не задавать человеку продуктовый вопрос:
набор без цели берёт что угодно, и собрать его можно молча. Защита: цели нет
— это **ответ человека, а не умолчание** (`--no-goal` спрашивается так же, как
цель), плюс строка доклада, называющая спринт бесцельным и объясняющая почему.
Два бесцельных спринта подряд — предмет разбора процесса, а не мелочь.
- **Занизить урожай** — не заводить найденное по ходу. Защита: поимённая сверка
с **сохранённым независимым отчётом**, а не с прозой исполнителя. Каждая
отложенная находка имеет либо слаг, либо строку «не заведена: причина».