Files
dev-skills/decisions/64-three-plugins-merged.md
T
av bf6a173115 журнал решений: разложен по теме на файл, метки решений стали номерами
- DECISIONS.md (4040 строк, 65 тем) → decisions/, файл на тему плюс указатель;
- буквенные метки решений заменены сквозными Р1–Р234, следствия получили
  префикс С при прежних номерах: схема букв выродилась до пятибуквенных и
  сломалась — `АЕАКЛ` была занята и темой 53, и темой 65;
- 42 перекрёстные ссылки переписаны под новые номера и стали живыми; где номер
  означал тему, а слово стояло «решение», формулировка исправлена.
2026-08-13 12:40:56 +03:00

6.1 KiB

64. Три плагина слились в один: раскол платили, а не пользовались (2026-08-13)

Плагинов было три — av-dev-docs, av-dev-tasks, av-dev-code, — и разрез между ними шёл по признаку «ставится порознь» (тема 51). Признак был выбран верно, но посылка под ним не проверялась: за всё время подмножество не понадобилось ни разу, а платился раскол постоянно.

Цена измерена, а не оценена: шестьдесят с лишним вызовов между скиллами при цикле зависимостей docs → code → docs, язык проектных текстов четырьмя помеченными копиями по 213 строк, словарь сопровождения двумя, правило границы семью, дюжина веток «плагина нет» — и copies.py, заведённый ровно затем, чтобы это не разъезжалось молча.

Довод «а вдруг понадобится» снят наблюдением владельца, а не спором. Ждали случая «документы и задачи без OpenSpec» — например, ansible-репозиторий. Он уже покрыт: сценарий обслуживания в resolve OpenSpec не требует по построению, а docs.py считает отсутствие openspec/ неприменимостью, а не отказом. То есть режим, ради которого держали раскол, работает и в слитом плагине.

Слияние оказалось дешевле, чем выглядело, потому что граница была сделана правильно. Присутствие соседа узнавалось следом в проекте (.docs.json, .tasks.json, openspec/config.yaml), а не перечнем установленных плагинов. Значит мягкость поведения держалась на состоянии проекта и пережила слияние без единой правки логики: сменилась упаковка, а не механика. Дом правила переехал из plugin-boundary.md в absence.md и стал говорить о том, чем он и был на деле, — о частях раскладки, которых может не быть.

Р231. Версия стала одна и начинается с 1. Две версии — канон 14 и формат задач 1 — двигались порознь, потому что порознь ставились плагины; с одним плагином два числа означали бы только вопрос, по какому журналу повышать. Прежние журналы закрыты и не переписаны: адрес, верный на день записи, остаётся свидетельством. Служебный файл один, .av-dev.toml в корне репозитория, и формат выбран ради комментариев — файл живёт в чужом репозитории, и назначение числа должно читаться из него самого, а не из документации плагина. Отсюда правило записи: скрипт правит строку, а не переписывает файл.

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

Что из этого следует

С218. Разрез, оправданный сценарием, обязан этот сценарий однажды увидеть. «Ставится порознь» — проверяемое утверждение, и проверяется оно не рассуждением, а тем, поставил ли кто-нибудь половину. Пока не поставил, разрез оплачивается копиями за случай, которого нет.

С219. Механика, привязанная к состоянию проекта, переживает перестановку плагинов; привязанная к их составу — нет. Это и есть практическая разница между «узнаём следом» и «узнаём перечнем», и обнаруживается она только на слиянии или расколе.

С220. Копия дословного текста — плата за неразрешимый путь, а не за важность правила. Путь разрешился — копия становится вторым домом без причины. Остаётся она там, где текст обязан лежать внутри промпта: устав агента, SKILL.md скилла и скелет, уезжающий в проект. Разрез проверяемый: файл, который модель получает целиком, против файла, за которым она идёт отдельным чтением.

С221. Формат служебного файла выбирается по тому, кто его читает. Читает человек в чужом репозитории через полгода — значит комментарии, значит TOML, значит построчная правка вместо перезаписи.