Files
dev-skills/av-dev-pm/skills/session/references/cadence.md
T
avandClaude Opus 5 47a2f3de63 язык скиллов av-dev-pm: проход упрощения пятью агентами и разбор находок
Эксперимент: по сабагенту на каждый скилл av-dev-pm, задача — переписать текст
более простыми словами, но только там, где уверен и без потери смысла и
точности. Нормой служил устав языка самого проекта, language.md, включая его
раздел «Порог правки»: правка без нарушенного правила не делается.

36 правок в двенадцати файлах, +64/-63 — почти строго замена, а не
переписывание. Правили залог (пассив с названным деятелем в творительном),
отглагольные существительные, параллельность перечней, канцелярит «является»,
пару garden-path и одно двойное отрицание. Контракт не задет нигде: в диффе нет
изменённых строк-заголовков, а код-спаны встречаются ровно парой минус-плюс,
то есть ни имя, ни флаг, ни путь не переписаны.

Отчёты «что рассматривал и не тронул» вышли длиннее отчётов о правках у всех
пятерых, и это главный результат прогона. Самый частый повод остановиться —
слово, живущее в четырёх файлах: конфляция, интейк, провенанс, непоймание.
Правка в одном месте развела бы словарь, а править все — уже не упрощение
текста скилла, а сквозной проход по репозиторию. Второй повод — формулировка,
дословно повторённая в соседнем плагине: декорреляция, материализация
нерешённого, «при расхождении прав текст».

Шестой агент проверил все 36 правок и нашёл четыре.

Перестановка слов в task-research.md развела формулу с её домом: «число без
источника проход ревью обязан читать как условие» стоит в canon.md и в уставе
doc-consistency, который прямо ссылается на канон как на источник. Откачено —
это ровно тот класс расхождения, который сам doc-consistency и ловит.

«Держит H1, мету и индекс в согласии» — управление требует дополнения, а
language.md в разделе англицизмов прямо оговаривает: русский аналог звучит
коряво — остаётся термин. Взят третий вариант, «согласованными».

В skeletons.md «правка тянет запись, и она называет» — местоимение указывает
на два женских существительных сразу. Стало «и запись называет».

Четвёртая находка не откачена: правка в init/SKILL.md хорошая, но развела
конструкцию с близнецом в canon/SKILL.md — выровнена вторая половина.

Побочно найдена старая логическая инверсия в DECISIONS.md, решение U:
«становится неотличимым, только если отрицание обязательно» — смысл вывернут,
в docs/SKILL.md и во второй записи журнала он правильный. Починено.

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

24 KiB
Raw Blame History

Сессия: четыре шага

Одна сессия между спринтами. Порядок шагов — зависимость, а не список: переоценивать задачи, не разобрав вопросы, значит переоценивать вслепую; набирать спринт, не переоценив, значит набирать из протухшего.

Начинается сессия с tasks.py checkcheck --fix, если дрейф накопился) — результат идёт строкой в доклад.

Шаг 1. Разбор вопросов

tasks.py list --questions — всё, что накопилось. Вопрос это решение человека, и разбирается он пачкой, а не по одному, как только возник: по одному — это дёрганье, пачкой — это сессия.

Порядок по каждому вопросу:

  1. Проверь, не отвечен ли он уже — решением, документом, соседним изменением, самим ходом прошедшего спринта. Отвеченный вопрос не выносится человеку: это самая частая находка и она не требует ничьего решения.
  2. Сформулируй развилку с вариантами и последствием каждого, рекомендация — первым вариантом.
  3. Вынеси пачкой через AskUserQuestion, не больше трёх за раз.
  4. Запиши ответ в тело задачи, опустоши раздел «Вопросы», сними тег (edit <slug> --rm-tag question), перепиши «зачем»: «Решено: …» на вопрос «почему это лежит в беклоге» уже не отвечает. Опустошение раздела — не уборка, а условие взятия: правило и причина в скилле tasks, references/task-format.md.

