Files
dev-skills/av-dev/skills/task-track/references/split.md
T
av de12a4d8a3 слияние: три плагина стали одним av-dev, скиллы получили префиксы
Каталоги, агенты и общие дома переехали в av-dev/; скиллы названы по прежнему
плагину — doc-*, task-*, code-*, с двумя смысловыми именами вместо тавтологии:
doc-sync вместо docs, task-track вместо tasks. Манифесты сведены к двум
плагинам. Пространства имён вызовов и пути внутри дерева переписаны машинно;
проза, которая называет прежние плагины отдельными, идёт следующим шагом.
2026-08-13 10:10:51 +03:00

117 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Декомпозиция и мозговой штурм
Обе операции превращают одну запись в несколько (или в ноль). Разница во входе:
декомпозиция дробит **слишком крупную задачу**, штурм прорабатывает **идею**,
которая ещё не задача.
## Тест декомпозиции
Задачу можно дробить, только если части удовлетворяют **обоим** условиям:
1. **Мерджатся независимо.** Часть Б не требует, чтобы часть А была уже влита.
Есть порядок «сперва А, потом Б, иначе не собрать» → это не декомпозиция, а
план реализации: шаги остаются **внутри одного файла**.
2. **Каждая — самостоятельный шаг.** Часть, осмысленная только в комплекте с
другой, — не задача. Проверяй тестом «готова к взятию» (task-format): какую
строку «Завершения» цели двигает **именно эта часть** и какие у неё
собственные критерии приёмки. У операционных частей (`fix`, `chore`,
`research`) цели может не быть — тогда достаточно собственных критериев.
Не проходит хотя бы одно — **не дроби**. Ложная декомпозиция плодит файлы,
которые нельзя взять поодиночке, и переоценка потом склеивает их обратно.
## Где резать, если резать можно
Тест выше говорит, **допустим** ли разрез. Где его провести из нескольких
допустимых мест — отвечает шов.
**Шов — там, где падает метка ревью.** Раздел «Затрагивает» перечисляет
границы; если одна строка перечня поднимает метку выше остальных, эта часть и
режется отдельно. Пример: задача перекладывает несколько узлов разом и заодно
добавляет два поля в существующий ответ. Целиком это `large` — семь проходов по
всему диффу, включая два, что держат машину и идут цепочкой. Разрезанная по шву,
она даёт `large` на маленькой переложенной части и `medium` на остатке.
**Считай костяк, а не файлы.** У каждой задачи есть несокращаемые четыре прохода
(гейт, спеки, код, триаж), и они платятся за каждую. Разрез, после которого обе
половины остаются в одной метке, делает ревью **дороже**: тот же объём
проверяется тем же составом, но костяк оплачен дважды. Отсюда правило: **резать,
когда разрез снимает дорогой проход с большей части диффа**, и не резать, когда
он просто делает файлы мельче.
**Это планирование, а не предписание процесса.** Метка ревью выбирается по
факту изменения — тем, кто его видит, — и в тело задачи не пишется: строка
«делать с меткой medium» это ровно тот второй дом правила выбора, который
гигиена полей снимает. Шов пользуется меткой как **признаком**, что в задаче
две разнородные работы; решение о метке остаётся за конвейером.
**Цель наследуется.** Все части несут `goal:` родителя: декомпозиция не меняет
того, чему работа служит. Если у части цель другая — это признак, что дробили не
по той границе, либо что часть вообще из другой работы.
## Что делать с родителем
После разделения родитель **не остаётся** третьей висящей строкой:
- части полностью замещают его → `close <slug> --reason "разложена на a, b"`.
`REJECTED.md` здесь — не «выкинули», а именно тот след, что переживает запись:
через квартал вопрос «куда делась задача X» отвечается строкой со ссылками на
наследников, а не археологией git;
- родитель осмыслен как **возможность**, а не как шаг → это цель, и **строка
переезжает**: `edit <slug> --type goal --section <часть роадмапа>` снимает её с
`BACKLOG.md` и вставляет в `ROADMAP.md`. Файл в `items/` при этом не двигается —
он и есть запись. Части получают `--goal <слаг родителя>`, а закрывать родителя
нечем и незачем: он не выкинут, он стал целью.
**Промежуточного зонтика между целью и задачей нет.** Тип `epic` упразднён:
роль зонтика играет цель, а слишком крупный шаг дробится на шаги помельче под
той же целью. Если частям нужен общий заголовок — значит у них общая
возможность, и её надо назвать целью, а не заводить временный тип.
## Когда декомпозиция случается посреди работы
Задача, которая **оказалась крупнее задачи**, распознаётся до того, как под неё
заведено предложение об изменении: иначе его придётся выбрасывать. Она выходит
из работы на декомпозицию, а её строка возвращается в беклог с причиной
(`move … --reason "крупнее задачи"`). Части заводятся сразу под той же целью, и
**место в очереди им назначает человек**: машина поставит их в конец секции, а
крупная задача редко распадается на что-то менее срочное, чем была сама.
## Мозговой штурм сырья
Сырьё — запись типа `research`, у которой раздел «Вопрос» пуст: она не проходит
тест «готова к взятию», потому что неясно, что именно делаем. Штурм проясняет —
и это **generative-операция, а не applicative**.
Исход штурма и есть заполненный «Вопрос» (тогда разведку можно брать в работу)
или набор задач с типами, которые из ответа следуют. Третий законный исход —
`close --reason`.
Applicative-штурм («перечисли задачи, следующие из идеи») выдаёт очевидное:
перечисляется то, что уже видно в формулировке. Ценное — на уровень выше.
1. **Сперва — формы, а не задачи.** Предложи **три разные постановки** идеи и
назови **компромисс каждой**: что она даёт, чем платит, что оставляет за
бортом. Если получилась одна постановка — штурм не состоялся, это
applicative.
2. **Вынеси формы пользователю** через `AskUserQuestion` с компромиссами. Рамку
выбирает он: это продуктовое решение, не механика.
3. **Назови цель.** Выбранная форма служит цели — существующей или новой. Идея,
для которой цель не находится, скорее всего уезжает в `REJECTED.md`, а не
заводится задачей.
4. **Только выбранную форму** дроби по тесту декомпозиции выше и проставь
критерии приёмки: без них наследники останутся идеями под другим именем.
**«Выкинуть» — полноправный исход штурма, а не его неудача.** Проработка, честно
показавшая, что пользы нет или она несоразмерна цене, — это результат: идея
уезжает с этой самой причиной, и та причина гасит её повторное появление.
## Доклад
- Идея/задача на входе, выбранная рамка (для штурма), задачи-наследники со
слагами, целями и секциями.
- Судьба родителя: удалён / стал целью / выкинут с причиной.
- `tasks.py check` после правок.
- Границы покрытия: какие постановки рассмотрены и какие сознательно отброшены —
чтобы штурм не пришлось повторять с нуля.