- META-37: тема называется решением и адресатом, а не ролью части проекта; логи сервера и браузера — logging и client-logging, а не суффиксная пара - META-38: ось слоя объявляется ключами lang/stack в шапке, а не выводится из пути — переезд файла между директориями иначе молча менял состав копии у каждого потребителя; шапки двенадцати конвенций приведены к правилу - в список проверок добавлены объявление оси, единственность базового слоя и совпадение объявленного с директорией
53 KiB
version
| version |
|---|
| 1 |
Язык конвенций
Формальный язык, на котором записаны правила этого канона: что считается правилом, чем оно отличается от прозы вокруг, какими словами задаётся обязательность и как на правило сослаться извне.
Версия языка — 1. Номер называется в каждой конвенции: словарь может пополниться, и текст, написанный по предыдущей версии, должен читаться по той, по которой написан.
Документ адресован автору набора и в репозиторий-потребитель не едет. К
читателю копии едет короткое READING.md: словарь со значениями, форма
правила и её граница, ссылки, локальная часть — без разделов о ведении набора.
Словарь в двух документах обязан совпадать (META-30), и это единственное
место, где между ними возможен дрейф.
Описание языка ни на один набор конвенций не опирается, поэтому все примеры
здесь — вымышленные правила с префиксами на X (XKEY, XMIG, XLOG).
Такие префиксы канон не занимает никогда, в манифесте набора их нет — значит
пример не спутать с настоящим правилом, а перенумерация конвенций описание
языка не задевает.
Опора на стандарты
Язык не выводится из вкуса автора. Каждое решение о форме взято из документа, где эта задача уже решена и обкатана, и отклонения от источника названы явно.
| Источник | Что взято | Что отклонено |
|---|---|---|
| BCP 14 (RFC 2119 + RFC 8174) | шкала модальности; правило «нормативно только заглавное»; сдержанность в высшей модальности; англоязычный словарь как готовый | синонимы REQUIRED, RECOMMENDED, OPTIONAL; SHALL как форма требования |
| ISO/IEC Directives, Part 2 | разделение «требование — рекомендация — разрешение — возможность»; запрет модальных глаголов в утверждениях о факте | списки равнозначных словесных форм («is to», «is required to», «only … is permitted») |
| ISO/IEC/IEEE 29148 | характеристики хорошего требования — единичность и проверяемость; обоснование и метод верификации как отдельные атрибуты требования | остальной аппарат требований: приоритеты, источники, матрицы трассируемости |
| DMN | таблица решений с объявленной политикой совпадения | исполняемая семантика и всё, что предполагает движок решений |
| EARS | паттерн «нежелательное поведение» — в виде таблицы | шаблоны как форма записи правила: WHEN, WHILE, WHERE |
| OpenSpec | четырёхчастная форма правила; адресуемость правила идентификатором; форма «условие → следствие» для стыка правил | SHALL; GIVEN/WHEN/THEN как общая форма записи |
Три отклонения стоят объяснения, потому что выглядят как произвол.
Синонимов нет. BCP 14 держит REQUIRED рядом с MUST и OPTIONAL
рядом с MAY ради читаемости английской прозы. Одна форма записи на ступень
означает, что проверка «модальное слово употреблено вне правила» становится
перечислением, а не разбором синонимических рядов.
SHALL не используется ни в каком словаре этого языка. Слово занято
спецификациями (OpenSpec), и общая с ними форма стирала бы границу между
конвенцией и описанием поведения системы: SHALL в конвенции читался бы как
контракт, которого конвенция не даёт. Для англоязычного словаря это означает
выбор в пользу MUST из BCP 14, а не shall из ISO/IEC Directives.
GIVEN/WHEN/THEN не берётся как общая форма. У спецификации субъект —
система, и её поведение разворачивается во времени: состояние, событие,
исход. У конвенции субъект — автор кода, и разворачивать нечего: есть
ситуация выбора и вердикт. Это таблица, а не траектория. Тем же рассуждением
отклонены шаблоны EARS как форма записи правила, а взято из EARS другое —
сообщённое снижение числа дефектов после введения шаблонов. Вывод, что дело в
самой обязательности формы, а не в её конкретном виде, наш; он ниже, среди
усилений.
Исключение — стык правил, где субъект действительно система: там форма «условие → следствие» берётся сознательно, вместе со служебными словами под неё. Это единственное место, и оно описано в «Таблицах решений».
Где источник усилен
Три решения идут дальше источника, и это наши решения, а не его требования. Названы они отдельно, чтобы довод не подменялся ссылкой: спорить с ними нужно по существу, а не со стандартом.
- Обоснование обязательно. В 29148 rationale — из списка рекомендуемых атрибутов требования; обязательный костяк там другой, это характеристики самого требования. Здесь правило без блока ПОЧЕМУ не принимается, потому что конвенция живёт годами и переживает автора: норма без причины через год либо отменяется первым возражением, либо соблюдается там, где вредит.
- Полнота таблицы решений. DMN даёт политику совпадения как именованный атрибут, а полноты не требует: индикатор полноты был в первой версии спецификации и из последующих убран, полноту проверяют валидаторы инструментов. Здесь она требуется, потому что таблицу и заводят ради видимости пропуска: неперечисленный случай в прозе не виден, а пустая клетка видна.
- Вывод про обязательность шаблона. В EARS сообщается о снижении числа дефектов в требованиях после введения шаблонов. Вывод, что выигрыш даёт сама обязательность формы, а не её конкретный вид, — наш: он объясняет, почему мы берём из EARS результат, но не берём сами шаблоны.
Что даёт формализация
Адресуемое правило — не украшение формы, а условие работы трёх механизмов:
- Механизация. Запись о ней должна говорить «правило
XMIG-4проверяетarchrules», а не «AUTOINCREMENTв новых миграциях —archrules»: во втором случае читатель сам догадывается, к какому утверждению это относится, и догадывается по-разному. - Отступления. «У нас не так» бесполезно, пока не сказано, что именно «не так». Со ссылкой на правило отступления становятся счётными: видно, сколько правил конвенции репозиторий реально не соблюдает.
- Промоут находки. Путь «находка → конвенция → правило линтера» требует ручки, за которую берут конкретное правило.
Общий знаменатель — идентификатор. Модальные слова и таблицы полезны, но вторичны.
Единица — правило
### XKEY-5. Разбор внешнего идентификатора на границе
**ДОЛЖЕН.** Идентификатор, пришедший снаружи, проходит разбор до запроса
к базе.
**ПОЧЕМУ.** Разбор валидирует формат и нормализует регистр. Сравнение строк
в базе побайтовое, поэтому без нормализации запрос молча не находит
существующую запись — отладка такого случая стоит дороже, чем сам разбор.
Четыре обязательные части: идентификатор, заголовок, модальность с нормой, обоснование под меткой ПОЧЕМУ. Пятый блок, ПРИМЕРЫ, необязателен — о нём ниже. Норма — одна фраза; если в неё не влезает, это два правила. Требование единичности взято из ISO/IEC/IEEE 29148: составная норма не проверяема целиком, и нарушение одной её половины нечем адресовать.
Метки правила — модальное слово, ПОЧЕМУ, ПРИМЕРЫ — пишутся заглавными и принадлежат словарю набора: скелет правила читается одинаково в любом языке, на который канон переведён.
Правило кончается перед следующим заголовком. Область правила — от его заголовка до следующего заголовка любого уровня. Внутри области текст принадлежит последнему открытому блоку: метка блок открывает, и блок длится до следующей метки или до конца области.
### XKEY-3. Заголовок правила
**ДОЛЖЕН.** Норма одной фразой.
| № | ситуация | вердикт | ← блок нормы: таблица уточняет её
**ПОЧЕМУ.** Причина.
Продолжение причины, пример, ← блок обоснования продолжается
ссылка на внешнюю практику.
### XKEY-4. Следующее правило ← здесь область кончилась
Отсюда три следствия:
- Хвост после ПОЧЕМУ — обоснование до следующей метки или до конца области, а не безымянная часть правила и не проза вокруг. Требований в нём не живёт: то, что подлежит исполнению, стоит в блоке нормы, где у него есть модальность и адрес. Требование, оставленное в хвосте, требованием не является — сослаться на него нельзя и отступление от него записать нельзя.
- Таблица и список после модальной метки — часть нормы. Правило, классифицирующее ситуации, ровно так и записывается («Таблицы решений»), а вердикт из такой таблицы адресуется номером строки.
- Проза — это то, что лежит вне областей правил. Тем самым проверка «заглавных модальных слов вне правил нет» становится реализуемой: границу считает разметка, а не читательское суждение о том, где правило кончилось.
Заглавное модальное слово внутри области правила законно, когда это упоминание ступени в обосновании («для СЛЕДУЕТ это честно»). Метку от упоминания отличает положение: метка стоит первой в своём абзаце, полужирным и с точкой.
Примеры к правилу
Пятый блок правила — необязательный, под меткой ПРИМЕРЫ. В нём код, показывающий норму в деле, обычно парой «плохо → хорошо». Стоит он после обоснования: сначала требование, потом причина, потом иллюстрация.
### XKEY-5. Внешний идентификатор разбирается до обращения к базе
**ДОЛЖЕН.** Значение, пришедшее снаружи, проходит разбор и нормализацию
раньше, чем по нему делается запрос.
**ПОЧЕМУ.** Синтаксически невалидное значение не может соответствовать
записи, поэтому поход в базу за ним — заведомо холостой.
**ПРИМЕРЫ.**
Плохо — строка уходит в запрос как пришла:
```go
row := db.QueryRow("select … where id = ?", r.PathValue("id"))
```
Хорошо — разбор на границе, запроса при неудаче нет:
```go
id, err := ident.Parse(r.PathValue("id"))
if err != nil {
return notFound(w)
}
row := db.QueryRow("select … where id = ?", id)
```
Пример иллюстрирует норму, а не задаёт её. Три следствия, ради которых это сказано:
- требований в блоке нет. Всё, что подлежит исполнению, стоит в блоке нормы; деталь примера — имя переменной, конкретная функция, форма ответа — требованием не становится. Разошёлся пример с нормой — действует норма, а пример правят;
- это не готовый сниппет. Код в примере сокращён до того, что показывает правило: обработка ошибок, контекст, импорты в нём условны, и копировать его дословно не нужно;
- пример стареет быстрее нормы. Он привязан к сегодняшнему API, поэтому расхождение примера с текущим кодом — повод поправить пример, а не отменять правило.
Блок необязателен: он окупается там, где норму словами описать дороже, чем показать, — форма вызова, структура записи в логе, раскладка файла. У правила про выбор границы или про уровень лога иллюстрировать нечего.
Обоснование обязательно
Правило без блока ПОЧЕМУ не принимается. Это требование к форме, а не пожелание. В 29148 обоснование — отдельный атрибут требования, но из рекомендуемых; здесь оно обязательно, и вот почему:
- Обоснование — единственный способ увидеть, что правило устарело. Норма стареет молча; причина стареет заметно. Когда причина отпала, видно, что правило пора убрать, а не соблюдать по инерции.
- Правило без обоснования не переживает спор. Через год ни автор, ни агент не восстановят мотив, и правило будет либо отменено первым же возражением, либо соблюдено там, где вредит.
- Формулировка обоснования — проверка на то, что это вообще правило. Если причина не формулируется, перед нами привычка или вкусовщина; ей место в черновиках, а не в конвенции.
Обоснование отвечает на «что сломается, если сделать иначе», а не пересказывает норму другими словами. «Потому что так принято» — не обоснование.
Форма обоснования при этом ничем не ограничена: рамки здесь только смысловые. Абзац может быть длинным, вести рассуждение, приводить пример, ссылаться на стандарты, внешние практики и чужие проекты — на устройство OpenTelemetry, на умолчания библиотек логирования, на процедуру миграции из документации СУБД. Запрещённых слов и обязательной структуры у обоснования нет, и заводить их не нужно: обязательность несёт норма, а обоснование её объясняет — путаницу между этими двумя ролями исключает правило о заглавных.
Модальные слова
Инвариант языка — шкала: пять ступеней в четырёх категориях ISO/IEC Directives, Part 2, по одной форме записи на ступень, заглавными. Какими словами ступени названы — параметр естественного языка набора, а не часть языка конвенций. Этот канон написан по-русски и несёт русский словарь.
Пишутся заглавными — это ключевые слова, а не обычный текст.
| Слово | Категория | Значение | Отступление |
|---|---|---|---|
| ДОЛЖЕН | требование | нарушение считается ошибкой | только с записью в отступления |
| НЕ ДОЛЖЕН | требование | запрет | то же |
| СЛЕДУЕТ | рекомендация | сильная рекомендация; новый код пишем так | допустимо, причину записываем |
| НЕ СЛЕДУЕТ | рекомендация | обратное к СЛЕДУЕТ | то же |
| ДОПУСКАЕТСЯ | разрешение | выбор за автором кода; возражение на ревью не принимается | не требуется — правило ничего не запрещает |
Нормативно только заглавное написание. Это правило RFC 8174, и оно здесь по той же причине, по которой понадобилось там: без него каждое строчное «должен» во вводной прозе становится предметом спора о том, норма это или речь. Строчное слово нормой не является никогда, поэтому проза свободна, а проверка «модальное слово вне правила» сводится к поиску заглавных форм.
Четвёртая категория ISO — возможность — ключевого слова не имеет. Утверждения о том, что бывает и что технически осуществимо, пишутся обычной прозой и модальных слов не несут. Модальное слово в таком утверждении превращает описание в норму, которую никто не собирался вводить.
ДОПУСКАЕТСЯ адресовано рецензенту. В BCP 14 у MAY есть вторая
половина, которую обычно не замечают: сторона, не выбравшая опцию, обязана
работать с той, что выбрала. В конвенции этому соответствует запрет
возражать: выбор, помеченный ДОПУСКАЕТСЯ, на ревью не обсуждается. Без этой
половины слово было бы удобством читателя, а не нормой, и не работало бы в
единственной точке, где у конвенции есть принуждение.
ДОЛЖЕН требует двух условий сразу:
- нарушение причиняет названный вред, а не расходится со вкусом — META-25, он же критерий BCP 14, где высшая модальность резервируется под то, что действительно ломается, и не употребляется для навязывания метода;
- вердикт о нарушении воспроизводим — META-6: по тексту правила двое проверяющих приходят к одному ответу, иначе обязательность держится на том, кто читал.
Не выполнено первое — правилу место в СЛЕДУЕТ или нигде. Не выполнено второе — в СЛЕДУЕТ. Воспроизводимость сама по себе не повышает правило до ДОЛЖЕН: проверяемых мелочей больше, чем важных вещей, и безразборное повышение обесценивает шкалу быстрее, чем её отсутствие.
Модальность живёт на правиле, а не на файле. Файловый статус
(status: рекомендуемая / обязательная в шапке) не используется: он
неизбежно врёт, потому что один файл смешивает жёсткие требования с
советами. В шапке остаются только topic, prefix и extends.
Словарь другого языка
Словарь набора — три перечня, и требования к ним одни и те же.
Шкала обязательности. Для английского готовый словарь даёт BCP 14; для любого другого языка слова берут из перевода стандарта, если он есть, или переводят сами. Шкала и семантика ступеней при этом не меняются — меняется только запись.
| Ступень | Русский | Английский (BCP 14) |
|---|---|---|
| требование | ДОЛЖЕН | MUST |
| запрет | НЕ ДОЛЖЕН | MUST NOT |
| рекомендация | СЛЕДУЕТ | SHOULD |
| рекомендация против | НЕ СЛЕДУЕТ | SHOULD NOT |
| разрешение | ДОПУСКАЕТСЯ | MAY |
Метки. Обязательности не задают, а размечают: ПОЧЕМУ — обоснование, ПРИМЕРЫ — иллюстрации к норме, МЕХАНИЗИРОВАНО — запись о проверке в копии, СНЯТО — заглушку на месте убранного правила. Стандартом не даются ни в одном языке: в BCP 14 таких понятий нет, слова подбираются под язык так же, как остальные.
| Метка | Русский | Английский |
|---|---|---|
| обоснование | ПОЧЕМУ | WHY |
| иллюстрации | ПРИМЕРЫ | EXAMPLES |
| способ проверки | МЕХАНИЗИРОВАНО | MECHANIZED |
| снятое правило | СНЯТО | RETIRED |
Служебные слова сценарного блока — КОГДА, ТОГДА, И, ИЛИ; таблица
и объяснение в разделе «Таблицы решений».
Что требуется от любого словаря:
- одна форма на ступень и на метку. Синонимы отклонены не из аскетизма: проверка «модальное слово вне правила» перечисляет формы, и синонимический ряд превращает перечисление в разбор.
- слово заглавными не встречается в обычной прозе этого языка. Иначе правило «нормативно только заглавное» перестаёт спасать: проверка ловит оформление, а не модальность.
- модальные слова и метки перечислены в строке о версии языка. Читателю копии они известны из самого файла, без обращения к этому документу, — иначе конвенция в чужом репозитории теряет ключ к собственному тексту. Служебные слова сценария в строку не входят: структура блока читается из самого блока, и в файле без стыков правил их нет вовсе.
- словарь один на канон. Два словаря параллельно дают две формы записи одного требования и удваивают каждую проверку; выбор языка — свойство набора, а не отдельного файла.
Ссылка на язык из конвенции
Каждая конвенция называет язык одной строкой во вводной прозе:
Ключевые слова ДОЛЖЕН, НЕ ДОЛЖЕН, СЛЕДУЕТ, НЕ СЛЕДУЕТ, ДОПУСКАЕТСЯ и метки ПОЧЕМУ, ПРИМЕРЫ, МЕХАНИЗИРОВАНО и СНЯТО толкуются как описано в языке конвенций версии 1 — тогда и только тогда, когда написаны заглавными.
Слова в строке — из словаря того языка, на котором написан набор. Для англоязычного набора та же строка выглядит так:
The key words MUST, MUST NOT, SHOULD, SHOULD NOT, MAY and the marks WHY, EXAMPLES, MECHANIZED and RETIRED are to be interpreted as described in the conventions language, version 1, and only when written in capitals.
Форма скопирована у BCP 14, где та же задача решается тем же способом: спецификация не прикладывает к себе словарь и не указывает путь к нему, а называет документ и версию. Пути в этой строке нет намеренно — конвенция уезжает в чужой репозиторий, где путей канона не существует, а норму исполнить всё равно можно: строка сама перечисляет ключевые слова набора и сама несёт правило заглавных.
Обязательность и способ проверки — разные атрибуты
Механизация не входит в шкалу модальности: она говорит не о том, насколько правило обязательно, а о том, чем эта обязательность обеспечена. В 29148 это два разных атрибута требования, и здесь тоже два.
Проверяющий по умолчанию — читатель правила, человек или агент. Канон пишется прежде всего под агента: он читает конвенцию и по ней смотрит код, то есть проверка есть у каждого правила с первого дня, и её инструмент — формулировка нормы. Поэтому вторым условием ДОЛЖЕН стоит воспроизводимость вердикта (META-6), а не наличие скрипта: ступень говорит о важности нормы и о том, сколько внимания она получает при проверке, а не о состоянии инструментов. Линтер сильнее чтения — он не забывает, ничего не стоит на каждом прогоне и краснеет до ревью, — поэтому механизация желательна везде, где проверка пишется (META-27), и остаётся концом пути «находка → конвенция → проверка». Но обязательным условием высшей ступени она не является: иначе весь канон стоял бы в СЛЕДУЕТ до появления скриптов, которых пока нет ни одного.
Механизация нормы не заменяет и не сокращает. Норма остаётся в правиле навсегда — как и обоснование (META-8, META-10), — сколько бы проверок её ни подпирало. Причин три:
- линтер сообщает, что нарушено, но не сообщает, что требуется. Без нормы правило нечем исполнить и не с чем сверить вердикт проверки, а проверяющий по умолчанию читает именно норму;
- подписчики появляются позже. Репозиторий, подключившийся через год, получил бы правило без нормы и без линтера — ни текста, ни проверки;
- «механизировано у всех» набору не проверить: списка подписчиков у него нет по построению.
Отметка — свойство репозитория, а не набора. Механизирована норма или нет, зависит от того, чей это репозиторий, поэтому в тексте конвенции отметки нет: её место — запись о механизации в локальной части копии, со ссылкой на идентификатор правила (META-7).
<!-- conv:local -->
XMIG-2, XMIG-4 — МЕХАНИЗИРОВАНО: `internal/archrules`, в новых миграциях.
Так у правила остаются оба атрибута сразу: обязательность — в норме, которая приезжает из набора и одинакова у всех, способ проверки — в записи, которая принадлежит репозиторию и у каждого своя.
Таблицы решений
Часть правил классифицирует ситуации: какой уровень лога, какая
категория директории, что делать с невалидным вводом в зависимости от его
источника. Каноническая форма для них — таблица «ситуация → вердикт», строки
которой нумеруются как подпункты правила (XLOG-8.1).
Таблица плотнее прозы и не даёт пропустить ветку: пустая клетка видна, а неупомянутый случай в абзаце — нет. От такой таблицы требуются два свойства — первое названо в DMN, второе мы добавили сами («Где источник усилен»):
- Политика совпадения. По умолчанию строки взаимоисключающи: любой ситуации соответствует ровно одна. Если это не так, таблица объявляет порядок строкой над собой — «применяется первое совпадение». Молчание об этом означает, что при двух подходящих строках читатель выбирает сам, и два автора выберут по-разному.
- Полнота. Перечислены все случаи, попадающие в область действия. Если возможен случай вне перечисленных, он назван отдельной строкой, а не оставлен на догадку.
Сценарный блок остаётся точечным инструментом — для стыка правил, когда два правила вместе дают неочевидный результат:
КОГДА зависимость недоступна И ретраи вызова исчерпаны
ТОГДА внешний вызов даёт запись ERROR,
И тик фонового цикла, упавший по той же причине, — запись WARN
Такой блок ставится после обоих правил и ссылается на их идентификаторы. Если стыков нет — сценариев в файле нет.
Форма «условие → следствие» здесь взята намеренно, хотя как общая форма записи она отклонена: на стыке правил субъект действительно система, и результат разворачивается во времени — то самое, для чего эта форма и придумана. Служебные слова блока перечислены ниже и подчиняются тем же требованиям, что модальные: одна форма на роль, заглавными, набор один на канон.
| Роль | Русский | Английский |
|---|---|---|
| условие | КОГДА | WHEN |
| следствие | ТОГДА | THEN |
| соединение | И | AND |
| выбор | ИЛИ | OR |
Модальными словами они не являются: обязательности не задают, только структуру. Поэтому в строку о версии языка они не попадают — там перечисляется то, чему нужно определение, а логическая связка читается сама, — и под проверку «модальные слова вне правил» не подпадают.
Идентификаторы
Идентификаторов в языке два: правило адресуется префиксом с номером, конвенция целиком — именем темы. Ссылаться путём к файлу нельзя ни на то, ни на другое.
Правило.
- Формат —
<ПРЕФИКС>-<номер>:XKEY-5,XLOG-27. Префикс принадлежит файлу, нумерация внутри файла сквозная и начинается с единицы. - Строка таблицы, если на неё нужно ссылаться отдельно, —
XKEY-5.1,XKEY-5.2. - Идентификатор глобален. Префикс уникален по всему канону, поэтому
путь файла в ссылке не нужен:
XKEY-5адресует правило одинаково изнутри файла, из соседней конвенции и из чужого репозитория. В собранной копии слои разных осей лежат в одном документе, так что ссылка на базовый слой из языкового вообще никуда не ведёт — правило рядом. - Идентификаторы стабильны и не переиспользуются. Занять номер снятого правила новым нельзя — иначе ссылка из чужого репозитория начнёт указывать на другое утверждение. То же относится к префиксам: выбывшие хранит манифест набора.
- Снятое правило остаётся заглушкой. Заголовок и номер сохраняются, норму с обоснованием заменяет блок СНЯТО с датой и причиной. Поэтому нумерация в файле сплошная, а любая ссылка разрешается — либо в правило, либо в объяснение, почему его сняли (META-31, META-32). Отдельного реестра снятых номеров нет: он был бы вторым источником правды рядом с файлом.
- Префикс выбирается под файл, а не выводится по формуле: он нужен, чтобы по нему искать, а не чтобы его разбирать. Выводимый префикс вдобавок привязал бы идентификатор к таксономии, которую канон перестраивает, и упёрся бы в потолок из числа букв алфавита.
- Префиксы на букву
Xканоном не занимаются: они принадлежат локальным правилам репозиториев-потребителей. - Перенос правила в другой файл — смысловое изменение, а не переименование: новый файл означает новый префикс и новую нумерацию. Переезд самого файла между осями идентификаторы не трогает.
Порядок правил в файле выбирается по читаемости, не по номерам: номер — это идентификатор, а не позиция.
Тема.
- Тема — набор правил об одном фокусе разработки: время, конфигурация, схема БД. Она же — единица подписки: потребитель берёт тему целиком, а не отдельные правила.
- Имя темы записывается латиницей. Рекомендуется нижний kebab-case
(
db-identifiers), но годится любой идентификатор, пригодный для имени файла: имя попадает и в файловую систему потребителя, и в его манифест. - Тему объявляет файл, а не файловая система. Имя стоит в шапке
(
topic:) и зарегистрировано в манифесте набора. Слои одной темы несут одно и то же имя — по нему они и собираются в один документ, как бы ни назывались их файлы. - Имя темы не переиспользуется — как и префикс: оно живёт в шапке
origin:каждой копии, в подписке манифеста и в тексте ссылок, поэтому снятое имя уходит в раздел выбывших манифеста, а не достаётся другой теме. - Ссылка на конвенцию — имя темы (конвенция
logging), ссылка на правило — идентификатор (XLOG-27). Путь файла не употребляется ни там, ни там: в собранной копии путей канона не существует.
Что правилом не является
Заглавные модальные слова в этих частях не употребляются — иначе перестанет быть понятно, что адресуемо, а что нет:
- Область действия — на что конвенция распространяется во времени («новые таблицы; существующие не переписываются»). Это рамка для всех правил файла, а не правило.
- Связано — ссылки на смежные конвенции, ADR, код.
- Локальная часть копии — содержимое принадлежит репозиторию.
- Вводная проза, объясняющая предмет конвенции.
Все четыре части лежат вне областей правил: до первого заголовка правила или после заголовка, которым область закрылась. Хвост обоснования сюда не относится — он внутри правила, и модальные слова в нём законны как упоминания.
Как на правила ссылаются копии
Ниже маркера локальной части, в репозитории:
<!-- conv:local -->
XMIG-2, XMIG-4 — МЕХАНИЗИРОВАНО: `internal/archrules`, в новых миграциях.
XMIG-6 не соблюдается в легаси-таблицах `show_history`, `queue`: составные
ключи там появились до конвенции, переписывание требует миграции данных.
Отсюда видно и то, чего раньше не было видно: конвенция из восьми правил, из которых два механизированы и одно не соблюдается.
Что стоит проверять машиной
Проверке подлежит всё, что язык употребляет: файлы конвенций и документ,
которым канон сам себя ведёт (в этом каноне — GUIDE.md, префикс META). Файл,
который язык цитирует, — это описание вроде текущего: ключевые слова стоят
в нём как предмет разговора, а не как норма, и проверки к нему не применяются.
Различает не расположение файла, а роль слова в нём.
Ни одна проверка пока не реализована, поэтому при ревью их выполняют чтением.
Форма правила — разбором текста, в любом файле, который язык употребляет:
- модальные и служебные слова принадлежат объявленному словарю канона, а не смеси словарей;
- префикс в шапке файла совпадает с манифестом набора, состоит из четырёх
заглавных латинских букв, не начинается на
Xи не значится в списке выбывших; - заголовки правил файла используют только его собственный префикс;
- нумерация внутри файла сплошная: от единицы до наибольшего номера без пропусков, номера не повторяются, новое правило берёт следующий за наибольшим (META-31);
- у каждого
### <ПРЕФИКС>-<n>есть либо модальное слово с нормой и блок ПОЧЕМУ — ни норма, ни обоснование не удаляются никогда (META-8, META-10), — либо блок СНЯТО с датой и причиной; - блок ПРИМЕРЫ, если он есть, стоит после обоснования и не открывает правило: порядок блоков — норма, ПОЧЕМУ, ПРИМЕРЫ;
- вводная проза содержит строку о версии языка;
- ссылки вида
<ПРЕФИКС>-<n>— хоть в тексте набора, хоть в локальной части копии — разрешаются: неразрешённый идентификатор всегда ошибка (META-32); - заглавные модальные слова не встречаются вне областей правил (область — от заголовка правила до следующего заголовка) — кроме строки о версии языка, которая их перечисляет по назначению;
- модальная метка стоит первой в своём абзаце: заглавное слово в середине фразы — упоминание ступени, а не вторая норма правила.
Распространение — разбором текста, только в файлах конвенций: эти проверки о том, что документ уезжает к потребителю, а документ, которым канон ведёт себя, не уезжает никуда.
- шапка файла несёт имя темы, и это имя стоит в манифесте набора — среди живых, а не среди выбывших;
- ось слоя объявлена в шапке, а не выведена из пути; у одной темы не больше одного слоя без ключей оси — базовый слой единственный;
- если директории осей используются, объявленное в шапке совпадает с путём: расхождение означает переезд файла без правки шапки;
- имя темы, названное в ссылке или в подписке потребителя, тоже разрешается по манифесту: ссылка на снятую тему не проходит молча;
- префиксы локальных правил копии начинаются на
X; - отметки МЕХАНИЗИРОВАНО в тексте конвенции нет: её место — запись о механизации в локальной части копии (META-7);
- словарь в коротком описании языка совпадает с этим: те же ступени, те же метки, те же значения (META-30);
- префикс чужой темы не встречается в абзаце с модальностью (META-20); префикс арх-слоя своей темы там допустим (META-24), префикс другого языка или стека — нет;
- путь файла канона не встречается в тексте конвенции (META-21).
Чтением, потому что машине не даётся:
- строки таблицы взаимоисключающи либо политика совпадения объявлена;
- перечисленные в таблице случаи покрывают область действия;
- норма исполнима без обращения к другим файлам (в файлах конвенций: они уезжают по одной, а обвязка ссылается на соседей свободно);
- обоснование отвечает на «что сломается», а не пересказывает норму;
- хвост обоснования не вводит требований, которых нет в блоке нормы;
- примеры иллюстрируют норму и не расширяют её: деталь примера не читается как требование.
Проверки выше — про запись правила. Граница самой темы (не собрала ли она два решения сразу, нужна ли потребителю целиком) языку не принадлежит: её вопросы стоят в документе, которым набор ведёт себя.
Версия языка
Номер версии называется в каждой конвенции, поэтому он двигается, когда изменение формы способно изменить чтение уже разданной копии: копия ссылается на номер, а не на текст, и обязана читаться по той версии, по которой написана. Правки формы до того, как копии разошлись, номер не двигают — читать по ним пока нечего.
Смена словаря под другой естественный язык версию не двигает никогда: версия принадлежит шкале, меткам и правилам формы, а не буквам.