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

5.1 KiB
Raw Blame History

47. OpenSpec заводится скиллом, а его конфиг — часть канона (2026-08-07)

Р186. init заводит OpenSpec сам, а не оставляет это человеку. Каталог openspec/ был предпосылкой, о которой канон говорил, но за которой не следил: openspec/specs/ объявлен домом темы requirements, config.yaml описан абзацем — а заводилось всё руками, и не проверялось ничего. Новый проект выходил из init с полным каноном документов и без каталога, без которого не работают ни opsx:propose, ни ревью дизайна, ни сверка требований. Команда названа поимённо (openspec init --tools claude) в трёх местах — скилле, каноне и отказе скрипта: отказ без команды заставляет искать её в другом месте.

Р187. Файл из коробки хуже отсутствующего, и потому проверяется машиной. openspec init кладёт config.yaml, где context и rules — закомментированный пример на английском. Такой файл читается как настроенный: он есть, он валиден, имя правильное. Работает он как пустой, и узнаётся это по уже написанному предложению — на другом языке, с capability по имени пакета, без единого SHALL. docs.py проверяет четыре вещи, и каждая про молчащий пробел: каталог есть; имя именно config.yaml (config.yml OpenSpec не читает и об этом не сообщает); context и rules.specs не остались примером, а правила называют SHALL; context называет passport и CLAUDE.md.

Р188. Форма конфига — маршрутизатор, и это разрез, а не пожелание. Утверждение, которое можно опровергнуть, открыв другой файл проекта, — пересказ; строка, которая говорит, какой файл открыть, — ссылка. context читается при порождении каждого артефакта, туда удобно дописать «чтобы агент знал», и именно поэтому в нём заводятся вторые дома инвариантов, конвенций, гейта и правил ревью. Машина этот разрез не проверяет — отличить ссылку от пересказа она не умеет, — и он отдан doc-consistency отдельным абзацем правила «один факт — один дом», с config.yaml, добавленным ему во вход.

Обязательными сделаны ровно два адреса — паспорт и CLAUDE.md. Причина в порядке работы: предложение пишется до того, как кто-либо откроет docs/, и без этих двух строк его пишут, не зная ни границы домена, ни инвариантов. Длинный список адресов превратил бы context во второй дом ровно тем способом, против которого правило и заведено.

Образец конфига лёг в канон, а не в конвейер, как планировалось решением Р3. Форма документа принадлежит тому, кто владеет каноном документов; конвейер её читатель. Иначе av-dev-pipeline завёл бы у себя описание файла, который заводит и проверяет av-dev-pm, — тот же шов, что разбирали, убирая имена проходов из канона.

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

С167. Предпосылка, за которой никто не следит, — не предпосылка, а пожелание. Если условие названо обязательным, его должен кто-то заводить и кто-то проверять; иначе оно живёт ровно до первого проекта, где о нём забыли.

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