Files
dev-skills/av-dev-pm/skills/tasks/references/adopt.md
T
avandClaude Opus 5 1fb006df4a ревью двумя проходами: 20 находок, все починены
Два независимых сабагента на av-dev-pm и av-dev-pipeline. Две находки нашли оба.

Главная — моя же перестановка закрытия за коммит сломала reopen и батч. close
печатал «дорога назад из git», а reopen искал коммит удаления, которого в новом
порядке ещё нет: шаг 11 последний, учёт остаётся незакоммиченным. Проверено
прогоном — отказ кодом 2 на свежезакрытой задаче. Тем же грязным деревом
ломались rebase и worktree remove в батче: каждая закрывшая задачу ветка уехала
бы в провалившиеся.

Починено с обеих сторон: reopen берёт текст из HEAD, если коммита удаления нет,
а шаг 11 коммитит учёт вторым коммитом.

Вторая — канонический пример docs/.pm.json убивал tasks.py. Четыре документа
показывали ключ tasks.sections, которого скрипт не знает: неизвестный ключ это
код 3 на любой команде. Проект, заведённый по канону дословно, остался бы без
работы с задачами, а docs.py при этом печатал «канон соблюдён». Секции живут в
заголовках индекса и второго дома не получают.

Остальные восемнадцать: init писал конфиг в упразднённый .tasks.json;
looks_like_tasks не видел переименованный индекс; урожай спринта терял автотег
после sprint close; ответ на вопрос по инструкции оставлял задачу незабираемой;
adopt требовал недостижимого зелёного; путь отчёта триажа не переживал archive;
review-specs не имел режима для стыка после слияния; три остатка «шаг 9а» несли
предкоммитную позицию закрытия; sprint.md отрицал сам себя в пункте «Сделана».

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 15:54:15 +03:00

10 KiB
Raw Blame History

Адаптация каталога задач

Проект, где задачи уже как-то ведутся, и из имеющегося материала выводится заполненный каталог задач: цели, задачи, кладбище, индексы. Операция разовая — после неё проект живёт скиллами tasks и session.

Это часть приведения проекта к канону. Раскладку docs/ целиком ведёт скилл av-dev-pm:canon; он же зовёт этот сценарий на шаге «каталог задач», потому что форматом задач владеет tasks, а не canon. Отдельно сценарий вызывается, когда переводить надо только задачи.

Вход какой угодно: старая раскладка av-dev-backlog (индекс README.md, кладбище CLOSED.md, приоритеты секциями, транслитные слаги, файлы рядом с индексом), TODO.md, россыпь заметок, раздел «планы» в README.md, список шагов в плане проекта.

Три правила, из которых всё следует

  1. Сперва карта, потом файлы. Человеку показывается, что найдено, как разложилось по целям и что не разложилось, — и только после подтверждения пишется хоть один файл. Это то же правило, что у интейка находок ревью: массовое заведение записей без подтверждения — самый дорогой отказ, потому что разгребает его потом переоценка.
  2. Ничего не терять. Исходный текст переезжает в тело, хук и причина сохраняются, кладбище переносится строка в строку. Переименование слага — не правка, а перенос ссылок: он делается одним проходом вместе с переименованием, иначе останутся битые ссылки, которых никто не проверяет.
  3. Что не классифицировалось — назвать поимённо. Проглоченный пункт выглядит как «всё перенеслось». Список «не разложилось» идёт в доклад целиком, с причиной по каждому пункту.

Форма: карта — суждение — запись

Механику несёт tasks.py adopt, суждение — ты. Разделено ровно по границе «машина умеет / не умеет»:

tk="$CLAUDE_PLUGIN_ROOT/skills/tasks/scripts/tasks.py"

python3 $tk adopt scan --from docs/backlog docs/plan.md TODO.md \
        --target docs/tasks --out tasks-adopt-plan.json      # только чтение
python3 $tk adopt apply --plan tasks-adopt-plan.json \
        --refs docs openspec CLAUDE.md README.md             # запись

scan ничего не пишет, кроме карты: он распознаёт раскладку, собирает записи, хуки, причины, кладбище, помечает похожее на транслит и на открытый вопрос в прозе, и называет поимённо то, что не разложилось. apply пишет каталог целиком одним проходом и чинит перекрёстные ссылки.

