спринт без цели: цель стала необязательной, но не молчаливой
Цель была обязательной во всех трёх местах сразу: 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:
@@ -2661,3 +2661,49 @@ JJJ): у профиля обязан быть один правильный от
|
||||
Читателей документа не перечисляет ни одна сторона — читатель назначается
|
||||
планом прогона. Прежняя ссылка на «таблицу читателей» пережила саму таблицу
|
||||
и обещала то, чего нет, — с той самой правки, которая таблицу и убрала.
|
||||
|
||||
## 39. Спринт без цели — законный случай (2026-08-07)
|
||||
|
||||
Цель была обязательной: `sprint start --goal` требовал слаг, `check` считал
|
||||
ошибкой набор без названной цели, `sprint take` отказывал задаче под чужой
|
||||
целью. Модель описывала только спринт развития — а спринт бывает под багфикс,
|
||||
под техдолг, под здоровье проекта. Такой набор собран **по работоспособности, а
|
||||
не по направлению**, и цели у него нет не по недосмотру.
|
||||
|
||||
Обходной путь существовал и был хуже прямого: завести цель-пустышку («Здоровье
|
||||
проекта») и вешать под неё `fix`-и. Тогда `ROADMAP.md` — документ про то, что
|
||||
приложение умеет, — обрастает строками про то, что оно не ломается, а тег
|
||||
`goal:` перестаёт значить направление.
|
||||
|
||||
**АЕААА. Цель у спринта необязательна, но её отсутствие — ответ, а не молчание.**
|
||||
`sprint start` принимает `--goal <слаг>` **или** `--no-goal`, и голое отсутствие
|
||||
обоих — отказ с объяснением. Причина в стимуле: цель называет человек, и это
|
||||
единственный продуктовый вопрос всей сессии. Разреши мы заводить спринт просто
|
||||
без флага — забытый флаг, лень спросить и осознанное решение стали бы неотличимы
|
||||
на выходе, а дешевле всего из трёх агенту именно не спрашивать.
|
||||
|
||||
**АЕААБ. В спринте без цели цель не проверяется вовсе.** Набор берёт что угодно
|
||||
готовое к взятию, включая задачи под разными целями: сверять не с чем. Правило
|
||||
«набор служит одной цели» не ослаблено, оно просто не применяется — целей в
|
||||
таком наборе не больше одной, их ноль. Взамен машинной проверки остаётся показ
|
||||
набора человеку до заморозки: у бесцельного спринта это **единственная**
|
||||
проверка состава, и в скилле это сказано прямо.
|
||||
|
||||
**АЕААВ. Признак «спринт идёт» — слаг, а не цель.** Прежде код спрашивал цель и
|
||||
получал заодно ответ про то, открыт ли спринт; теперь эти вопросы разошлись.
|
||||
Слаг подходит на роль признака лучше цели по существу: он есть у любого спринта,
|
||||
потому что без него нечем проставить `sprint:<слаг>`, то есть нечем собрать
|
||||
урожай. Поле «Цель» в шапке остаётся на месте и у бесцельного набора — пишется
|
||||
прозой без ссылки: **«цели нет» и «цель потерялась» обязаны различаться**.
|
||||
|
||||
### Что из этого следует
|
||||
|
||||
145. **Необязательное поле, которое всё же решают, заводится парой «значение или
|
||||
явный отказ».** Умолчанием тут был бы не выбор, а его отсутствие — и
|
||||
отличить его от забывчивости уже не смог бы никто, включая автора.
|
||||
146. **Признак «сущность существует» нельзя вешать на её необязательное поле.**
|
||||
Пока цель была обязательной, `sprint_goal()` отвечал сразу на два вопроса,
|
||||
и это работало ровно до тех пор, пока второй ответ не понадобился отдельно.
|
||||
147. **Снятая проверка называет, что осталось вместо неё.** Цель не проверяется
|
||||
— значит, за состав отвечают показ человеку и строка доклада; иначе
|
||||
послабление читается как «здесь можно не думать».
|
||||
|
||||
Reference in New Issue
Block a user