Вопросы на задачах-кандидатах разбираются вне очереди порции — здесь же, на этой сессии, даже если сама задача в порцию переоценки не попала. Иначе правило «задача с открытым вопросом в набор не берётся» создаёт стимул вопрос не записывать, лишь бы не вычеркнуть задачу из ближайшего спринта.

Шаг 2. Разбор прошедшего спринта — про процесс, а не про задачи

Не «что мы сделали» (это доклад спринта, он уже был), а:

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

Замеров процесс не ведёт намеренно: оценки в очках и velocity не взяты («Почему не Scrum»), а спринт ограничен объёмом, а не временем — сравнивать «сколько заняло» не с чем. Разбор здесь качественный, и это не упущение.

Артефакт обязателен. Вывод, оставшийся в контексте сессии, не существует: следующая сессия его не увидит. Дом у него один и известен из канона — docs/review.md: вывод про конвейер и про то, что перестали проверять, идёт в раздел настройки, вывод про воспроизведённый дефект — в журнал. Решение с долгим следом — в docs/adr/.

Отдельным ритуалом ретроспектива не выделяется: процесс личный, синхронизировать некого.

Здесь же зовутся оба судьи документов — на весь канон разом, а не на пачку, отобранную работой:

  • doc-consistency — согласованность документов между собой и с openspec: факт в двух домах, прямое противоречие, поведение в architecture.md вместо спек, ADR без парного статуса при замене, число без провенанса;
  • doc-code-drift — сверка с кодом по закрытому перечню фактов: имя основной ветки, команды, пути, внешние зависимости поимённо, настройки с числовым значением, единые точки проекта, capability.

Раз в спринт, а не чаще, и причина в цене: оба на opus, а второй ещё и читает репозиторий. Но и не реже — спринт это ровно то, что двигает код и документы: переименованная цель сборки, ушедшая зависимость, второй способ делать то, что обзор объявил единственным; факт, дописанный в architecture.md, уже живущий в CLAUDE.md. Протухшее и раздвоившееся неотличимо от свежего, и по нему принимают решения, пока кто-нибудь не наткнётся.

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

Находки обоих — обычный материал переоценки: строка на замену идёт в документ сразу, работа больше чем на абзац становится задачей типа chore. Позвал — скажи в докладе, кого именно позвал, и приложи границы покрытия; не позвал — скажи и это, иначе доклад читается как «сверено».

Шаг 3. Переоценка задач

Цель — выкинуть то, что перестало быть задачей, и вернуть остальному честное состояние. Не «пересмотреть всё», а «пересмотреть порцию до конца».

Порция и правило остановки

Тридцать задач за один заход — это усталость и штамповка: последние десять получат «оставить» не потому, что живы, а потому, что сессия затянулась.

  • 5–8 задач за порцию. Размер обоснован усталостью, а не пропускной способностью, и менять его не надо — надо брать несколько порций за сессию.
  • Сколько порций: не меньше ⌈урожай прошедшего спринта / 8⌉. Урожай — это задачи, заведённые за спринт; при урожае в 15 это две-три порции.
  • Отбор порций по порядку:
    1. урожай спринтаlist --tag sprint:<слаг>: свежезаведённое ещё не проходило ни одной проверки на нужность. Тег на задачах проставлен автоматически при заведении — руками не метят и не вспоминают. Слаг берётся из отчёта sprint close, а не из SPRINT.md: сессия идёт после закрытия, а закрытие этот файл очищает;
    2. дальше по залежалостиlist --stale;
    3. по потребности — одна секция целиком, один тег (партия ревью), одна цель (--goal), список от пользователя.
  • Останавливайся на границе порции, даже если «ещё чуть-чуть осталось». Между порциями — промежуточный доклад.

Что делать с каждой задачей

