diff --git a/LANGUAGE.md b/LANGUAGE.md index d9103ff..1a74dcb 100644 --- a/LANGUAGE.md +++ b/LANGUAGE.md @@ -12,6 +12,12 @@ version: 1 пополниться, и текст, написанный по предыдущей версии, должен читаться по той, по которой написан. +Описание языка ни на один набор конвенций не опирается, поэтому все примеры +здесь — вымышленные правила с префиксами на `X` (`XKEY`, `XMIG`, `XLOG`). +Такие префиксы канон не занимает никогда, реестру они не принадлежат — значит +пример не спутать с настоящим правилом, а перенумерация конвенций описание +языка не задевает. + ## Опора на стандарты Язык не выводится из вкуса автора. Каждое решение о форме взято из @@ -56,7 +62,7 @@ version: 1 Адресуемое правило — не украшение формы, а условие работы трёх механизмов: -- **Механизация.** Запись о ней должна говорить «правило `MIGR-4` проверяет +- **Механизация.** Запись о ней должна говорить «правило `XMIG-4` проверяет `archrules`», а не «`AUTOINCREMENT` в новых миграциях — `archrules`»: во втором случае читатель сам догадывается, к какому утверждению это относится, и догадывается по-разному. @@ -72,7 +78,7 @@ version: 1 ## Единица — правило ```markdown -### KEYS-5. Разбор внешнего идентификатора на границе +### XKEY-5. Разбор внешнего идентификатора на границе **ДОЛЖЕН.** Идентификатор, пришедший снаружи, проходит разбор до запроса к базе. @@ -153,9 +159,9 @@ version: 1 Форма обоснования при этом ничем не ограничена: рамки здесь только смысловые. Абзац может быть длинным, вести рассуждение, приводить пример, -ссылаться на внешние практики, стандарты и чужие проекты — канон это уже -делает («адаптация OpenTelemetry», «как по умолчанию в zap и zerolog», -двенадцатишаговая процедура SQLite). Запрещённых слов и обязательной +ссылаться на стандарты, внешние практики и чужие проекты — на устройство +OpenTelemetry, на умолчания библиотек логирования, на процедуру миграции из +документации СУБД. Запрещённых слов и обязательной структуры у обоснования нет, и заводить их не нужно: обязательность несёт норма, а обоснование её объясняет — путаницу между этими двумя ролями исключает правило о заглавных. @@ -306,7 +312,7 @@ Directives, Part 2, по одной форме записи на ступень, удаляется, а модальность и обоснование остаются: ```markdown -### MIGR-6. Дефолтов времени в схеме БД нет +### XMIG-6. Дефолтов времени в схеме БД нет **ДОЛЖЕН. МЕХАНИЗИРОВАНО.** Проверяется общим правилом линтера; формулировка удалена, потому что дублировала работающую проверку. @@ -331,7 +337,7 @@ Directives, Part 2, по одной форме записи на ступень, Часть правил **классифицирует ситуации**: какой уровень лога, какая категория директории, что делать с невалидным вводом в зависимости от его источника. Каноническая форма для них — таблица «ситуация → вердикт», строки -которой нумеруются как подпункты правила (`SLOG-8.1`). +которой нумеруются как подпункты правила (`XLOG-8.1`). Таблица плотнее прозы и не даёт пропустить ветку: пустая клетка видна, а неупомянутый случай в абзаце — нет. Два свойства такой таблицы взяты из DMN, @@ -379,12 +385,12 @@ Directives, Part 2, по одной форме записи на ступень, ## Идентификаторы -- Формат — `<ПРЕФИКС>-<номер>`: `KEYS-5`, `SLOG-27`. Префикс принадлежит +- Формат — `<ПРЕФИКС>-<номер>`: `XKEY-5`, `XLOG-27`. Префикс принадлежит файлу, нумерация внутри файла сквозная и начинается с единицы. -- Строка таблицы, если на неё нужно ссылаться отдельно, — `KEYS-5.1`, - `KEYS-5.2`. +- Строка таблицы, если на неё нужно ссылаться отдельно, — `XKEY-5.1`, + `XKEY-5.2`. - **Идентификатор глобален.** Префикс уникален по всему канону, поэтому - путь файла в ссылке не нужен: `KEYS-5` адресует правило одинаково изнутри + путь файла в ссылке не нужен: `XKEY-5` адресует правило одинаково изнутри файла, из соседней конвенции и из чужого репозитория. В собранной копии слои разных осей лежат в одном документе, так что ссылка на базовый слой из языкового вообще никуда не ведёт — правило рядом. @@ -428,10 +434,10 @@ Directives, Part 2, по одной форме записи на ступень, ```markdown -MIGR-2, MIGR-4 механизированы — `internal/archrules` (проверяются в новых +XMIG-2, XMIG-4 механизированы — `internal/archrules` (проверяются в новых миграциях). -MIGR-6 не соблюдается в легаси-таблицах `show_history`, `queue`: составные +XMIG-6 не соблюдается в легаси-таблицах `show_history`, `queue`: составные ключи там появились до конвенции, переписывание требует миграции данных. ``` diff --git a/TODO.md b/TODO.md index b498dda..a390ed9 100644 --- a/TODO.md +++ b/TODO.md @@ -4,31 +4,12 @@ решения. Закрытый вопрос отсюда удаляется — принятое решение живёт в `README.md`, `GUIDE.md` или `LANGUAGE.md`, а не в этом файле. -Две секции: сначала язык и подход, потом канон с тулингом. Пункты 1–7 +Две секции: сначала язык и подход, потом канон с тулингом. Пункты 1–6 пришли из внешнего ревью описания языка и проверены по файлам на месте. # Язык и подход -## 1. Примеры в LANGUAGE.md сидят на живых идентификаторах - -Учебные примеры используют настоящие префиксы канона с номерами, которые в -каноне означают другое: - -| В примере `LANGUAGE.md` | В каноне на самом деле | -|---|---| -| `MIGR-4` проверяет `AUTOINCREMENT` в новых миграциях | MIGR-4 — «В деплое схема движется только вперёд»; про AUTOINCREMENT — MIGR-12 | -| «MIGR-6. Дефолтов времени в схеме БД нет» | MIGR-6 — «ER-схема обновляется в том же изменении»; дефолты — MIGR-9 | -| «KEYS-5. Разбор внешнего идентификатора на границе» | KEYS-5 — «Внешний идентификатор разбирается до обращения к базе», с другим текстом нормы | - -Язык держится на том, что идентификатор адресует ровно одно утверждение, и -документ, определяющий язык, это нарушает. Ни одна проверка не поймает — -идентификаторы существуют. Дрейф вдобавок гарантирован: канон -перенумеровывался, примеры не двигались. - -Лечится дёшево: примеры берут префиксы на `X`, зарезервированные как раз под -то, что каноном не занято. - -## 2. «Тема» — несущий идентификатор без определения и реестра +## 1. «Тема» — несущий идентификатор без определения и реестра META-21 велит ссылаться на соседнюю конвенцию именем темы, манифест подписывается `topics = ["time", …]`, сборка собирает файл темы из слоёв — @@ -41,13 +22,13 @@ META-21 велит ссылаться на соседнюю конвенцию файла темы тихо осиротит все текстовые ссылки во всех копиях. Вопрос уже не гипотетический: пара `arch/db-identifiers.md` против -`lang/go/db-schema.md` (см. вопрос 11) показывает, что имена слоёв одной +`lang/go/db-schema.md` (см. вопрос 10) показывает, что имена слоёв одной темы могут не совпадать. Смежно: `extends: arch/time.md` у SLOG ломает гарантию META-24 («базовый слой отсутствовать не может») — она верна только для базы своей темы, а машинной проверке негде узнать тему, кроме имени файла. -## 3. GUIDE выведен из-под проверок ложным основанием +## 2. GUIDE выведен из-под проверок ложным основанием `LANGUAGE.md` исключает обвязку из проверок формулировкой «она ключевые слова цитирует, а не употребляет». Для `GUIDE.md` это неверно: META-правила @@ -63,7 +44,7 @@ META-21 велит ссылаться на соседнюю конвенцию Честнее развести: `GUIDE.md` язык **употребляет** и проверяется как конвенция, `LANGUAGE.md` и `README.md` — цитируют. -## 4. МЕХАНИЗИРОВАНО не переживает нового подписчика +## 3. МЕХАНИЗИРОВАНО не переживает нового подписчика META-8 запрещает удалять норму, пока механизирована не у всех, и защищает тем самым потребителей, существующих **на момент удаления**. Будущих не @@ -81,7 +62,7 @@ META-8 запрещает удалять норму, пока механизир в тексте канона, то есть ровно то, что запрещает META-4. Либо это законное исключение, и тогда его надо назвать, либо конфликт. -## 5. Семантика ключевых слов в копию не едет +## 4. Семантика ключевых слов в копию не едет Строка о версии языка перечисляет слова, но не их значения, а всё нетривиальное в шкале живёт только в `LANGUAGE.md`, который в репозиторий не @@ -97,7 +78,7 @@ META-8 запрещает удалять норму, пока механизир копиями короткую выжимку семантики; расширить строку о версии до двух-трёх предложений; или признать ограничение и записать его явно. -## 6. Две «механические» проверки без источника данных +## 5. Две «механические» проверки без источника данных В списке «разбором текста» стоят два пункта, которые без дополнительного реестра нерешаемы: @@ -113,7 +94,7 @@ META-8 запрещает удалять норму, пока механизир реестр снятых номеров не объявлен частью языка, оба пункта принадлежат списку «чтением». -## 7. Натяжки в опоре на стандарты +## 6. Натяжки в опоре на стандарты Три места, где источнику приписано чуть больше, чем в нём есть: @@ -132,7 +113,7 @@ META-8 запрещает удалять норму, пока механизир Остальное в таблице проверку выдержало, включая вторую половину `MAY` из BCP 14 и списки эквивалентных словесных форм ISO Directives. -## 8. Одиннадцать таблиц не прочитаны на взаимоисключительность +## 7. Одиннадцать таблиц не прочитаны на взаимоисключительность `LANGUAGE.md` объявил, что строки таблицы решений взаимоисключающи по умолчанию, а иной порядок объявляется явно. Объявление не делает таблицы @@ -147,7 +128,7 @@ BCP 14 и списки эквивалентных словесных форм IS Работа читательская, машине не даётся; в список проверок она уже записана в разделе «Чтением, потому что машине не даётся». -## 9. Описание языка отдельно от набора конвенций +## 8. Описание языка отдельно от набора конвенций `LANGUAGE.md` и `GUIDE.md` описывают, **как** пишутся конвенции; `conventions/` — **один конкретный** набор. Сейчас они склеены в одном @@ -156,7 +137,9 @@ BCP 14 и списки эквивалентных словесных форм IS Срочности нет: версия языка объявлена в самом `LANGUAGE.md` (ключ `version:`), и конвенции ссылаются на неё номером, а не путём, — то есть -самодостаточность копии выноса не требует. +самодостаточность копии выноса не требует. Примеры в `LANGUAGE.md` вдобавок +переведены на вымышленные `X`-правила, так что на конкретный набор описание +языка больше не ссылается вовсе. Что осталось поводом: @@ -170,7 +153,7 @@ BCP 14 и списки эквивалентных словесных форм IS # Канон, тулинг, подключение -## 10. Тулинг: две разные задачи в одном `conv` +## 9. Тулинг: две разные задачи в одном `conv` Сейчас в `conv` смешаны две категории работы, и они расходятся по всему — по частоте запуска, по тому, кто запускает, и по тому, что считается @@ -201,7 +184,7 @@ BCP 14 и списки эквивалентных словесных форм IS ссылках: это установка, а не целостность, но список подписок ему нужен из манифеста. -Часть проверок из этого списка сейчас нереализуема по причине из вопроса 6, +Часть проверок из этого списка сейчас нереализуема по причине из вопроса 5, так что порядок такой: сначала язык, потом чекер. Перед тем как переписывать, стоит посмотреть на два готовых прототипа: @@ -209,14 +192,14 @@ BCP 14 и списки эквивалентных словесных форм IS манифеста и `vendir.yml` — как пример того, где проходит граница между «чего хочу» и «что получил». -## 11. Пары слоёв и темы без базы +## 10. Пары слоёв и темы без базы Отложено сознательно, но список стоит держать перед глазами: - `SLOG` объявляет `extends: arch/time.md` — расширение **чужой** темы. Сборщик темы `logging` на это наткнётся: базового слоя с темой `logging` нет, а `arch/time.md` он тянуть не должен. Чинится переводом в обычную - ссылку «связано». Вдобавок это ломает гарантию META-24 — см. вопрос 2. + ссылку «связано». Вдобавок это ломает гарантию META-24 — см. вопрос 1. - Темы без арх-слоя: `db-schema`, `errors`, `web-ui`. Собираются в файл с одной секцией — само по себе не ломается, но это и есть тот невыделенный арх-слой из известного долга. @@ -228,7 +211,7 @@ BCP 14 и списки эквивалентных словесных форм IS - Вынос арх-ядра из `errors` и `logging` закроет две хрупкие ссылки из `web-ui` (стек) в go-слой — единственные ссылки стек → язык в каноне. -## 12. Подключение к репозиториям +## 11. Подключение к репозиториям Ничего ещё не подключено. Кандидаты — jellybit и pet-project-server. Понадобится: заполнить локальную часть копий тем, что сейчас в этих @@ -237,7 +220,7 @@ BCP 14 и списки эквивалентных словесных форм IS строка в `AGENTS.md` каждого потребителя про то, что файлы в `docs/conventions/` — копии. -## 13. Тулинг на Go, живущий независимо +## 12. Тулинг на Go, живущий независимо Сейчас `conv` — питоновский скрипт внутри канона, то есть тулинг и данные в одном репозитории и правятся одним движением. Мысль: вынести в отдельный @@ -246,10 +229,10 @@ Go-бинарь со своим релизным циклом, ставить ч Что за этим стоит помимо вкуса: независимый бинарь физически не даёт править инструмент «заодно» с правкой конвенции, работает против **любого** канона и -любого потребителя — что прямо требуется вопросом 9, — и снимает питон из +любого потребителя — что прямо требуется вопросом 8, — и снимает питон из зависимостей репозиториев-потребителей. -Порядок обратный ожидаемому: пока вопрос 9 не сделан, инструмент всё равно +Порядок обратный ожидаемому: пока вопрос 8 не сделан, инструмент всё равно работает против одного конкретного канона, и независимый релизный цикл ему -нечего обслуживать. Сначала 9, потом 13. Разделение из вопроса 10 при этом +нечего обслуживать. Сначала 8, потом 12. Разделение из вопроса 9 при этом дешевле заложить сразу, чем отпиливать потом.