- DECISIONS.md (4040 строк, 65 тем) → decisions/, файл на тему плюс указатель; - буквенные метки решений заменены сквозными Р1–Р234, следствия получили префикс С при прежних номерах: схема букв выродилась до пятибуквенных и сломалась — `АЕАКЛ` была занята и темой 53, и темой 65; - 42 перекрёстные ссылки переписаны под новые номера и стали живыми; где номер означал тему, а слово стояло «решение», формулировка исправлена.
52 lines
4.6 KiB
Markdown
52 lines
4.6 KiB
Markdown
# 10. Ревью готовых плагинов двумя проходами (2026-08-03)
|
||
|
||
## Что было
|
||
|
||
Два независимых сабагента `fable` — по одному на `av-dev-pm` и `av-dev-pipeline`.
|
||
**20 находок, из них две найдены обоими независимо.** Прошлые три круга ревью
|
||
шли по одному проходу на всё; два прохода с разными предметами дали и больший
|
||
урожай, и перекрёстное подтверждение самого дорогого дефекта.
|
||
|
||
## Что оказалось сломано по существу
|
||
|
||
**Р36. Перестановка закрытия за коммит (решение из [темы
|
||
8](08-rollout-order.md)) сломала `reopen` и батч — и это нашли оба прохода.**
|
||
`close --implemented` печатает «дорога назад: файл восстанавливается из git», а
|
||
`reopen` искал **коммит удаления**, которого в новом порядке ещё нет: шаг 11
|
||
идёт последним, и учёт остаётся незакоммиченным. Проверено прогоном: `reopen`
|
||
отказывал кодом 2 на свежезакрытой задаче — то есть в самом вероятном своём
|
||
применении. Тем же грязным деревом ломался `task-batch`: `git rebase` и `git
|
||
worktree remove` отказывают, и **каждая успешно закрывшая задачу ветка** уезжала
|
||
бы в провалившиеся.
|
||
|
||
Починено с обеих сторон: `reopen` берёт текст из `HEAD`, если коммита удаления
|
||
нет, а шаг 11 обязан **коммитить учёт вторым коммитом** — иначе закрытие не
|
||
доезжает до основной ветки и опора «`SPRINT.md` под git» остаётся словами.
|
||
|
||
**Р37. Канонический пример `docs/.pm.json` убивал `tasks.py`.** `canon.md`,
|
||
`skeletons.md`, `tasks/SKILL.md` и `adopt.md` показывали ключ `tasks.sections`,
|
||
которого скрипт не знает: `_validate_config` отвергает неизвестные ключи кодом 3
|
||
на **любой** команде. Проект, заведённый по канону дословно, остался бы без
|
||
работы с задачами целиком — а `docs.py check` при этом печатал «канон соблюдён»,
|
||
потому что чужой код 3 уходит в «не проверялось». Секции живут в заголовках `##`
|
||
индекса и второго дома не получают.
|
||
|
||
## Что из этого следует
|
||
|
||
**С44. Класс находок тот же, что и в прошлые три круга: стыки.** Не новый код, а
|
||
место, где один файл ссылается на другой. `sprint.md` в пункте «Сделана» всё ещё
|
||
отсылал к порядку, который сам же тремя экранами ниже отменил; три остатка «шаг
|
||
9а» несли **предкоммитную** позицию закрытия; путь отчёта триажа не переживал
|
||
`opsx:archive`, хотя по нему сверяют полноту ревью четверо.
|
||
|
||
**С45. Инструкция, которую нельзя выполнить, выглядит как выполненная.** Ответ
|
||
на вопрос по документированной процедуре (снять тег) оставлял задачу
|
||
незабираемой, потому что судит **раздел**, а не тег; `canon adopt` требовал
|
||
гнать `docs.py check` «до отсутствия дрейфа», недостижимого без нарушения
|
||
запрета сочинять цели; урожай спринта, заведённый после `sprint close`, терял
|
||
автотег молча.
|
||
|
||
**С46. Два прохода по разным предметам дороже одного, но не вдвое.** Перекрытие
|
||
оказалось ровно в одной находке из двадцати — той самой, что подтвердилась
|
||
дважды. Практика остаётся: ревью на плагин, а не одно на репозиторий.
|