скрипты: запись настроек перестала уходить мимо и молчать
Найдено ревью, каждое воспроизведено на фикстуре. Граница репозитория. find_root обходил всех предков в поисках .av-dev.toml и только потом смотрел на .git: вложенный проект объявлялся здоровым по конфигу соседа, а init дописывал секцию в чужой репозиторий. Подъём останавливается на первом .git. Туда же ключ [tasks] dir: он не судился как путь, и «../соседний» уводил запись за пределы репозитория с зелёным кодом. Запись TOML. Значения склеивались в кавычки без экранирования — имя индекса с кавычкой ломало файл целиком, и оба скрипта после этого отвечали кодом 3 на любую команду. Заголовок секции искался точным сравнением строки, так что «[tasks] # комментарий» — ровно та возможность, ради которой взят формат, — не находился, и дописывалась вторая таблица. set_version правил version внутри секции и ломал файл, если версия в кавычках. Молчание вместо отказа. Неизвестные ключи не отвергались: migrations, положенный верхним уровнем (а именно так его перенесут руками из .docs.json), давал «проверка неприменима» и зелёный итог. Неверный dir проваливался в поиск вверх, и скрипт работал в другом каталоге, не сказав о ключе. Прежние файлы узнавались только когда нового нет — половина переезда проходила молча. Честность доклада. Версию не двигал никто: set_version был написан и не подключён, init печатал версию, которой не записал, adopt писал dir мимо --target. Теперь повышение — команда docs.py bump, а init и adopt зовут общий write_config, который пишет версию, дописывает ключи и вслух называет разошедшиеся. Отсутствие shared/config.py давало трейсбек и код 1 вместо 3. Число зовётся LAYOUT_VERSION в обоих скриптах вместо CANON_VERSION и FORMAT_VERSION.
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
Каталог `openspec/` — предпосылка **конвейера**, а не канона документов: без него
|
||||
не работают ни `opsx:propose`, ни ревью дизайна, ни сверка требований. Поэтому и
|
||||
проверка формы живёт здесь, рядом со скиллом, который каталог заводит. Раньше она
|
||||
жила в `docs.py` плагина канона, и у файла было два владельца: один заводит,
|
||||
жила в `docs.py`, у скилла канона, и у файла было два владельца: один заводит,
|
||||
другой проверяет.
|
||||
|
||||
Проверяется то, что **молчит при поломке**. Файл из коробки хуже отсутствующего:
|
||||
@@ -219,8 +219,8 @@ def check_form(root: Path, rep: Report) -> None:
|
||||
if not (root / where).exists():
|
||||
rep.skip(
|
||||
f"{where} в проекте нет — ссылка на него в context не "
|
||||
f"требуется. Документы канона ведёт отдельный плагин "
|
||||
f"(av-dev-docs), и без него конвейер работает вслепую"
|
||||
f"требуется. Документы канона проект не завёл, и без них "
|
||||
f"конвейер работает вслепую: заводит их av-dev:doc-canon"
|
||||
)
|
||||
continue
|
||||
if pointer not in live:
|
||||
@@ -289,8 +289,8 @@ def report(rep: Report) -> int:
|
||||
"документов проекта и ключи rules против артефактов схемы. Чего она не\n"
|
||||
"видит — **пересказ вместо ссылки**: утверждение, которое можно\n"
|
||||
"опровергнуть, открыв другой файл проекта, от строки «открой такой-то\n"
|
||||
"файл» она не отличает. Это суждение агента `doc-consistency` из плагина\n"
|
||||
"канона документов; нет плагина — нет и этой проверки, и так и скажи."
|
||||
"файл» она не отличает. Это суждение агента `doc-consistency`; документов\n"
|
||||
"канона в проекте нет — сверять пересказ не с чем, и так и скажи."
|
||||
)
|
||||
if rep.errors:
|
||||
print(f"\nИтог: дрейф, {len(rep.errors)} пунктов.")
|
||||
|
||||
Reference in New Issue
Block a user