слияние: три плагина стали одним av-dev, скиллы получили префиксы
Каталоги, агенты и общие дома переехали в av-dev/; скиллы названы по прежнему плагину — doc-*, task-*, code-*, с двумя смысловыми именами вместо тавтологии: doc-sync вместо docs, task-track вместо tasks. Манифесты сведены к двум плагинам. Пространства имён вызовов и пути внутри дерева переписаны машинно; проза, которая называет прежние плагины отдельными, идёт следующим шагом.
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
---
|
||||
name: code-openspec
|
||||
description: "Завести и настроить 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](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](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/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` из плагина канона.
|
||||
Плагина нет — эту проверку не делает никто, и так и скажи.
|
||||
Reference in New Issue
Block a user