--- name: task-groom description: "Груминг беклога — интерактивный разбор, отвечающий на два вопроса: что сейчас самое важное и что перестало быть важным. Ответ записывается порядком строк в беклоге: первая строка — то, что делают следующим. Разбирает накопившиеся вопросы, переоценивает задачи порциями по 5–8 (сделано попутно, отменено решением, слилось с соседней, подешевело, разрослось, стало сырьём), закрывает отжившее с причиной и расставляет очередь. Использовать, когда просят разобрать беклог, расставить приоритеты, решить «что делать дальше», провести груминг или переоценку, а также когда вернулись к проекту после перерыва и надо понять, где остановились. Формат и содержимое записей — скилл av-dev:task-track; выполнение задачи — конвейер проекта." --- # Груминг: что важно, что перестало Скилл отвечает на **два вопроса**, и всё, что не служит им, — не его работа: 1. **Что сейчас самое важное?** 2. **Что перестало быть важным?** Ответ на оба **записывается порядком строк в беклоге**: первая строка секции — то, что делают следующим; то, что перестало быть важным, из беклога уходит с причиной. Приоритет — свойство очереди, а не задачи, и живёт он в индексе (правило 4 скилла `task-track`). Груминг — единственное место, где очередь назначается человеком. **Скилл интерактивный.** Он не «приводит беклог в порядок» сам: суждение о важности принадлежит человеку, и весь ход — это подготовленные развилки с рекомендацией. Что решается фактом (сделано, отменено, дублируется), решается без вопросов и показывается списком. Форматом и содержимым записей владеет скилл `task-track` — груминг зовёт его операции, а не правит файлы руками. Выполнением задачи — конвейер проекта. ## Три правила, из которых всё следует 1. **Порядок назначает человек, машина его не выводит.** Ни давность, ни тип, ни размер секции приоритетом не являются. Единственное место в очереди, назначенное не человеком, — конец секции у сырья, и оно из очереди изъято (`task-track`, правило 4). 2. **Порция важнее охвата.** Тридцать задач за заход — это усталость и штамповка: последние десять получат «оставить» не потому, что живы, а потому, что разбор затянулся. Лучше две честные порции, чем один полный проход. 3. **Причина уезжает в запись.** Всё, что решено здесь, оставляет след: `--reason` у закрытия и переноса, ответ в теле задачи, строка в докладе. Решение, оставшееся в переписке, будет принято заново через месяц. ## Груминг — операция доработки **Стадия проекта решает, применим ли груминг вообще** (дом стадии — [`task-track`, «Две стадии»](../task-track/SKILL.md#две-стадии); посмотреть — `tasks.py stage`). На **доработке** он и есть основная гигиена: беклог пополняется извне и вразнобой, порядок значит важность, и назначить её может только человек. На **стройке** оба вопроса скилла отвечены заранее. «Что сейчас самое важное» — первая строка плана, и назначил её не приоритет, а зависимость: переставить её значит сломать стройку. «Что перестало быть важным» возникает не порциями, а разом — когда меняется замысел, — и тогда пересматривается **план целиком**, а не 5–8 задач из середины. Порционный разбор здесь вреден: он вынимает шаги из списка, порядок которого и есть его содержание. Поэтому на стройке скилл говорит это строкой и **отсылает к другой работе**: [пересмотр плана целиком](../task-track/SKILL.md#пересмотр-плана-стройки) — сценарий скилла `task-track`, гигиена полей — тоже его, а исчерпанный беклог значит переход (`tasks.py stage support`). Четыре вещи он делает и на стройке, потому что от стадии они не зависят: `tasks.py check --fix`, разбор накопившихся вопросов, закрытие сделанного попутно и **возврат неудавшейся приёмки** (`reopen`). **Возврат приёмки от стадии не зависит вовсе, и это надо сказать отдельно.** Приёмщик и исполнитель у нас совпадают, и опор против этого две: независимый отчёт ревью и `reopen`. Вторая привязана к грумингу только по привычке — заметил, что закрытая задача сделана не тем, чем обещала, возвращай сразу, на любой стадии и в любой момент. ## Когда груминг созрел **Зовёт человек.** Скилл сам себя не назначает, но обязан **напоминать**, и признак наблюдаемый, а не календарный: - в беклоге появились записи, которых человек ещё не видел (заведены по ходу работы, урожаем ревью, разбором находок); - на верхних строках очереди есть задача с открытым вопросом — очередь показывает то, что взять нельзя; - `tasks.py check` печатает «готово к взятию: 0 из N» — брать сегодня нечего. **На стройке этот признак читается иначе**: он значит «план ещё не дописан», а не «пора грумить». Порога в неделях нет намеренно: счётчик простоя пришлось бы вести руками, а решает всё равно человек. Признак — **очередь перестала быть твоей**: взялся перечитывать, почему эти задачи стоят в таком порядке, — пора. ## Вопрос, блокер, необратимое | | Что это | Когда спрашиваем | Что останавливает | | --- | --- | --- | --- | | **Вопрос** | решение человека | на груминге, пачкой | взятие задачи в работу | | **Блокер** | работа не может продолжаться ни одной задачей | немедленно | всё | Право на **необратимое** — третье и отдельное: что именно необратимо, называет `CLAUDE.md` проекта, и спрашивается оно всегда, независимо от того, когда был последний груминг. **Блокер определяется исходом, а не одновременностью.** Встали разом или задачи выпадали по одной — если продолжать нечем, это блокер, и человек спрашивается немедленно, а не ждёт ближайшего груминга. **Отличать вопрос от застревания.** Правило про остаток принадлежит управлению задачами: оно решает, **сделана задача или вышла**, а это исход планирования, не исполнения. **Ниже канонический текст; конвейер проекта на него ссылается, а не пересказывает** — два экземпляра одного правила разъезжаются, и разъезжаются незаметно, потому что расхождение видно только на редком входе. > Есть остаток, который доводится без ответа, — задача продолжается, вопрос > записывается в файл. Остатка нет — задача возвращается в беклог. С двумя оговорками, без которых тест ошибается: > **Остаток, который материализует нерешённое** — записывает в хранилище, > журнал, витрину **или наружу** состояние, зависящее от неотвеченного вопроса, > — **не остаток**. Решение поднимается до начала записи: откатить запись > дороже, чем подождать ответ, а иногда невозможно. «Наружу» — часть правила, а > не пример: выкладка, публикация и отправка данных третьей стороне не > откатываются тем более. > **Пол для остатка:** остаток, из которого пропала польза, названная в «зачем», — > это не сделанная задача, а вернувшаяся в беклог. ## Ход груминга Четыре шага, и порядок — зависимость, а не список. ```mermaid flowchart TD check["tasks.py check (+ --fix)
результат — строкой в доклад"] s1["1. Осмотреться
что накопилось, чего человек ещё не видел"] s2["2. Разобрать вопросы
пачкой, не больше трёх за раз"] s3["3. Что перестало быть важным
порциями по 5–8"] s4["4. Что важно сейчас
расставить порядок строк"] check --> s1 --> s2 --> s3 --> s4 s2 -->|"неотвеченный вопрос → судим о важности вслепую"| s4 s3 -->|"без переоценки очередь строится из протухшего"| s4 ``` Схема — **сводка**: процедура каждого шага в [references/portions.md](references/portions.md), и при расхождении прав текст. **1. Осмотреться.** `tasks.py check` (при дрейфе — `--fix`), затем показать человеку текущую очередь: верхние строки каждой секции и что появилось с прошлого раза. Это половина ответа на «что важно»: очередь, которую не видели, обсуждать бессмысленно. **2. Разобрать вопросы.** Вопрос — решение человека, и разбирается он **пачкой**, а не по одному, как только возник: по одному это дёрганье, пачкой это груминг. Вопрос на верхних строках очереди разбирается **вне очереди порции**: иначе правило «задача с открытым вопросом в работу не берётся» создаёт стимул вопрос не записывать, лишь бы не вычеркнуть задачу из ближайшей работы. **3. Что перестало быть важным.** Порциями по 5–8. Сперва то, что решается фактом и не требует ничьего суждения (сделано попутно, отменено решением, дублируется, симптомы одного дефекта), затем то, что решает человек (жива ли, задача ли это ещё). **4. Что важно сейчас.** Расстановка порядка — `move --after <слаг>` и `move --first`. Разбирается **не весь беклог, а верх очереди**: первые три-пять строк каждой секции. Ниже пятой строки порядок всё равно перестаёт что-либо значить — до них дойдут после следующего груминга, и очередь к тому времени будет другой. ## Приоритет: как его расставляют **Вопрос ставится сравнением, а не оценкой.** «Насколько важна эта задача» не имеет проверяемого ответа; «что из этих двух делают раньше» — имеет. Поэтому очередь строится попарно и сверху: что первое, что после него. Доводы, которые принимаются: - **что сломано сейчас** — работоспособность обгоняет развитие, и это не правило вкуса: сломанное дорожает само; - **что разблокирует остальное** — задача, после которой можно взять три другие, стоит раньше любой из трёх; - **что дешевеет от того, что сделано** — работа рядом с только что тронутым кодом стоит меньше, чем та же работа через квартал; - **что дорожает от ожидания** — данные копятся, миграция усложняется, внешний срок приближается; - **то, что человек назвал следующим.** Довод **записывается причиной** (`move --after <слаг> --reason …`). Порядок без причины — это порядок, который на следующем груминге назначат заново с нуля. **Тема и приоритет — независимые оси.** Очередь может идти поперёк полок, и это законно: задачи одной темы не обязаны стоять подряд. Но если из одной полки годами ничего не поднимается наверх — это разговор про саму работу, а не про очередь, и он идёт на шаге 3. ## Документы устаревают тем же ходом работы Груминг судит **задачи**, а не документы, и агентов канона не зовёт: они принадлежат скиллам документации, и когда их звать — решают они. Но повод назвать это здесь есть: беклог и документы протухают от одного и того же — от сделанной работы. Пришёл на груминг и видишь, что с прошлого раза сделан десяток задач, — скажи строкой, что документы стоит сверить (`av-dev:doc-healthcheck`), и иди дальше. Документов канона в проекте нет — сверять нечем, и это тоже строка. ## Интерактив - Вопросы — через `AskUserQuestion`, **не больше трёх за раз**. Порция в 5–8 задач обычно даёт больше трёх суждений: веди несколько итераций по ≤3, а не по одному вопросу на задачу и не одним перегруженным запросом. - К каждому варианту — **предварительное суждение, рекомендация первым вариантом**: «предлагаю выкинуть, потому что …». Возразить дешевле, чем судить с нуля. - Всё, что решается фактом, решай сам и показывай списком в докладе. - **Останавливайся на границе порции**, даже если «ещё чуть-чуть осталось». Между порциями — промежуточный доклад. Примеры итераций, отбор порции, храповик на залежавшихся — [references/portions.md](references/portions.md). ## Стимулы, которые процесс создаёт Правило, которое можно обойти в свою пользу, будет обойдено. **Приёмщик и исполнитель совпадают, и это надо назвать вслух.** Задачу закрывает тот же агент, который её и сделал. Груминг приёмкой не занимается — отдельного ритуала у неё нет, — и настоящих опор остаётся две: - **независимый отчёт ревью** — артефакт, написанный не исполнителем: отчёт триажа в `openspec/changes/archive//review/` (до архивации — `changes//review/`); - **`reopen <слаг> --reason`** — закрытие не окончательно. Заметил, что закрытая задача сделана не тем, чем обещала, — возвращай, это штатная операция, а не скандал, и ждать груминга она не требует (на стройке его и не будет). Индексы под git: `git log -p` по беклогу показывает, что и когда закрыто, потому что закрытие коммитится отдельным коммитом учёта. Известные обходы: - **Не записать вопрос** на задаче, которую хочется поднять наверх очереди. Защита: вопросы верхних строк разбираются вне очереди порции, шагом 2. - **Оставить всё как есть.** Груминг, на котором ничего не сдвинулось и ничего не закрылось, — это не «беклог в порядке», а не проведённый груминг. Защита: задача из верхних строк, которую и этот заход оставляет без изменений, **либо двигается, либо получает записанную причину**, почему её держат. - **Расставить порядок молча**, без доводов: тогда через месяц он неотличим от случайного. Защита: причина у каждого движения и строка доклада. - **Разобрать много и мелко** вместо немногого и важного: тридцать полей гигиены вместо трёх решений о важности. Защита: гигиена — работа скилла `task-track` и побочный продукт здесь; доклад называет **решения**, а не правки. ## Слоты проекта Груминг не знает ни языка, ни сборки, ни CI. Проект дописывает в `CLAUDE.md`: 1. **Что считается сломанным** — какая красная проверка обгоняет развитие. Не названо — спрашиваем человека, а не решаем сами. 2. **Необратимое** — что спрашивается всегда (тот же слот, что у скилла `task-track`; дом один). 3. **Ориентир по размеру порции**, если он замерялся. Умолчание — 5–8 задач, и это **ориентир, а не закон**. Числа проекта (сколько задач приходит за месяц, каков прирост беклога) — предмет наблюдения человека, а не константы этого скилла. ## Доклад - Что просмотрено: N из M, сколько порций, по какому признаку отобраны. - Вопросы: разобрано N, из них отвечено без человека N, снято тегов N. - **Что перестало быть важным**: удалено как реализованное (со ссылками), ушло без реализации (с причинами), понижено до сырья, слито, сменило тип. - **Что важно сейчас**: верх очереди по каждой секции — слаги в порядке, и по каждому движению довод одной строкой. - **Границы покрытия**: сколько задач не трогали и какие именно секции или теги остались — иначе доклад читается как «беклог разобран». - `tasks.py check` после правок — результат строкой. ## Чего этот скилл не делает Не пишет код и не выполняет задачи. Не заводит и не переоформляет записи сам по себе — формат и содержимое ведёт `task-track` (груминг зовёт его операции). Не решает за человека, что важно: он готовит развилки и рекомендует. Не принимает закрытые задачи отдельным ритуалом — `reopen` есть, момента у него нет. Не судит документы проекта — это скиллы `av-dev:canon` и `av-dev:doc-healthcheck`.