форма config.yaml сверяется с живым openspec, а не с памятью

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

Сторожем поставлено сравнение версий. check спрашивает openspec --version —
десятые доли секунды — и сравнивает major.minor с той, на которой форма
сверялась. Разошлось — замечание, не отказ, с именем команды, которая
перепроверяет. Патч-версия в сравнение не берётся намеренно: формы она не меняет,
а нагоняй на каждый багфикс приучает пролистывать весь блок.

Перепроверяет docs.py openspec-form: берёт openspec templates --json, то есть
перечень артефактов текущей схемы, и печатает, что разошлось с константами.
Дорогой вызов вынесен из check сознательно — он стоит втрое дороже опроса версии,
а ответ меняется только вместе с версией. Дешёвая проверка служит воротами
дорогой, и дорогая не ржавеет, потому что зовут её не по памяти. Чинится
расхождение в плагине, а не в проекте, и команда печатает три адреса правки
списком: константы скрипта, скелет, журнал версий канона.

Пятой проверкой формы стали ключи под rules: — это имена артефактов, и правило,
адресованное несуществующему, не применяется молча. rules.spec вместо
rules.specs даёт конфиг, выглядящий написанным и не работающий.

Первый вариант этой проверки искал ключи отступом по всему файлу и нашёл их
внутри литерального блока context: строки «Language: Russian» и
«av-dev-pm:review-pipeline» выглядят ключами. Оба живых проекта из-за этого
покраснели на правде. Теперь разбор идёт от строки rules: до следующего ключа
нулевой колонки; на тех же проектах чисто, а опечатка в имени артефакта
по-прежнему находится.

Решение — 48.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
av
2026-08-07 12:07:46 +03:00
co-authored by Claude Opus 5
parent a79266cfcb
commit 6ff12fedd5
6 changed files with 259 additions and 9 deletions
+44
View File
@@ -3083,3 +3083,47 @@ JJJ): у профиля обязан быть один правильный от
вторую.** Файл на месте, валиден, с правильным именем — и пуст по существу:
это худший вид пробела, потому что выглядит он как его отсутствие.
## 48. Форма чужого инструмента держится опросом инструмента, а не памятью (2026-08-07)
**АЕАИГ. Схема и артефакты OpenSpec записаны в скрипте как слепок, и у слепка
есть сторож.** Проверка формы `config.yaml` знает имя схемы и перечень артефактов
(`proposal`, `specs`, `design`, `tasks`). Это не наше решение, а состояние чужого
инструмента: OpenSpec переименует артефакт — правила под прежним именем перестанут
применяться, конфиг останется выглядеть написанным, а канон продолжит требовать
прежнее. Все три стороны при этом молчат.
Сторожем сделано сравнение версий: `check` спрашивает `openspec --version`
(десятые доли секунды) и сравнивает `major.minor` с той, на которой форма
сверялась. Разошлось — **замечание**, не отказ, с именем команды, которая
перепроверяет. Патч-версия в сравнение не берётся намеренно: формы она не
меняет, а нагоняй на каждый багфикс приучает пролистывать весь блок.
**АЕАИД. Перепроверка спрашивает инструмент, а не нас.** `docs.py openspec-form`
берёт `openspec templates --json` — перечень артефактов текущей схемы — и
печатает, что разошлось с константами. Дорогой вызов вынесен из `check`
сознательно: он стоит втрое дороже опроса версии, а ответ меняется только вместе
с версией. Дешёвая проверка служит **воротами** дорогой, и дорогая не ржавеет,
потому что зовут её не по памяти.
**Чинится расхождение в плагине, а не в проекте, и это сказано в трёх местах.**
Проект в такой ситуации не виноват и починить ничего не может: у него нет ни
констант скрипта, ни скелета, ни журнала версий канона. Замечание поэтому
адресовано владельцу плагина, а команда печатает три адреса правки списком.
**Заодно поймано ложное срабатывание на живом конфиге.** Первый вариант искал
ключи `rules` отступом по всему файлу и нашёл их внутри литерального блока
`context: |`: строки «Language: Russian» и «av-dev-pm:review-pipeline» выглядят
ключами. Проверка теперь идёт от строки `rules:` до следующего ключа нулевой
колонки. Правило, краснеющее на правде, хуже отсутствующего — его перестают
читать целиком.
### Что из этого следует
169. **Знание о чужом инструменте, записанное у себя, — это слепок с датой.**
Он законен, пока рядом стоит тот, кто заметит, что дата протухла; без
сторожа он превращается в уверенное враньё.
170. **Дешёвая проверка как ворота дорогой.** Опрос версии стоит копейки и
точно говорит, могла ли измениться дорогая величина. Так дорогая проверка
остаётся редкой и при этом не забытой.