Между ними — твоя работа, которую машина не сделает:

  • английские слаги. Перевести taj-brejk-pri-ravnoj-polnote в tie-break-equal-completeness может только тот, кто понимает смысл. scan честно говорит: проверить надо все слаги, признаки транслита — эвристика;
  • цели. Шаги плана — готовые цели линии (порядок и обоснование у них уже есть); тематические скопления задач — кусты («прочность слияния», «журнал и пересборка»). Предлагаешь ты, назначает человек;
  • что вообще не задача. Обоснование порядка шагов, абзац прозой, заголовок раздела — это не пункты беклога, и они уходят в «не разложилось» с причиной.

Порядок

  1. Осмотрись. Где лежат задачи, план, заметки. Каталог задач по канону — всегда docs/tasks. Секции беклога (--sections) — по умолчанию ядро,инфра; если у проекта деление другое по существу, оно называется здесь, а не подгоняется под умолчание, и становится заголовками ## индекса — их единственным домом. В docs/.pm.json секции не пишутся.
  2. adopt scan по всем источникам разом. Один прогон, одна карта: два прохода дадут два несогласованных состояния.
  3. Заполни карту: slug (английский), section, goal у каждой записи; список goals — из шагов плана и из кустов. Закрытый шаг плана целью не заводится. Пустой goal — законный исход только у идеи.
  4. Покажи человеку карту через AskUserQuestion, ≤3 вопроса за итерацию, рекомендация первым вариантом. Показывается: сколько записей, предлагаемые цели (линия и кусты) с обоснованием, спорные отнесения, список «не разложилось». Массовые механические решения (слаги, порядок строк) не выносятся — это механика.
  5. adopt apply. --refs перечисляет всё, где могут стоять ссылки на слаги: документация, архив изменений, CLAUDE.md, README.md. Скрипт посчитает и покажет, сколько ссылок поправлено и по каким слагам.
  6. tasks.py check и доклад.

apply отказывается писать поверх живого каталога и проверяет карту целиком до первой записи: неверная секция, дубль слага, цель, которой нет в карте — всё это отказ до того, как на диске появился хотя бы один файл.

Переходное состояние — объявляется, а не заминается

Сразу после адаптации задачи в большинстве своём не готовы к взятию: у них нет критериев приёмки, а у части может не быть цели. Это нормально, но обязано быть названо, иначе следующий агент примет пустой беклог за поломку.

apply печатает состояние по факту: сколько задач без цели (это ошибки check) и сколько без критериев (check их ошибкой не считает, но sprint take такую задачу не возьмёт). Закрывается это порциями переоценки — шаг 3 скилла session, 5–8 задач за порцию: проставить цели, превратить «готово, когда» в критерии с оракулами, вынуть вопросы из прозы в раздел «Вопросы».

Готовность к первому спринту — не «check зелёный», а «есть 2–5 критериев хотя бы у набора под одну цель».

Чего адаптация не делает

  • Не удаляет источники. Старый каталог остаётся на месте: сверить и убрать — дело человека, удалять чужое молча нельзя. В доклад идёт готовая команда.
  • Не переписывает подписи ссылок. [docs/backlog](docs/tasks/BACKLOG.md) — цель поправлена, текст остался; это правится глазами, и таких мест немного.
  • Не сочиняет критерии приёмки и не придумывает цели, которых в материале нет. Придуманная цель хуже отсутствующей: под неё соберут спринт.
  • Не трогает историю. В коммитах старые слаги остаются, и это нормально.

Доклад

  • Источники и что в каждом распознано (раскладка, индекс, кладбище, секции).
  • Сколько записей перенесено, сколько целей заведено (линия / кусты) и откуда каждая выведена.
  • Переименования: сколько слагов, сколько ссылок поправлено и в скольких файлах — числом, а не «поправлены ссылки».
  • Не разложилось: поимённо, с причиной.
  • Переходное состояние: сколько задач без цели, сколько без критериев, чем и за сколько порций закрывается.
  • tasks.py check — результат строкой.