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

9.0 KiB
Raw Blame History

54. Стык плагинов: правило получило дом, адреса остались у владельцев (2026-08-09)

Р202. Вопрос пришёл с другой стороны: ревью опирается на документы проекта, но не должно жёстко предполагать, где файл лежит; напрашивалось оглавление адресов и сводка возможностей скиллов в CLAUDE.md проекта. Отклонено и то и другое, но не потому, что проблемы нет.

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

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

Настоящий пробел был в другом, и он измерен. Правило обращения к соседнему плагину стояло в пяти местах в пяти редакциях:

Где стояло Довод Ветка «не разрешился»
task-pipeline устаревшая проектная копия нет
task-batch то же нет
review-pipeline вшито в пункт про удаление проектных копий нет
openspec путём в чужое дерево — никогда есть
canon есть

Два разных довода, и ни в одном месте не было обоих; три места из пяти молчали о том, что делать при неразрешившемся вызове, — то есть о единственном, ради чего правило написано. Плюс невысказанный инвариант: $CLAUDE_PLUGIN_ROOT ведёт только в свой плагин, употреблён двадцать раз и нигде не оговорён — а именно он соблазняет дописать /../av-dev-docs/.

Сделано: дом shared/plugin-boundary.md, блок граница-плагинов, семь помеченных копий — четыре скилла конвейера и три скилла канона. В дом вошли полное имя, запрет пути в чужое дерево, ветка «не разрешился» с обязанностью доклада и признак присутствия по заведённому соседом файлу.

Разрез, по которому дом наполнялся: правило общее, последствие местное. «Нет av-dev-tasks — учёт остаётся владельцу» знает только конвейер; «нет конвейера — docs.py о каталоге openspec/ молчит» знает только канон. Держи дом последствия — он знал бы наперечёт всех своих потребителей и стал бы вторым каноном.

Адреса при этом наружу не поехали. У них владелец есть: раскладку docs/ держит канон, каталог задач — плагин задач. shared/ заводится только для фактов без владельца; чужое с владельцем остаётся дома, а сходимость упоминаний в чужих деревьях проверяет машина — scripts/addresses.py, тем же заходом.

Что выяснилось при написании чекера: судить незнакомое нельзя. Первый прогон дал шесть находок, и три из них были не дрейфом, а свойством канона: docs/** — шаблон, а docs/accessibility.md в двух местах — пример своей темы проекта, которую канон разрешает заводить произвольно. Список тем открытый, значит незнакомое имя опровергнуть нечем, и проверка «есть ли такой документ у владельца» ловила бы законное. Переименование при этом ловится точно и по другому основанию: канон, убирая слот, кладёт его в карту переездов RETIRED — она и есть перечень запрещённого. Рядом одна догадка: имя, почти совпавшее с каноническим, читается как опечатка. Порог замерен по репозиторию — законные имена дают до 0.64, опечатки от 0.91, и между ними пусто.

Четвёртая находка оказалась настоящей: REMAINING.md иллюстрировал смысловой дубль адресом docs/specs/recognition.md — слотом, упразднённым в версии 1 канона, то есть при десяти нынешних. Пример, который сам протух, — ровно то, ради чего чекер и писался.

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

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

С180. shared/ — для фактов без владельца, и только. У адресов владелец есть, и вынести их наружу значило бы отобрать у него его же предмет. Признак верного дома не «нужно нескольким», а «никому из них не принадлежит».

С181. Общее правило и его последствия живут порознь. Правило можно вынести в дом, последствие — нет: оно знает про место, а место про правило знать не обязано. Дом, вобравший последствия, становится реестром потребителей и устаревает быстрее их всех.

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

С183. Замер порога записывается рядом с порогом. Число, выбранное на глаз, через месяц неотличимо от подогнанного под один случай. Обе стороны разрыва названы (0.64 и 0.91) — и видно не только, что порог верен, но и насколько он не на грани.