Сперва то, что не требует ничьего решения:

  1. Проверь, не сделано ли уже. Задача, реализованная попутно в соседнем изменении, — самая частая находка. Смотри код, документацию, историю коммитов по ключевым словам. Удаление «как реализованной» деструктивно и без следа (в REJECTED.md реализованные не пишутся), поэтому порог улики жёсткий: close <slug> --implemented только имея конкретный коммит или строку документа, закрывающие задачу, и ссылка идёт в доклад. Есть лишь косвенные признаки — не удаляй сам, вынеси в пачку вопросов. Сделана частично → задача сжимается до остатка: тело правишь редактором, заголовок и «зачем» — через edit.
  2. Проверь, не отменена ли решением. Документ, ADR или архивное изменение мог закрыть вопрос иначе — тогда close <slug> --reason "<ссылка на решение>". Задача закрывается не только коммитом.
  3. Проверь пересечения. Две задачи об одном — содержимое в одну, вторую close <slug> --reason "слита с <другой-слаг>". Смотри шире порции: интейк дедуплицирует новое против существующего, но никогда не пересматривает уже лежащее, и две задачи с одной причиной могут лежать рядом месяцами.
  4. Пере-кластеризуй по общей причине. Несколько задач, оказавшихся симптомами одного дефекта, сливаются в одну — это находка, которую интейк дать не мог.
  5. Гигиена полей — протухшее «зачем», вопрос в прозе, снятый ответ, свойство репозитория в рамках, предписание процесса в теле, тип, разошедшийся с задачей, границы вместо реализации в разделе «Затрагивает». Список и правила — в скилле tasks. Переоценка — то самое место, где беклог добирает тип и разделы его схемы: требовать их на входе значило бы выгонять в заметки то, что должно лежать задачей, а к взятию в спринт они уже обязательны. Блок здоровья check печатает, сколько записей готово к взятию, — по этому числу и видно, добрала переоценка или нет.

Затем — то, что решает пользователь:

  1. Жива ли она вообще. Контекст мог измениться: ушла зависимость, отпал сценарий, обошли иначе. Здесь и звучит вопрос, выкидывать ли.

  2. Та ли цель — и нужна ли она вообще. Приоритетов нет, и «повысить» нечего — вместо повышения задача меняет цель (edit <slug> --goal <другой>) или входит в ближайший набор. feature, которой не находится цель, — кандидат на выход: новая возможность вне цели это возможность, которой никто не заказывал. Операционной задаче (fix, chore, research) цель не нужна, и выдумывать её здесь не надо.

    Отменяется и сама цель — когда замысел оказался неверен, а не когда задача выбрала не ту. Тогда порция расширяется до всех задач этой цели: каждую либо закрыть своей причиной, либо перевесить на другую цель, и только потом закрыть цель. Порядок и почему он такой — task-goal.md. Здесь этому и место: отмена цели это разбор её задач, а разбор задач — этот шаг.

  3. Задача ли это по-прежнему. Не проходит тест «готова к взятию» → edit <slug> --type research и опустошённый раздел «Вопрос», то есть сырьё; дальше штурм. Разрослась → это несколько задач под той же целью, дальше декомпозиция.

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

Храповик на залежавшихся

Сильно залежавшаяся задача — сигнал сама по себе: её либо ни разу не собирались делать, либо нечем взять. Измеряй наблюдаемым — датой последней правки из git (list --stale ставит такие первыми); счётчик «сколько сессий пережила» нигде не хранится.

Задача из верхних строк --stale, которую и этот заход оставляет без изменений, либо двигается (меняет цель, идёт в набор, уходит с причиной), либо остаётся с явно записанной причиной, почему её держим (move <slug> --section <та же> --reason …). Молчаливое «оставить как есть» на давно неподвижной задаче — это решение не принимать решение; запись причины превращает его в осознанное и не даёт тому же вопросу всплыть на следующей сессии.

Интерактив

  • Вопросы — через AskUserQuestion, не больше трёх за раз. Порция в 5–8 задач обычно даёт больше трёх суждений — тогда веди несколько итераций по ≤3, а не по одному на задачу и не одним перегруженным запросом.
  • К каждому варианту — предварительное суждение, рекомендация первым вариантом: «предлагаю выкинуть, потому что …». Пользователю дешевле возразить, чем судить с нуля.
  • Всё, что решается фактом (сделано / отменено / дублируется), решай сам и показывай списком в докладе, а не выноси в вопросы.

