Files
dev-conventions/TODO.md
T
av 682fa075bb снятое правило остаётся заглушкой, нумерация сплошная
- META-31 и META-32: номера идут без пропусков, ссылка обязана разрешаться;
  обе проверки стали механическими — данных со стороны языка им хватает
- заведена метка СНЯТО: заголовок и номер снятого правила сохраняются, норму
  с обоснованием заменяет блок с датой и причиной, отдельный реестр снятых
  номеров не нужен
- META-9, META-16 и META-26 переписаны из таблицы «Освободившиеся номера» в
  заглушки; три висячие ссылки, тянувшиеся с утра, закрылись
2026-07-26 15:59:22 +03:00

158 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# К обсуждению
Черновик для следующего разговора: вопросы и варианты, а не принятые
решения. Закрытый вопрос отсюда удаляется — принятое решение живёт в
`README.md`, `GUIDE.md` или `LANGUAGE.md`, а не в этом файле.
Две секции: сначала язык и подход, потом канон с тулингом. Пункт 1 пришёл
из внешнего ревью описания языка и проверен по файлам на месте.
# Язык и подход
## 1. Натяжки в опоре на стандарты
Три места, где источнику приписано чуть больше, чем в нём есть:
- **DMN и полнота таблицы.** Политика совпадения — действительно именованное
свойство DMN. Полноту стандарт не требует: индикатор полноты был в DMN 1.0
и убран в последующих версиях, её проверяют валидаторы инструментов.
- **29148 и обоснование.** Rationale там — рекомендуемый атрибут требования,
а не обязательный «наравне с самим требованием». Обязательный костяк
стандарта — характеристики well-formed requirement, откуда честно взяты
единичность и проверяемость.
- **EARS.** Вывод «выигрыш дала сама обязательность шаблона, а не его
конкретный вид» — экстраполяция, поданная как взятое из источника. Вывод
от этого не становится неверным, но графа «что взято» описывает не
содержимое EARS.
Остальное в таблице проверку выдержало, включая вторую половину `MAY` из
BCP 14 и списки эквивалентных словесных форм ISO Directives.
## 2. Одиннадцать таблиц не прочитаны на взаимоисключительность
`LANGUAGE.md` объявил, что строки таблицы решений взаимоисключающи по
умолчанию, а иной порядок объявляется явно. Объявление не делает таблицы
такими: нумерованные строки есть в одиннадцати файлах канона, и ни одна
таблица под новое требование не прочитана.
Конкретный подозреваемый — SLOG-11: «по реальному действию или изменению»
против «повторяющаяся служебная, по таймеру или поллингу». Периодическая
операция, которая всё-таки меняет данные, подходит под обе строки, и уровень
из таблицы не выводится однозначно.
Работа читательская, машине не даётся; в список проверок она уже записана в
разделе «Чтением, потому что машине не даётся».
## 3. Описание языка отдельно от набора конвенций
`LANGUAGE.md` и `GUIDE.md` описывают, **как** пишутся конвенции;
`conventions/`**один конкретный** набор. Сейчас они склеены в одном
репозитории, и из одного описания нельзя собрать второй набор (рабочий,
доменный, чужой).
Срочности нет: версия языка объявлена в самом `LANGUAGE.md` (ключ
`version:`), и конвенции ссылаются на неё номером, а не путём, — то есть
самодостаточность копии выноса не требует. Примеры в `LANGUAGE.md` вдобавок
переведены на вымышленные `X`-правила, так что на конкретный набор описание
языка больше не ссылается вовсе.
Что осталось поводом:
- из одного описания по-прежнему нельзя собрать второй набор;
- тулинг валидирует правила, зашитые в его код, а не объявленную версию
языка.
Оба повода включаются, только когда появится второй набор. Цена — ещё одна
сущность и ещё одна синхронизация; при одном наборе лечение выходит хуже
болезни.
# Канон, тулинг, подключение
## 4. Тулинг: две разные задачи в одном `conv`
Сейчас в `conv` смешаны две категории работы, и они расходятся по всему —
по частоте запуска, по тому, кто запускает, и по тому, что считается
провалом.
**Целостность канона.** Префиксы уникальны и не переиспользованы, шапка
совпадает с манифестом, у каждого правила модальность и блок ПОЧЕМУ, ссылки
разрешаются, префикс чужой темы не лезет в норму (META-20), путей канона в
тексте нет (META-21), строка о версии языка на месте. Запускается в каноне,
при каждой правке, провал — это ошибка. Логика уже написана и много раз
прогнана руками, но живёт в скретчпаде, а не в репозитории.
**Установка в проект.** Манифест `.conventions.toml`, сборка файла темы из
слоёв (`arch` → язык → стек), сохранение при пересборке всего, что ниже
маркера, `READING.md` рядом с копиями, предупреждение о висячих ссылках на
неподписанные темы. Запускается
в репозитории-потребителе, изредка, провал — это чаще «посмотри глазами»,
чем «ошибка». Отчёта «канон ушёл вперёд» здесь нет: его делает `git diff`
после пересборки.
Что обсудить:
- Разделять ли на два исполняемых файла, или хватит подкоманд с честной
границей внутри.
- Валидацию канона стоит ли отдать агенту скиллом вместо (или вдобавок к)
скрипту: часть проверок формулируется как «прочитай и скажи, самодостаточна
ли норма» — механически это не берётся, а агентом берётся.
- Куда в этой раскладке ложится запаркованное предупреждение о висячих
ссылках: это установка, а не целостность, но список подписок ему нужен из
манифеста.
Список проверок теперь реализуем целиком: граница правила определена,
нумерация сплошная, снятое правило остаётся заглушкой — данных со стороны
языка проверке хватает.
Перед тем как переписывать, стоит посмотреть на два готовых прототипа:
дистрибуцию пакетов Vale (`.vale.ini``vale sync``styles/`) как образец
манифеста и `vendir.yml` — как пример того, где проходит граница между «чего
хочу» и «что получил».
## 5. Пары слоёв и темы без базы
Отложено сознательно, но список стоит держать перед глазами:
- `SLOG` объявляет `extends: arch/time.md` — расширение **чужой** темы.
Сборщик темы `logging` на это наткнётся: базового слоя с темой `logging`
нет, а `arch/time.md` он тянуть не должен. Чинится переводом в обычную
ссылку «связано». Вдобавок это ломает гарантию META-24: она верна только
для базы своей темы, а `arch/time.md` объявляет тему `time`, не `logging`.
С объявленной темой расхождение стало проверяемым машинно.
- Темы без арх-слоя: `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-слой — единственные ссылки стек → язык в каноне.
## 6. Подключение к репозиториям
Ничего ещё не подключено. Кандидаты — jellybit и pet-project-server.
Понадобится: заполнить локальную часть копий тем, что сейчас в этих
репозиториях записано по факту; обёртка в раннере (`inv conventions` /
`task conventions`, единый интерфейс команд у трёх ansible-репозиториев);
строка в `AGENTS.md` каждого потребителя про то, что файлы в
`docs/conventions/` — копии.
## 7. Тулинг на Go, живущий независимо
Сейчас `conv` — питоновский скрипт внутри канона, то есть тулинг и данные в
одном репозитории и правятся одним движением. Мысль: вынести в отдельный
Go-бинарь со своим релизным циклом, ставить через `eget` (механизм уже есть
в pet-project-server).
Что за этим стоит помимо вкуса: независимый бинарь физически не даёт править
инструмент «заодно» с правкой конвенции, работает против **любого** канона и
любого потребителя — что прямо требуется вопросом 3, — и снимает питон из
зависимостей репозиториев-потребителей.
Порядок обратный ожидаемому: пока вопрос 3 не сделан, инструмент всё равно
работает против одного конкретного канона, и независимый релизный цикл ему
нечего обслуживать. Сначала 3, потом 7. Разделение из вопроса 4 при этом
дешевле заложить сразу, чем отпиливать потом.