- языковой и стековый слои называют идентификатор правила арх-слоя своей темы прямо в норме: подписываются темой, а не слоем, поэтому базовый слой в собранной копии присутствует всегда и ссылка не ведёт в пустоту - разрешение узкое по построению — на слои других языков и стеков не распространяется, их состав в копии зависит от манифеста - из META-21 убрано предписание ссылаться на свой слой словами «базовый слой»: слова не проверяются и не ведут к утверждению, а идентификатор ведёт
181 lines
14 KiB
Markdown
181 lines
14 KiB
Markdown
# К обсуждению
|
||
|
||
Черновик для следующего разговора: вопросы и варианты, а не принятые
|
||
решения. Закрытый вопрос отсюда удаляется — принятое решение живёт в
|
||
`README.md`, `GUIDE.md` или `LANGUAGE.md`, а не в этом файле.
|
||
|
||
## 1. Тулинг: две разные задачи в одном `conv`
|
||
|
||
Сейчас в `conv` смешаны две категории работы, и они расходятся по всему —
|
||
по частоте запуска, по тому, кто запускает, и по тому, что считается
|
||
провалом.
|
||
|
||
**Целостность канона.** Префиксы уникальны и не переиспользованы, шапка
|
||
совпадает с реестром, номера без дыр вниз, у каждого правила модальность и
|
||
«Почему», ссылки разрешаются, префикс чужой темы не лезет в норму (META-20),
|
||
путей канона в тексте нет (META-21), строка о версии языка на месте.
|
||
Запускается в каноне, при каждой правке, провал — это ошибка. Логика уже
|
||
написана и много раз прогнана руками, но живёт в скретчпаде, а не в
|
||
репозитории.
|
||
|
||
**Установка в проект.** Манифест `.conventions.toml`, сборка файла темы из
|
||
слоёв (`arch` → язык → стек), сохранение при пересборке всего, что ниже
|
||
маркера, предупреждение о висячих ссылках на неподписанные темы. Запускается
|
||
в репозитории-потребителе, изредка, провал — это чаще «посмотри глазами»,
|
||
чем «ошибка». Отчёта «канон ушёл вперёд» здесь нет: его делает `git diff`
|
||
после пересборки.
|
||
|
||
Что обсудить:
|
||
|
||
- Разделять ли на два исполняемых файла, или хватит подкоманд с честной
|
||
границей внутри.
|
||
- Валидацию канона стоит ли отдать агенту скиллом вместо (или вдобавок к)
|
||
скрипту: часть проверок формулируется как «прочитай и скажи, самодостаточна
|
||
ли норма» — механически это не берётся, а агентом берётся.
|
||
- Куда в этой раскладке ложится запаркованное предупреждение о висячих
|
||
ссылках: это установка, а не целостность, но список подписок ему нужен из
|
||
манифеста.
|
||
|
||
Перед тем как переписывать, стоит посмотреть на два готовых прототипа:
|
||
дистрибуцию пакетов Vale (`.vale.ini` → `vale sync` → `styles/`) как образец
|
||
манифеста и `vendir.yml` — как пример того, где проходит граница между «чего
|
||
хочу» и «что получил».
|
||
|
||
## 2. Пары слоёв и темы без базы
|
||
|
||
Отложено сознательно, но список стоит держать перед глазами:
|
||
|
||
- `SLOG` объявляет `extends: arch/time.md` — расширение **чужой** темы.
|
||
Сборщик темы `logging` на это наткнётся: базового слоя с темой `logging`
|
||
нет, а `arch/time.md` он тянуть не должен. Чинится переводом в обычную
|
||
ссылку «связано».
|
||
- Темы без арх-слоя: `db-schema`, `errors`, `web-ui`. Собираются в файл с
|
||
одной секцией — само по себе не ломается, но это и есть тот невыделенный
|
||
арх-слой из известного долга.
|
||
- Имена тем в паре не совпадают: `arch/db-identifiers.md` против
|
||
`lang/go/db-schema.md`. При сборке по имени темы это две разные темы —
|
||
проверить, что так и задумано.
|
||
- В `lang/go/db-schema.md` сидит целый пласт `stack/sqlite/` (типы колонок),
|
||
тоже из известного долга README.
|
||
- Вынос арх-ядра из `errors` и `logging` закроет две хрупкие ссылки из
|
||
`web-ui` (стек) в go-слой — единственные ссылки стек → язык в каноне.
|
||
|
||
## 3. Подключение к репозиториям
|
||
|
||
Ничего ещё не подключено. Кандидаты — jellybit и pet-project-server.
|
||
Понадобится: заполнить локальную часть копий тем, что сейчас в этих
|
||
репозиториях записано по факту; обёртка в раннере (`inv conventions` /
|
||
`task conventions`, единый интерфейс команд у трёх ansible-репозиториев);
|
||
строка в `AGENTS.md` каждого потребителя про то, что файлы в
|
||
`docs/conventions/` — копии.
|
||
|
||
## 4. Описание языка отдельно от набора конвенций
|
||
|
||
`LANGUAGE.md` и `GUIDE.md` описывают, **как** пишутся конвенции;
|
||
`conventions/` — **один конкретный** набор. Сейчас они склеены в одном
|
||
репозитории, и из одного описания нельзя собрать второй набор (рабочий,
|
||
доменный, чужой).
|
||
|
||
Срочности нет: версия языка объявлена в самом `LANGUAGE.md` (ключ
|
||
`version:`), и конвенции ссылаются на неё номером, а не путём, — то есть
|
||
самодостаточность копии выноса не требует.
|
||
|
||
Что осталось поводом:
|
||
|
||
- из одного описания по-прежнему нельзя собрать второй набор;
|
||
- тулинг валидирует правила, зашитые в его код, а не объявленную версию
|
||
языка.
|
||
|
||
Оба повода включаются, только когда появится второй набор. Цена — ещё одна
|
||
сущность и ещё одна синхронизация; при одном наборе лечение выходит хуже
|
||
болезни.
|
||
|
||
## 5. Тулинг на Go, живущий независимо
|
||
|
||
Сейчас `conv` — питоновский скрипт внутри канона, то есть тулинг и данные в
|
||
одном репозитории и правятся одним движением. Мысль: вынести в отдельный
|
||
Go-бинарь со своим релизным циклом, ставить через `eget` (механизм уже есть
|
||
в pet-project-server).
|
||
|
||
Что за этим стоит помимо вкуса: независимый бинарь физически не даёт править
|
||
инструмент «заодно» с правкой конвенции, работает против **любого** канона и
|
||
любого потребителя — что прямо требуется вопросом 4, — и снимает питон из
|
||
зависимостей репозиториев-потребителей.
|
||
|
||
Порядок обратный ожидаемому: пока вопрос 4 не сделан, инструмент всё равно
|
||
работает против одного конкретного канона, и независимый релизный цикл ему
|
||
нечего обслуживать. Сначала 4, потом 5. Разделение из вопроса 1 при этом
|
||
дешевле заложить сразу, чем отпиливать потом.
|
||
|
||
## 6. `WHEN`/`AND` в блоке стыка правил
|
||
|
||
Блок для стыка двух правил записан английскими словами:
|
||
|
||
```
|
||
WHEN зависимость недоступна и ретраи вызова исчерпаны → ext-запись ERROR
|
||
AND тик фонового цикла упал по той же причине → доменная запись WARN
|
||
```
|
||
|
||
Рядом сказано, что `SHALL` не берётся ни в один словарь, потому что занят
|
||
OpenSpec. `WHEN` и `AND` — из того же набора и по той же причине должны бы
|
||
не браться, но взяты. Это нестыковка, а не решение.
|
||
|
||
Варианты:
|
||
|
||
- **перевести** на `КОГДА` / `И`: словарь набора один, и служебные слова
|
||
внутри канона следуют ему же;
|
||
- **оставить и объяснить**: блок стыка описывает поведение системы во
|
||
времени, а не выбор автора, — то есть это единственное место, где форма
|
||
спецификации уместна, и заимствование её синтаксиса намеренно.
|
||
|
||
Второе честнее по смыслу (субъект там действительно система), но требует
|
||
явной оговорки в `LANGUAGE.md`, иначе читается как недосмотр. Заодно решить,
|
||
подпадают ли `WHEN`/`AND` под проверку «заглавные модальные слова не
|
||
встречаются вне правил»: сейчас формально нет, потому что в словаре их нет.
|
||
|
||
## 7. Критерий «названного вреда» никого не обязывает
|
||
|
||
`LANGUAGE.md` говорит, что ДОЛЖЕН требует двух условий сразу: нарушение
|
||
причиняет названный вред (критерий BCP 14) и норма проверяема машиной
|
||
(META-6). Но правила под первое условие нет: META-6 работает только в одну
|
||
сторону — «нет машинной проверки, понижай в СЛЕДУЕТ». Обратной, «проверка
|
||
есть, а вреда нет — не повышай», не существует, и автор ничем не связан.
|
||
|
||
Решить, заводить ли META-24 под первое условие или оставить его семантикой
|
||
шкалы в описании языка. За правило: механически проверяемых мелочей больше,
|
||
чем важных вещей, и без нормы шкала размывается тем же способом, от которого
|
||
META-6 её защищает. Против: критерий «вред назван» проверяется чтением, а не
|
||
машиной, — то есть по META-6 сам он может быть только СЛЕДУЕТ.
|
||
|
||
## 8. Одиннадцать таблиц не прочитаны на взаимоисключительность
|
||
|
||
`LANGUAGE.md` объявил, что строки таблицы решений взаимоисключающи по
|
||
умолчанию, а иной порядок объявляется явно. Объявление не делает таблицы
|
||
такими: нумерованные строки есть в одиннадцати файлах канона, и ни одна
|
||
таблица под новое требование не прочитана.
|
||
|
||
Конкретный подозреваемый — SLOG-11: «по реальному действию или изменению»
|
||
против «повторяющаяся служебная, по таймеру или поллингу». Периодическая
|
||
операция, которая всё-таки меняет данные, подходит под обе строки, и уровень
|
||
из таблицы не выводится однозначно.
|
||
|
||
Работа читательская, машине не даётся; в список проверок она уже записана в
|
||
разделе «Чтением, потому что машине не даётся».
|
||
|
||
## 9. Возможность, записанная модальным словом
|
||
|
||
Четвёртая категория ISO — возможность и осуществимость — ключевого слова не
|
||
имеет: такие утверждения пишутся обычной прозой. Значит канон надо просмотреть
|
||
на обратную ошибку: где утверждение о факте («библиотеки по умолчанию отдают
|
||
именно его», «SQLite сравнивает строки побайтово») записано модальным словом
|
||
и тем самым превратилось в норму, которую никто не вводил.
|
||
|
||
Смотреть в первую очередь абзацы «Почему»: там факты и стоят, там же соблазн
|
||
усилить их модальностью выше всего.
|
||
|
||
## Мелкое, не закрыто
|
||
|
||
- `conv check` должен уметь отличать ссылку на удалённое правило от
|
||
упоминания дыры: сейчас `META-16` в прозе «Оформления» даёт ложное
|
||
срабатывание.
|