- DECISIONS.md (4040 строк, 65 тем) → decisions/, файл на тему плюс указатель; - буквенные метки решений заменены сквозными Р1–Р234, следствия получили префикс С при прежних номерах: схема букв выродилась до пятибуквенных и сломалась — `АЕАКЛ` была занята и темой 53, и темой 65; - 42 перекрёстные ссылки переписаны под новые номера и стали живыми; где номер означал тему, а слово стояло «решение», формулировка исправлена.
5.1 KiB
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. Заполненная форма и заполненный смысл — разные вещи, и первая маскирует вторую. Файл на месте, валиден, с правильным именем — и пуст по существу: это худший вид пробела, потому что выглядит он как его отсутствие.