Files
dev-skills/av-dev-pm/skills/docs/SKILL.md
T
avandClaude Opus 5 354a6b03d5 канон 4: слаг подкреплён проверкой, обещанный судья заведён
Оба пункта заметок оказались одним классом: правило записано и никем не
исполняется.

Слаги. canon.md говорил «слаги файлов, capability и задач — английские,
kebab-case» одной строкой в хвосте раскладки, а docs.py имён файлов не
смотрел вовсе. Итог нашёлся в самом плагине: единственный пример ADR в
скилле docs назывался ADR-2026-08-03-ochered-tablicej. Раскладка канона
при этом приглашала к нарушению — в схеме стояли плейсхолдеры <тема>.md,
то есть слово «тема» по-русски там, где надо писать <slug>.

docs.py check теперь смотрит имена: кириллица и не-kebab-case жёстко,
форма ADR-ГГГГ-ММ-ДД-slug.md жёстко, транслит эвристикой, то есть
замечанием. Проверяются docs/conventions, docs/research, docs/adr и имена
capability; каталог задач не трогается — его слаги ведёт tasks.py.

Набор маркеров транслита подобран так, чтобы ложных срабатываний не было
вовсе: выброшены ost (ловит post, cost), sch (schema), ya (yaml), nost
(nostalgia), хвост ii (radii). Цена названа в комментарии —
sostoyanie-partii проходит мимо. Правило, краснеющее на правде, приучает
пролистывать весь блок, и это дороже пропуска.

Агенты. В canon.md есть таблица «Что проверяет машина, а что человек», и
её правая колонка — смысловой дубль, поведение в architecture.md,
протухший факт, достаточность честной строки — три версии описывала
работу, которую никто не делал: скилл canon предлагал агенту судить об
этом самому, то есть проверять то, что он же и писал.

Заведены двое, разрез по глубине — тот же довод, что развёл task-form и
doc-wording. doc-consistency читает docs/ и openspec/, сверяет документы
между собой (факт в двух домах, прямое противоречие, поведение в обзоре
вместо спек, ADR без ссылки на design.md и без парного статуса, число без
провенанса, заглушка вместо честной строки) и зовётся на шаге синка
документации. doc-code-drift читает репозиторий, отвечает на «этот факт
ещё верен» и зовётся раз в спринт на сессии.

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

Карта домов уехала в устав doc-consistency помеченной копией: устав
ссылался на файл плагина, а агент работает в репозитории проекта, где
плагина может не быть. copies.py её сторожит.

Попутно: докстрока copies.py показывала закрывающие маркеры как
<!-- /дом -->, а код требует <!-- /дом: <id> -->. Нашлось первой же
попыткой ими воспользоваться.

DECISIONS тема 28 (ННОО–ХХЦЦ, следствия 105–108).

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

12 KiB
Raw Blame History

name, description
name description
docs Вести содержимое документов канона по ходу разработки — синк после сделанной задачи с построчным отчётом по каждому документу, заведение ADR промоутом из архивного design.md, запись наблюдения в research, запись дефекта и настройки конвейера в review.md, чистка architecture.md от поведения с маркерами долга. Использовать, когда задача сделана и надо обновить документацию, когда просят завести ADR или записать решение, занести находку о внешних данных, записать проскочивший дефект, разгрузить разросшуюся архитектуру. Раскладку и соответствие канону проверяет скилл canon.

Ведение содержимого канона

Скилл владеет содержимым документов канона; раскладкой владеет canon. Определение канона и роли документов — канон, здесь не пересказывается.

Главный вызывающий — шаг синка документации в пайплайне задачи. Пайплайн живёт в другом плагине и зовёт этот скилл по имени; проект без пайплайна ведёт документацию тем же скиллом вручную.

Правило, из которого всё следует

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

Причина, по которой правило именно такое, измерена: у ADR был список триггеров прозой — и он дал 6 записей на 43 изменения. Прозаический триггер, который некому проверить, не срабатывает. Умолчание «не написал» становится отличимым от «написал, что не требуется», только когда отрицание обязательно.

Это тот же приём, что «границы покрытия» в отчёте ревью и «пустое называется пустым» в каноне.

Чек-лист синка

Идёт сверху вниз; каждая строка попадает в доклад.

Документ Обновляется, когда Проверка
openspec/specs/ всегда при изменении поведения вливает opsx:archive
database.md тронуты миграции docs.py check --base
architecture.md новый компонент, граница, внешняя зависимость, изменилось окружение docs.py: capability без упоминания
adr/ дорогой откат, намеренный отказ, пересмотр прежнего нет — только этот чек-лист
research/ узнали новое о внешнем формате или данных нет
security.md новый недоверенный вход, токен, путь наружу, сдвиг периметра нет
conventions/ находка принята и не специфична для одного места промоут
review.md дефект воспроизведён; сузили или расширили проверку нет
passport.md новый потребитель, сдвиг границы «чем не является» нет
CLAUDE.md изменился инвариант, гейт, запрет, необратимое нет

