Каталоги, агенты и общие дома переехали в av-dev/; скиллы названы по прежнему плагину — doc-*, task-*, code-*, с двумя смысловыми именами вместо тавтологии: doc-sync вместо docs, task-track вместо tasks. Манифесты сведены к двум плагинам. Пространства имён вызовов и пути внутри дерева переписаны машинно; проза, которая называет прежние плагины отдельными, идёт следующим шагом.
14 KiB
name, description
| name | description |
|---|---|
| code-openspec | Завести и настроить OpenSpec в проекте — openspec init --tools claude, замена закомментированного примера в openspec/config.yaml на настройку канонической формы (язык, правила именования capability, придирки валидатора, адреса паспорта и CLAUDE.md), проверка формы своим скриптом openspec.py (имя файла, схема, незаменённый пример, адреса документов, ключи rules против артефактов схемы) и сверка слепка с живой версией инструмента. Использовать, когда в проекте нет каталога openspec/, когда config.yaml остался примером из коробки, когда заводят новый проект или переводят чужой и дошли до шага OpenSpec, а также когда конвейер отказался работать без источника требований. Каталог openspec нужен именно конвейеру: без него не работают ни opsx:propose, ни ревью дизайна, ни сверка требований. |
OpenSpec в проекте
Каталог openspec/ — предпосылка конвейера, а не канона документов. Без него
не работают ни opsx:propose, ни ревью дизайна, ни review-specs: у требований
не остаётся дома. Поэтому заводит и настраивает его этот плагин — тот, кто по
OpenSpec и работает.
Канон документов о файле не высказывается вовсе: docs.py его не открывает и об
его отсутствии молчит. Проект без конвейера живёт без OpenSpec законно, и
проверять там нечего. За каноном остаётся одно — единственный дом: не
пересказан ли в context документ, у которого есть свой файл. Это суждение, а не
форма, и смотрит его агент.
Два шага, и второй важнее первого
1. Завести.
openspec init --tools claude
Команда кладёт ещё .claude/skills/openspec-* и .claude/commands/opsx/* — это
её нормальная работа, не трогай их.
2. Заменить пример. openspec init кладёт config.yaml, где context и
rules — закомментированный пример на английском. Файл из коробки хуже
отсутствующего: он есть, он валиден, имя правильное, — и читается как
настроенный, работая как пустой. Узнаётся это по уже написанному предложению: на
другом языке, с capability по имени пакета, без единого SHALL.
Пример заменяется целиком по образцу: references/config-skeleton.md.
Что туда пишут, а что нет
Это маршрутизатор, а не второй дом фактов. Внутрь идёт ровно то, что нужно в момент порождения артефакта и чего в этот момент ещё никто не открыл: язык, правила именования capability, придирки валидатора и адреса документов проекта.
Сюда же — требования к форме proposal и design, на которых стоит чекпоинт
скилла av-dev:code-resolve: объяснение человеку собирается из этих двух
артефактов, и требование к ним обязано применяться в момент, когда их пишут, а не
вспоминаться шагом позже. Образец их содержит.
Пересказ паспорта, инвариантов, конвенций и правил ревью сюда не переносится.
Место для второго дома здесь самое частое: context читается при порождении
каждого артефакта, туда удобно дописать «чтобы агент знал», и так заводятся копии
инвариантов, состава гейта и правил выбора метки. Расходятся они молча, а
замечают это в уже написанном предложении.
Разрез, по которому отличают одно от другого: утверждение, которое можно
опровергнуть, открыв другой файл проекта, — пересказ; строка, которая говорит,
какой файл открыть, — ссылка. Машина этот разрез не проверяет; его смотрит
агент doc-consistency из плагина канона, когда тот подключён.
Два адреса обязательны — docs/passport.md и CLAUDE.md: предложение пишется до
того, как кто-либо откроет docs/, и без них его пишут, не зная ни границы
домена, ни инвариантов. Отсутствие адреса к существующему документу
openspec.py check называет отказом; документа нет в проекте — нет и требования.
Инструмент
os="$CLAUDE_PLUGIN_ROOT/skills/openspec/scripts/openspec.py"
python3 $os check --dir <корень> # форма config.yaml в проекте
python3 $os form # слепок формы против живого OpenSpec
Коды выхода — общий словарь скриптов av-dev: 0 сошлось, 1 дрейф, 2 ошибка употребления, 3 окружение, 4 внутренний сбой. Ветвись на коде, а не на тексте. Различать 1 и 3 обязательно: «форма разошлась» — рабочая ситуация, «openspec не отвечает» — нерабочая.
check проверяет форму, и каждая проверка — про молчащий пробел, а не про вкус:
каталог есть; имя именно config.yaml (config.yml OpenSpec не читает и об этом
не сообщает); ключ schema называет ту схему, для которой форма описана;
context и rules.specs не остались примером, а SHALL назван именно внутри
rules.specs (в context он стоит и в образце, поэтому греп по файлу здесь
ничего не значит); context называет паспорт и CLAUDE.md; ключи под rules: —
имена артефактов схемы, а не свободные слова. Числа проверок здесь нет намеренно:
оно протухает от каждой добавленной.
Адреса требуются только к тем документам, которые в проекте есть. Канон
документов ставится отдельным плагином и может быть не подключён; требовать
ссылку на несуществующий файл значит требовать битую ссылку. Нет
docs/passport.md — проверка по нему идёт строкой «не проверялось», и там же
сказано, что без канона конвейер работает вслепую.
Форма сверяется с живым инструментом
Схема (spec-driven) и перечень артефактов (proposal, specs, design,
tasks) — состояние чужого инструмента, а не наше решение. OpenSpec
переименует артефакт: правила под прежним именем перестанут применяться, конфиг
останется выглядеть написанным, и молчат при этом все три стороны.
Сторож — сравнение версий. check каждым прогоном спрашивает openspec --version (десятые доли секунды) и сравнивает major.minor с той версией, на
которой форма сверялась; разошлось — замечание, не отказ, с именем команды.
Патч-версия в сравнение не берётся намеренно: формы она не меняет, а нагоняй на
каждый багфикс приучает пролистывать весь блок.
Перепроверяет openspec.py form: он спрашивает openspec templates --json, то
есть перечень артефактов текущей схемы, и печатает, что разошлось с константами.
Дорогой вызов вынесен из check сознательно — он стоит втрое дороже опроса
версии, а ответ меняется только вместе с версией. Чинится расхождение в
плагине, а не в проекте: константы скрипта, образец
references/config-skeleton.md и запись в журнал
версий канона.
Кто зовёт этот скилл
av-dev:doc-init— шагом заведения нового проекта, до первого документа;av-dev:doc-canonв режимеadopt— если на переводимом проекте каталога нет илиconfig.yamlостался примером;av-dev:code-resolveиav-dev:code-review— не вызовом по ходу, а отсылкой: OpenSpec у обоих жёсткая предпосылка, и на проекте без каталога оба посылают сюда вместо того, чтобы заводить его руками;- человек — когда конвейер отказался работать без источника требований.
Копия. Дом правила — shared/plugin-boundary.md в репозитории плагинов.
Правится дом, а не этот файл.
Плагины av-dev ставятся порознь, и ни один не вправе считать, что сосед на
месте.
Чужой скилл зовётся полным именем — av-dev:doc-canon, av-dev:task-track,
av-dev:code-review. Короткое имя может разрешиться в устаревшую проектную копию
из .claude/skills/, и подмены не будет видно ни в докладе, ни в поведении.
Путь в дерево чужого плагина не пишется никогда. $CLAUDE_PLUGIN_ROOT ведёт
только в свой плагин; вычисленный от него путь к соседу либо не откроется, либо
откроет чужую установку. Нужен чужой справочник — зови владеющий им скилл, он
прочитает его сам.
Вызов не разрешился — плагина в проекте нет. Это исход, а не поломка: назови строкой доклада, чего теперь не делает никто, и продолжай работу. Молчать нельзя, пропуск неотличим от сделанного; выдумывать обходной путь нельзя тоже.
Присутствие узнаётся вызовом или следом в проекте, но не объявлением. Перечня
установленных плагинов проект не ведёт — он разошёлся бы с действительностью
молча. Что сосед здесь работал, видно по заведённому им файлу: docs/.docs.json —
канон, <каталог задач>/.tasks.json — задачи, openspec/config.yaml — конвейер.
Имя файла — имя плагина, который его завёл, и держит он в том числе версию своего
формата: у канона документов и у каталога задач они свои и двигаются порознь.
Здесь это значит: вызов не разрешился — плагина конвейера в проекте нет, и тогда OpenSpec заводит человек командой выше.
Чего этот скилл не делает
- Не пишет спеки и предложения. Это
opsx:proposeи конвейер задачи. - Не ведёт документы канона — их дом плагин
av-dev-docs, и адреса вcontextтолько на них ссылаются. - Не чинит расхождение формы с версией OpenSpec в проекте. Оно чинится в плагине: константы скрипта, образец здесь, запись в журнал версий канона.
- Не судит, ссылается
contextна документы или пересказывает их. Машине этот разрез не виден; его смотрит агентdoc-consistencyиз плагина канона. Плагина нет — эту проверку не делает никто, и так и скажи.