Осей было две — тип записи (goal/idea/task) и род работы (kind:<род> тегом), — и ортогональность у них была фальшивой: из двенадцати клеток произведения законны шесть. У цели род запрещён, у задачи обязателен, у идеи пуст и на практике не ставится. Плюс «алгоритм работы над записью такого типа» крепится не к task, а к fix и research, то есть к роду: ось, к которой пишется алгоритм, и была настоящим типом. Схлопнуто в одну ось из пяти значений: goal | feature | fix | chore | research. Тип idea упразднён отдельно и по другой причине: он значил не род работы, а незаполненность, а состояние типом быть не может — оно меняется по мере того, как запись дописывают, а тип меняют командой. Теперь состояние выводится из заполненности: research без раздела «Вопрос» это сырьё. В спринт не берётся, как и прежняя идея, лежит в конце категории, отбирается list --raw. Дом типа — поле меты «Тип» первой строкой, эмодзи в H1 производна. Прежнее «отдельного поля типа нет: два места для одного факта разъезжаются» отменено собственным аргументом: он был против префикса плюс поля, а при переносе дома место остаётся одно. Эмодзи стоит в H1, а не в строке индекса, чтобы инвариант «заголовок в индексе дословно» остался нетронутым. Поле места названо по типу: «Секция» у цели (часть роадмапа, состояние очереди), «Категория» у задачи (полка домена, куда её вернёт sprint drop). Одинаковое переименование закрепило бы конфляцию; какое поле обязательно, решает тип — то самое, ради чего затевалась правка. Два новых обязательных раздела выросли из правил, которые были записаны и которые нечем было проверить. «Не воспроизводится — это research, а не fix» стояло в каноне: теперь есть раздел «Воспроизведение». Приёмка разведки — «записанный ответ, а не изменённый код» — тоже стояла, но sprint take требовал от research два-пять критериев с оракулами, и они писались ради проверки; вместо них «Вопрос» и «Куда ляжет ответ». Сортировка «по важности» из заметок не взята: она требует, чтобы кто-то важность поддерживал, а это приоритет, от которого отказалось правило 4. Взято только «сырьё в конец категории» — этот порядок выводится из типа и заполненности, а не назначается человеком, и потому проверяется машиной. TYPE_SCHEMA кормит и body_template, и schema_verdict: иначе add кладёт то, на чём sprint take потом откажет. check --fix мигрирует за один проход — kind:/[goal]/[idea] в поле «Тип», эмодзи в заголовок, «Секция» → «Категория», сырьё в конец. Тип, которого неоткуда взять, не угадывается: feature от chore машина не отличает, такие записи уходят в НЕОДНОЗНАЧНО поимённо. Попутно закрыт класс отказов в --fix: шагов, правящих мету, стало пять, и второй, перечитавший файл с диска, стирал правку первого. Общий stage() поверх отложенных правок; до этого корректность держалась на том, что шагов было мало. Устав на тип отдельным файлом — references/task-<тип>.md, пять штук: схема, алгоритм, что видит машина и что человек. Агент task-form получил правило «тип сходится с тем, что в записи написано» с проверяемыми расхождениями. Обкатано на демо-наборе из 13 записей: миграция за один проход, второй прогон даёт ноль починок; fix без «Воспроизведения» и сырьё в спринт не идут, годная feature берётся. DECISIONS тема 27 (ААББ–ЛЛММ, следствия 101–104). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
22 KiB
name, description
| name | description |
|---|---|
| session | Ритуал между спринтами и ведение самого спринта: разбор накопившихся вопросов, разбор прошедшего спринта про процесс, переоценка задач порциями, выбор цели и набор нового спринта с заморозкой. Плюс правила по ходу спринта — что врывается в замороженный набор, чем вопрос отличается от блокера, когда задача выходит из спринта, что считается сделанным и что идёт в доклад. Использовать, когда просят закрыть или начать спринт, собрать набор, разобрать вопросы, провести груминг/переоценку/ретроспективу, решить «что делать дальше» или доложить итоги. Формат и содержимое задач — скилл tasks. |
Сессия между спринтами
Работа идёт спринтами: набор задач под одну цель, замороженный до конца
спринта. Между спринтами — одна сессия из четырёх шагов. Этот скилл владеет
ритуалом: как сессия проводится и как спринт ведётся. Форматом и содержимым
задач владеет скилл tasks, выполнением задачи — пайплайн проекта.
Почему не Scrum
Терминология близка — спринт, груминг, определение готовности, ретроспектива, — и это удобно: не нужно изобретать слова. Но добрая половина Scrum существует ради синхронизации людей, которых здесь нет.
Не берём: тайм-бокс (спринт ограничен объёмом, а не временем), velocity и оценки в очках, ежедневный стендап (стендап — это и есть диалог), планирование отдельно от груминга (владелец беклога один), роль скрам-мастера.
Берём: цель спринта, заморозку набора, определение готовности, груминг — каждое потому, что снимает решение, которое иначе принимается заново каждый раз. Ретроспективу берём содержанием, но не отдельным ритуалом: она шаг той же сессии. Процесс личный, синхронизировать некого, а отдельная встреча ради трёх вопросов — та самая плата ритуалом без выгоды.
Роли
Человек выбирает цель спринта, разбирает вопросы, держит право на необратимое и на истину в самих данных.
Агент — оркестрация. Он собирает набор под названную цель, ставит задачи, принимает отчёты и докладывает. Кто именно делает задачу — исполнитель, сабагент, пайплайн — дело проекта; сессия про это не знает и знать не должна.
Единицы
- Цель — то, ради чего набирается спринт. Файл типа
goal(🎯), перечисленный вROADMAP.md. Цель постоянна: живёт, пока живёт направление. - Задача — то, что мерджится целиком и даёт видимую пользу.
- Вопрос — решение человека. Не останавливает начатую работу, но блокирует
взятие задачи в спринт. Живёт внутри файла задачи разделом «Вопросы» и тегом
question. - Блокер — состояние, когда спринт не может продолжаться ни одной задачей.
- Спринт — набор задач под одну цель, замороженный до его конца.
Вопрос, блокер, необратимое
| Что это | Когда спрашиваем | Что останавливает | |
|---|---|---|---|
| Вопрос | решение человека | на сессии, пачкой | взятие задачи в спринт |
| Блокер | спринт не может продолжаться ни одной задачей | немедленно | всё |
Право на необратимое — третье и отдельное: что именно необратимо, называет
CLAUDE.md проекта, и спрашивается оно всегда, независимо от спринта.
Блокер определяется исходом, а не одновременностью. Встали разом или
высыпались из спринта по одной — если продолжать нечем, это блокер: спринт
распускается (sprint close --dissolve --reason …), человек спрашивается
немедленно. Иначе спринт, из которого задачи вышли поштучно, выглядел бы штатно
завершённым, а вопросы тихо ждали бы сессии.
Отличать вопрос от застревания. Правило про остаток принадлежит управлению задачами: оно решает, сделана задача или вышла, а это исход планирования, не исполнения. Ниже канонический текст; пайплайн проекта на него ссылается, а не пересказывает — два экземпляра одного правила разъезжаются, и разъезжаются незаметно, потому что расхождение видно только на редком входе.
Есть остаток, который доводится без ответа, — задача продолжается, вопрос записывается в файл. Остатка нет — задача выходит из спринта.
С двумя оговорками, без которых тест ошибается:
Остаток, который материализует нерешённое — записывает в хранилище, журнал, витрину или наружу состояние, зависящее от неотвеченного вопроса, — не остаток. Решение поднимается до начала записи: откатить запись дороже, чем подождать ответ, а иногда невозможно. «Наружу» — часть правила, а не пример: выкладка, публикация и отправка данных третьей стороне не откатываются тем более.
Пол для остатка: остаток, из которого пропала польза, названная в «зачем», — это не сделанная задача, а вышедшая из спринта.
Заморозка набора
Цель одна. Набор служит ей; задача, не служащая цели, в спринт не попадает,
даже если взять удобно (sprint take это и запрещает). Задача с открытым
вопросом в набор не берётся.
Новая работа падает в беклог, а не в идущий спринт. Решение «врываться или отложить» принимается один раз правилом, а не заново каждый раз. Врывается только два класса:
- Необратимый ущерб — потеря, порча или утечка данных: то, что не чинится доделкой потом.
- Сломан общий станок — красная проверка, на которой стоит определение готовности всех задач набора. Это не новая работа, а починка того, на чём делается вся остальная.
Что в проекте считается необратимым ущербом и что — общим станком, называет
CLAUDE.md проекта. Не названо — спрашиваем человека, а не решаем сами.
Конец спринта — когда каждая задача набора либо сделана, либо вышла с
записанной причиной. Не «все сделаны»: иначе одна застрявшая задача держит
спринт бесконечно. Пустой набор закрывается sprint close — скрипт не даст
закрыть непустой.
Ведение спринта целиком — исходы задачи, определение готовности, приёмка, доклад — references/sprint.md.
Сессия: четыре шага в этом порядке
Это зависимость, а не список.
- Разбор вопросов.
- Разбор прошедшего спринта — про процесс, а не про задачи.
- Переоценка задач порциями.
- Выбор цели и набор спринта. Цель называет человек, набор собирает агент и показывает до старта работ.
Рёбра подписаны тем, что ломается при их нарушении:
flowchart TD
check["tasks.py check (+ --fix)<br/>результат — строкой в доклад"]
s1["1. Разбор вопросов<br/>пачкой, не больше трёх за раз"]
s2["2. Разбор прошедшего спринта<br/>про процесс → docs/review.md"]
s3["3. Переоценка задач порциями"]
s4["4. Цель называет человек,<br/>набор собирает агент"]
sprint["спринт: набор заморожен"]
check --> s1
s1 --> s2
s2 --> s3
s1 -->|"неотвеченный вопрос → переоценка вслепую"| s3
s3 -->|"без переоценки набор берётся из протухшего"| s4
s4 --> sprint
Схема — сводка: процедура каждого шага в 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 — каталог задач проекта, по канону всегда docs/tasks; --dir передаётся
явно каждой командой. Вызов из чужого контекста описан в скилле tasks
(«Переносимость»). Коды выхода — там же: 1 это дрейф в беклоге, 3 это
«каталога нет», и ветвиться на них надо по-разному.
Слаг спринта заводит sprint start (по умолчанию — дата) и пишет его в
SPRINT.md; всё заведённое при открытом спринте помечается sprint:<слаг>
автоматически. Поэтому «первая порция — урожай прошедшего спринта» работает без
чьей-либо памяти — но ровно до команды sprint close, которая SPRINT.md
очищает. Отсюда порядок: урожай заводится до закрытия, слаг для сессии берётся
из отчёта sprint close (references/sprint.md).
Правки задач делаются мутациями (edit, move, close), а не редактором:
руками правится только тело файла. Это правило скилла tasks, здесь оно не
пересказывается.
Стимулы, которые процесс создаёт
Правило, которое можно обойти в свою пользу, будет обойдено.
Приёмщик и исполнитель здесь совпадают, и это надо назвать вслух. Задачу закрывает и двигает по индексам агент-оркестратор — тот же, кто её и сделал. Прежде границу держала механика: моста между плагинами не было, и закрыть задачу пайплайн физически не мог. Теперь мост есть, и защита у трёх обходов ниже — только текстовая. Опоры, которые остались настоящими:
- независимый отчёт ревью — артефакт, написанный не исполнителем; по нему
сверяют состав прогона и урожай. Где он лежит, знает пайплайн проекта; при
конвейере
av-dev-pipelineэто отчёт триажа вopenspec/changes/archive/<id>/review/(до архивации —changes/<id>/review/); SPRINT.mdпод git —git log -pпоказывает, что и когда было закрыто. Работает, только если закрытие закоммичено: удаление файла задачи и правка индекса, оставшиеся в рабочем дереве, никакой истории не образуют;reopen <слаг> --reason— закрытие не окончательно. Приёмка человеком на сессии его отменяет, и это штатная операция, а не скандал.
Известные обходы:
- Скрыть блокер — он останавливает всё и выглядит как провал исполнителя. Защита: тест про остаток плюс прямая запись, что объявление блокера неудачей не считается.
- Не записать вопрос на задаче-кандидате, чтобы не вычеркнуть её из ближайшего набора. Защита: вопросы кандидатов разбираются на той же сессии вне очереди порции.
- Занизить критерии приёмки, раз они пол. Защита ослаблена: правит их тот же, кто по ним отчитывается. Остаётся требование, что расхождение критериев с сутью — дефект критериев, о котором сообщают, а не молча дорабатывают, и переоценка на сессии, где критерии видит человек.
- Сжать задачу до остатка и отчитаться «сделана». Защита ослаблена там же.
Пол для остатка — польза, названная в «зачем»; проверяет его человек при приёмке,
и
reopen— его инструмент. - Занизить урожай — не заводить найденное по ходу. Защита: поимённая сверка с сохранённым независимым отчётом, а не с прозой исполнителя. Каждая отложенная находка имеет либо слаг, либо строку «не заведена: причина». Нулевой урожай при непустом отчёте виден сразу.
Проект без конвейера ревью — независимого отчёта нет, и это надо сказать, а не обойти молча. Задачи делались руками или чужим пайплайном, сверять урожай не с чем: остаётся проза исполнителя, то есть тот же взгляд, что и у автора. Тогда защита от занижения урожая снята, и доклад спринта обязан нести строку «урожай сверялся с отчётом исполнителя — независимого отчёта в проекте нет». Дальше это решение человека: завести конвейер, принимать выборочной перепроверкой или согласиться с ценой. Молчание здесь хуже любого из трёх исходов.
Стимулы внутри пайплайна задачи (занизить требования к проверке, пропустить проход) принадлежат ему и защищены там же.
Слоты проекта
Сессия не знает ни языка, ни сборки, ни CI. Часть проектного отвечает
канон структурой: разбор процесса (шаг 2) живёт
в docs/review.md, оракулы и «чем краснеет безусловно» — в семантике гейта в
CLAUDE.md. Остальное проект дописывает в CLAUDE.md:
- Пайплайн задачи — чем задача выполняется и что входит в его определение готовности. Сессия требует только форму: пайплайн пройден + критерии приёмки проверены поимённо.
- Общий станок — какая проверка, покраснев, врывается в замороженный спринт.
- Необратимое — что спрашивается у человека всегда (тот же слот, что у
скилла
tasks; дом один). - Ориентир по размеру спринта, если он замерялся. Умолчание — 5–8 задач, и это ориентир, а не закон.
Слота «куда копируются критерии приёмки» здесь нет намеренно: на него отвечает пайплайн проекта, перенося их в описание изменения при его заведении. Проект без пайплайна называет своё место сам, в слоте 1.
Числа проекта (сколько задач в спринте, сколько времени на задачу, каков прирост беклога) — предмет шага 2, а не константы этого скилла.
Чего этот скилл не делает
Не пишет код и не выполняет задачи. Не заводит и не переоформляет задачи сам по
себе — формат и содержимое ведёт tasks (сессия зовёт его операции). Не решает
за человека, какая цель следующая. Не двигает набор идущего спринта.