Пример одной итерации — три залежавшихся задачи, механику по ним уже разобрали:

Переоценка: 3 залежавшихся (порция по --stale)

  1. versii-kachestvo-repaki — версии и качество одного тайтла
    • Выкинуть (рекомендую) — помечена «не боль», за полгода ни разу не возникла
    • Оставить под целью nadyozhnost-razdach
    • Перевести под цель kachestvo-mediateki — там она первая в очереди
  2. backup-sqlite — бэкап базы
    • Оставить под текущей целью (рекомендую) — не сработала, но риск реальный
    • Взять в ближайший набор — без бэкапа ретеншн опасен
    • Выкинуть
  3. guessit-sputnik — вынести распознавание в сервис-спутник
    • Понизить до сырья (--type research) (рекомендую) — не проходит тест «готова к взятию»
    • Оставить задачей

Каждый вариант несёт причину — ту самую, что уедет в --reason. Ответы применяй сразу и, если в порции осталось ещё, следующей итерацией показывай следующие ≤3.

Шаг 4. Выбор цели и набор спринта

  1. Покажи состояние проекта: секцию Готово (что приложение уже умеет — это половина ответа на «где мы»), затем Запланировано с обоснованием очереди, Направления, и по каждой цели-кандидату — сколько под ней задач без открытых вопросов (list --goal <слаг>). Цель без готовых задач набором не станет: её сперва надо декомпозировать.

  2. Цель называет человек. Это продуктовое решение, а не механика: агент предлагает и объясняет, но не выбирает.

  3. Набор собирает агентsprint start --goal <слаг>, затем sprint take …. Скрипт не даст взять цель, задачу с чужой целью, с открытым вопросом, без типа и без разделов, которых требует её тип (у fix это в том числе Воспроизведение, у researchВопрос и Куда ляжет ответ, и сырьё поэтому не берётся вовсе). Задача без цели (fix, chore, research) берётся свободно — операционная работа входит в набор помимо его цели.

  4. Набор показывается человеку до старта работ. Показ — это и есть момент заморозки: после него набор не двигается. В показе называется состав по типам — три fix и ни одной feature под целью развития это разговор про цель, а не про набор, и увидеть его надо до заморозки, а не в докладе по итогам.

    Здесь же последний дешёвый момент заметить разнородную задачу: раздел «Затрагивает» показывает границы до того, как заведено предложение об изменении. Строка, которая одна тянет задачу на ступень выше остального перечня, — кандидат на разрез (шов — в tasks, references/split.md). Замеченная здесь, она стоит одного edit; замеченная на ревью — выброшенного предложения.

  5. Задача, которой для взятия не хватает только разделов её типа, дописывается здесь же — критерии с оракулами, перечень границ, шаги воспроизведения. Но если для этого нужен ответ человека, это вопрос, и задача в набор не идёт.

Размер — ориентир, а не закон: 5–8 задач. Можно взять больше, можно меньше — набор под цель важнее круглого числа; одна крупная задача спринтом тоже бывает.

Доклад сессии

  • Что просмотрено: N из M, сколько порций, по какому признаку отобраны.
  • Вопросы: разобрано N, из них отвечено без человека N, снято тегов N.
  • Разбор процесса: что записано и куда.
  • Сверка документов с кодом: звался ли doc-code-drift, что проверено из названного, что разошлось.
  • Изменения списком: удалено как реализованное (со ссылками), ушло без реализации (с причинами), понижено до сырья, слито, сменило тип или цель.
  • Новый спринт: цель, набор со слагами, дата, состав по типам.
  • Границы покрытия: сколько задач не трогали и какие именно секции, теги или цели остались — иначе доклад читается как «беклог разобран».
  • tasks.py check после правок — результат строкой.