Пример доклада:

Синк документации:
- architecture.md — добавлен воркер свёртки, ссылка на capability reindex
- database.md — миграция 00006, таблица bucket
- adr/ — заведён ADR-2026-08-03-queue-as-table: отказ от внешней очереди
- research/ — новое о формате не узнано
- passport, security, conventions, review — не требуется: изменение внутреннее
- сверка doc-consistency: находок нет, просмотрено 4 документа из 10

Сверка после синка

Синк правит документы поодиночке, а расходятся они между собой: факт, дописанный в architecture.md, уже живёт в CLAUDE.md; периметр в security.md не знает про новый эндпоинт. Поймать это на своей же правке нельзя — поэтому последним шагом синка зовётся агент doc-consistency на те документы, которых синк касался.

Он читает docs/ и openspec/, кода не читает, ничего не правит и возвращает готовые формулировки. Строка его доклада входит в доклад синка — включая пустую: «находок нет, просмотрено N из M» это ответ, а молчание читается как «не звали».

Сверку с кодом синк не зовёт. «Протухший факт, разошедшийся с кодом» смотрит doc-code-drift, он дорог (читает репозиторий) и зовётся раз в спринт на сессии — не на каждой сделанной задаче.

ADR — промоут, а не второе сочинение

Обоснование уже написано: opsx:propose кладёт design.md в каждый change, и после архивации он лежит в openspec/changes/archive/<id>/design.md с разделами Context / Goals / Non-Goals / Decisions / Risks / Trade-offs.

ADR цитирует решение оттуда и ссылается на источник. Не пересказывает и не сочиняет заново.

Триггер заведения, форма имени и правило замены — в каноне, раздел adr/. Здесь они не повторяются: копия правила расходится с оригиналом на первой же смене версии канона, а расходится незаметно.

Твоя часть — применить триггер к этой задаче и сказать вслух, сработал он или нет. Строка «adr/ — не требуется: решение рутинное» и есть то, ради чего чек-лист существует; её отсутствие неотличимо от «забыл посмотреть».

Порядок работы: открой архивный design.md change, найди в Decisions то, что проходит триггер, процитируй решение и его причину, сошлись на источник, добавь строку в индекс docs/adr/README.md сверху.

Чистка architecture.md

Обзор не держит поведение — его нормативный дом openspec/specs/. Форма маркера долга и правило «гейт от них не краснеет» — в каноне, раздел architecture.md.

Разбирается порциями: раздел вычищается той задачей, которая его касается. Содержимое не выбрасывается, а переезжает — требования в дельта-спеку change, обоснование в ADR, обзор остаётся строкой со ссылкой на capability.

Запись в research/

Наблюдение о внешнем мире: что реально шлёт источник, чем документация формата расходится с практикой. Требование провенанса и правило про расходящееся число — в каноне, раздел research/.

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

Запись в review.md

Файл держит два раздела с разными сроками жизни — журнал дефектов и настройку конвейера. Что в каком и в какой форме — в каноне, раздел review.md; подробности формы записи и выбор адреса, куда она ведёт, — у конвейера ревью проекта (при av-dev-pipelineSkill av-dev-pipeline:review-pipeline, его references/review-journal.md). Конвейера в проекте нет — пиши по форме из скелета review.md, которую положил канон, и скажи в докладе, что подробностей формы взять негде.

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

Промоут в конвенции

Находка → конвенция → правило линтера → удаление из прозы. Процедура целиком принадлежит конвейеру ревью проекта (при av-dev-pipeline — его references/promote.md, читается через Skill av-dev-pipeline:review-pipeline); роль каталога конвенций — в каноне. Конвейера нет — три шага всё равно твои, просто без его процедуры: сформулируй правило, поищи, чем оно механизируется, и вычеркни прозу, если механизировалось.

Твоя часть — третий шаг, который пропускают чаще всего: правило заработало, а формулировка осталась в прозе, и проход продолжает проверять уже проверенное. На синке это отдельная строка: «conventions/ — правило X механизировано, формулировка удалена» либо «не требуется».

Чего этот скилл не делает

  • Не проверяет раскладку — это canon.
  • Не заводит недостающие документы — их скелет кладёт canon adopt или init.
  • Не сочиняет содержание. Нечего записать — так и пишется, честной строкой.
  • Не переоформляет документы «заодно»: правится то, чего коснулась работа.