язык записи опёрт на стандарты, словарь стал параметром
- шкала обязательности объявлена инвариантом, а набор ключевых слов — параметром естественного языка набора: для английского готовый словарь даёт BCP 14, для прочих берут перевод стандарта или делают свой; отклонены синонимы ступеней и `SHALL`, занятый OpenSpec - применены шесть дельт: нормативно только заглавное написание (RFC 8174), ДОЛЖЕН требует названного вреда и машинной проверки сразу, ДОПУСКАЕТСЯ адресовано рецензенту, МЕХАНИЗИРОВАНО выведено из шкалы в отметку рядом с модальностью (ISO/IEC/IEEE 29148), у таблиц объявлены политика совпадения и полнота (DMN) - «Форма записи — LANGUAGE.md» в двенадцати конвенциях заменена строкой о версии языка по образцу boilerplate BCP 14: пути канона в копии не существует, а словарь и правило заглавных строка несёт сама
This commit is contained in:
@@ -21,15 +21,28 @@ code in this repository.
|
|||||||
`**МОДАЛЬНОСТЬ.** норма`, абзац `**Почему.** …`. Правило без «Почему» не
|
`**МОДАЛЬНОСТЬ.** норма`, абзац `**Почему.** …`. Правило без «Почему» не
|
||||||
принимается.
|
принимается.
|
||||||
- Норма — одна фраза; если в неё не влезает, это два правила.
|
- Норма — одна фраза; если в неё не влезает, это два правила.
|
||||||
- Модальные слова: **ДОЛЖЕН**, **НЕ ДОЛЖЕН**, **СЛЕДУЕТ**, **НЕ СЛЕДУЕТ**,
|
- Шкала инвариантна, словарь — параметр языка набора. Канон русский, значит
|
||||||
**ДОПУСКАЕТСЯ**, плюс не-модальная отметка **МЕХАНИЗИРОВАНО**. Английские
|
слова: **ДОЛЖЕН**, **НЕ ДОЛЖЕН**, **СЛЕДУЕТ**, **НЕ СЛЕДУЕТ**,
|
||||||
ключевые слова (SHALL, MUST) не используются — они заняты OpenSpec.
|
**ДОПУСКАЕТСЯ**. Словарь один на канон, синонимов на ступень нет.
|
||||||
- Модальные слова не употребляются вне правил: ни в «Область действия», ни в
|
- `SHALL` не используется ни в одном словаре — занято OpenSpec.
|
||||||
«Связано», ни в локальной части копии, ни во вводной прозе.
|
- Нормативно только заглавное написание (правило RFC 8174): строчное
|
||||||
|
«должен» в прозе нормой не является.
|
||||||
|
- ДОЛЖЕН требует двух условий сразу: нарушение причиняет названный вред
|
||||||
|
и норма проверяема машиной. Проверяемость сама по себе до ДОЛЖЕН не
|
||||||
|
повышает.
|
||||||
|
- ДОПУСКАЕТСЯ адресовано рецензенту: помеченный им выбор на ревью не
|
||||||
|
обсуждается.
|
||||||
|
- **МЕХАНИЗИРОВАНО** — не модальность, а способ проверки: отметка стоит
|
||||||
|
рядом с модальным словом (`**ДОЛЖЕН. МЕХАНИЗИРОВАНО.**`), а не вместо него.
|
||||||
|
- Заглавные модальные слова не употребляются вне правил: ни в «Область
|
||||||
|
действия», ни в «Связано», ни в локальной части копии, ни во вводной прозе.
|
||||||
|
Исключение — строка о версии языка, которая их перечисляет.
|
||||||
- «Почему» отвечает на «что сломается, если сделать иначе», а не
|
- «Почему» отвечает на «что сломается, если сделать иначе», а не
|
||||||
пересказывает норму. «Потому что так принято» — не обоснование.
|
пересказывает норму. «Потому что так принято» — не обоснование.
|
||||||
- Правило, классифицирующее ситуации, пишется таблицей «ситуация → вердикт»;
|
- Правило, классифицирующее ситуации, пишется таблицей «ситуация → вердикт»;
|
||||||
строки нумеруются `KEYS-5.1`.
|
строки нумеруются `KEYS-5.1`. Строки взаимоисключающи по умолчанию; иной
|
||||||
|
порядок объявляется явно, а перечисленные случаи покрывают область
|
||||||
|
действия.
|
||||||
- Модальность принадлежит правилу, а не файлу: `status:` в шапке отменён.
|
- Модальность принадлежит правилу, а не файлу: `status:` в шапке отменён.
|
||||||
|
|
||||||
## Идентификаторы и префиксы
|
## Идентификаторы и префиксы
|
||||||
@@ -88,8 +101,9 @@ code in this repository.
|
|||||||
|
|
||||||
## Оформление файла
|
## Оформление файла
|
||||||
|
|
||||||
Шапка `prefix:` (плюс `extends:`) → `# Тема` → вводная проза со строкой
|
Шапка `prefix:` (плюс `extends:`) → `# Тема` → вводная проза → отдельным
|
||||||
«Форма записи — `LANGUAGE.md`» → `## Область действия` (обязателен для
|
абзацем строка о версии языка (её точный текст — в `LANGUAGE.md`, раздел
|
||||||
|
«Ссылка на язык из конвенции») → `## Область действия` (обязателен для
|
||||||
трудноизменяемых слоёв — META-11) → правила → `## Связано` только с
|
трудноизменяемых слоёв — META-11) → правила → `## Связано` только с
|
||||||
каноническими ссылками (META-17). Имя файла — kebab-case по теме. Проза
|
каноническими ссылками (META-17). Имя файла — kebab-case по теме. Проза
|
||||||
переносится по ~76 колонок; таблицы и блоки кода не переносятся.
|
переносится по ~76 колонок; таблицы и блоки кода не переносятся.
|
||||||
|
|||||||
+253
-109
@@ -1,16 +1,55 @@
|
|||||||
|
---
|
||||||
|
version: 1
|
||||||
|
---
|
||||||
|
|
||||||
# Язык конвенций
|
# Язык конвенций
|
||||||
|
|
||||||
Как записываются правила в этом каноне. Документ описывает форму, а не
|
Формальный язык, на котором записаны правила этого канона: что считается
|
||||||
содержание: что такое правило, чем оно отличается от прозы вокруг и как на
|
правилом, чем оно отличается от прозы вокруг, какими словами задаётся
|
||||||
него сослаться.
|
обязательность и как на правило сослаться извне.
|
||||||
|
|
||||||
Форма подсмотрена у OpenSpec, но взято оттуда не всё — см. «Чего мы не
|
Версия языка — **1**. Номер называется в каждой конвенции: словарь может
|
||||||
берём».
|
пополниться, и текст, написанный по предыдущей версии, должен читаться по
|
||||||
|
той, по которой написан.
|
||||||
|
|
||||||
## Зачем формализовать
|
## Опора на стандарты
|
||||||
|
|
||||||
Не ради строгости. Три конкретные вещи, которые без адресуемых правил не
|
Язык не выводится из вкуса автора. Каждое решение о форме взято из
|
||||||
работают:
|
документа, где эта задача уже решена и обкатана, и отклонения от источника
|
||||||
|
названы явно.
|
||||||
|
|
||||||
|
| Источник | Что взято | Что отклонено |
|
||||||
|
|---|---|---|
|
||||||
|
| **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 другой результат: измеримый выигрыш дала
|
||||||
|
там сама обязательность шаблона, а не его конкретная форма.
|
||||||
|
|
||||||
|
## Что даёт формализация
|
||||||
|
|
||||||
|
Адресуемое правило — не украшение формы, а условие работы трёх механизмов:
|
||||||
|
|
||||||
- **Механизация.** Запись о ней должна говорить «правило `MIGR-4` проверяет
|
- **Механизация.** Запись о ней должна говорить «правило `MIGR-4` проверяет
|
||||||
`archrules`», а не «`AUTOINCREMENT` в новых миграциях — `archrules`»: во
|
`archrules`», а не «`AUTOINCREMENT` в новых миграциях — `archrules`»: во
|
||||||
@@ -39,51 +78,202 @@
|
|||||||
```
|
```
|
||||||
|
|
||||||
Четыре обязательные части: **идентификатор**, **заголовок**, **модальность
|
Четыре обязательные части: **идентификатор**, **заголовок**, **модальность
|
||||||
с нормой**, **почему**. Норма — одна фраза; если в неё не влезает, это два
|
с нормой**, **обоснование**. Норма — одна фраза; если в неё не влезает, это
|
||||||
правила.
|
два правила. Требование единичности взято из ISO/IEC/IEEE 29148: составная
|
||||||
|
норма не проверяема целиком, и нарушение одной её половины нечем
|
||||||
|
адресовать.
|
||||||
|
|
||||||
## Правило без «почему» не принимается
|
## Обоснование обязательно
|
||||||
|
|
||||||
Это жёсткое требование к форме, а не пожелание. Причины:
|
Правило без блока «Почему» не принимается. Это требование к форме, а не
|
||||||
|
пожелание; в 29148 обоснование — атрибут требования наравне с самим
|
||||||
|
требованием, и по тем же причинам:
|
||||||
|
|
||||||
- **«Почему» — единственный способ понять, когда правило перестало
|
- **Обоснование — единственный способ увидеть, что правило устарело.**
|
||||||
действовать.** Норма стареет молча; обоснование стареет заметно. Когда
|
Норма стареет молча; причина стареет заметно. Когда причина отпала, видно,
|
||||||
причина отпала, видно, что правило пора убрать, а не соблюдать по
|
что правило пора убрать, а не соблюдать по инерции.
|
||||||
инерции.
|
|
||||||
- **Правило без обоснования не переживает спор.** Через год ни автор, ни
|
- **Правило без обоснования не переживает спор.** Через год ни автор, ни
|
||||||
агент не восстановят мотив, и правило будет либо отменено первым же
|
агент не восстановят мотив, и правило будет либо отменено первым же
|
||||||
возражением, либо соблюдено там, где вредит.
|
возражением, либо соблюдено там, где вредит.
|
||||||
- **Формулировка «почему» — проверка на то, что это вообще правило.** Если
|
- **Формулировка обоснования — проверка на то, что это вообще правило.**
|
||||||
причина не формулируется, перед нами привычка или вкусовщина; ей место в
|
Если причина не формулируется, перед нами привычка или вкусовщина; ей
|
||||||
черновиках, а не в конвенции.
|
место в черновиках, а не в конвенции.
|
||||||
|
|
||||||
«Почему» отвечает на «что сломается, если сделать иначе», а не пересказывает
|
«Почему» отвечает на «что сломается, если сделать иначе», а не пересказывает
|
||||||
норму другими словами. «Потому что так принято» — не обоснование.
|
норму другими словами. «Потому что так принято» — не обоснование.
|
||||||
|
|
||||||
## Модальные слова
|
## Модальные слова
|
||||||
|
|
||||||
Пишутся капсом — это ключевые слова, а не обычный текст.
|
Инвариант языка — **шкала**: пять ступеней в четырёх категориях ISO/IEC
|
||||||
|
Directives, Part 2, по одной форме записи на ступень, заглавными. Какими
|
||||||
|
словами ступени названы — параметр естественного языка набора, а не часть
|
||||||
|
языка конвенций. Этот канон написан по-русски и несёт русский словарь.
|
||||||
|
|
||||||
| Слово | Значение | Отступление |
|
Пишутся заглавными — это ключевые слова, а не обычный текст.
|
||||||
|
|
||||||
|
| Слово | Категория | Значение | Отступление |
|
||||||
|
|---|---|---|---|
|
||||||
|
| **ДОЛЖЕН** | требование | нарушение считается ошибкой | только с записью в отступления |
|
||||||
|
| **НЕ ДОЛЖЕН** | требование | запрет | то же |
|
||||||
|
| **СЛЕДУЕТ** | рекомендация | сильная рекомендация; новый код пишем так | допустимо, причину записываем |
|
||||||
|
| **НЕ СЛЕДУЕТ** | рекомендация | обратное к СЛЕДУЕТ | то же |
|
||||||
|
| **ДОПУСКАЕТСЯ** | разрешение | выбор за автором кода; возражение на ревью не принимается | не требуется — правило ничего не запрещает |
|
||||||
|
|
||||||
|
**Нормативно только заглавное написание.** Это правило RFC 8174, и оно
|
||||||
|
здесь по той же причине, по которой понадобилось там: без него каждое
|
||||||
|
строчное «должен» во вводной прозе становится предметом спора о том, норма
|
||||||
|
это или речь. Строчное слово нормой не является никогда, поэтому проза
|
||||||
|
свободна, а проверка «модальное слово вне правила» сводится к поиску
|
||||||
|
заглавных форм.
|
||||||
|
|
||||||
|
**Четвёртая категория ISO — возможность — ключевого слова не имеет.**
|
||||||
|
Утверждения о том, что бывает и что технически осуществимо, пишутся обычной
|
||||||
|
прозой и модальных слов не несут. Модальное слово в таком утверждении
|
||||||
|
превращает описание в норму, которую никто не собирался вводить.
|
||||||
|
|
||||||
|
**ДОПУСКАЕТСЯ адресовано рецензенту.** В BCP 14 у `MAY` есть вторая
|
||||||
|
половина, которую обычно не замечают: сторона, не выбравшая опцию, обязана
|
||||||
|
работать с той, что выбрала. В конвенции этому соответствует запрет
|
||||||
|
возражать: выбор, помеченный ДОПУСКАЕТСЯ, на ревью не обсуждается. Без этой
|
||||||
|
половины слово было бы удобством читателя, а не нормой, и не работало бы в
|
||||||
|
единственной точке, где у конвенции есть принуждение.
|
||||||
|
|
||||||
|
**ДОЛЖЕН требует двух условий сразу:**
|
||||||
|
|
||||||
|
1. нарушение причиняет названный вред, а не расходится со вкусом — критерий
|
||||||
|
BCP 14, где высшая модальность резервируется под то, что действительно
|
||||||
|
ломается, и не употребляется для навязывания метода;
|
||||||
|
2. норма проверяема машиной — критерий META-6, иначе обязательность
|
||||||
|
держится на внимании и обещает то, чего не делает.
|
||||||
|
|
||||||
|
Не выполнено первое — правилу место в СЛЕДУЕТ или нигде. Не выполнено
|
||||||
|
второе — в СЛЕДУЕТ. Проверяемость сама по себе не повышает правило до
|
||||||
|
ДОЛЖЕН: механически проверяемых мелочей больше, чем важных вещей, и
|
||||||
|
безразборное повышение обесценивает шкалу быстрее, чем её отсутствие.
|
||||||
|
|
||||||
|
Модальность живёт на **правиле**, а не на файле. Файловый статус
|
||||||
|
(`status: рекомендуемая` / `обязательная` в шапке) не используется: он
|
||||||
|
неизбежно врёт, потому что один файл смешивает жёсткие требования с
|
||||||
|
советами. В шапке остаются только `prefix` и `extends`.
|
||||||
|
|
||||||
|
## Словарь другого языка
|
||||||
|
|
||||||
|
Для английского готовый словарь даёт BCP 14. Для любого другого языка слова
|
||||||
|
берут из перевода стандарта, если он есть, или переводят сами: шкала и
|
||||||
|
семантика ступеней при этом не меняются — меняется только запись.
|
||||||
|
|
||||||
|
| Ступень | Русский | Английский (BCP 14) |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| **ДОЛЖЕН** | нарушение считается ошибкой | только с записью в регион `отступления` |
|
| требование | ДОЛЖЕН | MUST |
|
||||||
| **НЕ ДОЛЖЕН** | запрет | то же |
|
| запрет | НЕ ДОЛЖЕН | MUST NOT |
|
||||||
| **СЛЕДУЕТ** | сильная рекомендация; новый код пишем так | допустимо, причину записываем |
|
| рекомендация | СЛЕДУЕТ | SHOULD |
|
||||||
| **НЕ СЛЕДУЕТ** | обратное к СЛЕДУЕТ | то же |
|
| рекомендация против | НЕ СЛЕДУЕТ | SHOULD NOT |
|
||||||
| **ДОПУСКАЕТСЯ** | явное разрешение | не требуется — правило ничего не запрещает |
|
| разрешение | ДОПУСКАЕТСЯ | MAY |
|
||||||
|
| отметка о способе проверки | МЕХАНИЗИРОВАНО | MECHANIZED |
|
||||||
|
|
||||||
**ДОПУСКАЕТСЯ** нужно не для симметрии: оно снимает вопрос «а так можно?»
|
Последняя строка стандартом не даётся ни в одном языке: способа проверки в
|
||||||
там, где соседнее правило звучит строго и его легко перечитать шире, чем
|
шкале BCP 14 нет, слово подбирается под язык так же, как остальные.
|
||||||
задумано.
|
|
||||||
|
|
||||||
Модальность живёт на **правиле**, а не на файле. Прежний файловый статус
|
Что требуется от любого словаря:
|
||||||
(`status: рекомендуемая` / `обязательная` в шапке) отменён: он неизбежно
|
|
||||||
врал, потому что один файл смешивает жёсткие требования с советами. В шапке
|
|
||||||
остаются только `prefix` и `extends`.
|
|
||||||
|
|
||||||
Мы **не используем SHALL и прочие английские ключевые слова**. Они заняты
|
- **одна форма на ступень.** Синонимы отклонены не из аскетизма: проверка
|
||||||
спецификациями (OpenSpec), и общий словарь стирал бы границу «конвенция —
|
«модальное слово вне правила» перечисляет формы, и синонимический ряд
|
||||||
не capability». Разный словарь эту границу держит бесплатно.
|
превращает перечисление в разбор.
|
||||||
|
- **слово заглавными не встречается в обычной прозе этого языка.** Иначе
|
||||||
|
правило «нормативно только заглавное» перестаёт спасать: проверка ловит
|
||||||
|
оформление, а не модальность.
|
||||||
|
- **словарь перечислен целиком в строке о версии языка.** Читателю копии он
|
||||||
|
известен из самого файла, без обращения к этому документу, — иначе
|
||||||
|
конвенция в чужом репозитории теряет ключ к собственному тексту.
|
||||||
|
- **словарь один на канон.** Два словаря параллельно дают две формы записи
|
||||||
|
одного требования и удваивают каждую проверку; выбор языка — свойство
|
||||||
|
набора, а не отдельного файла.
|
||||||
|
|
||||||
|
Смена словаря версию языка не меняет: версия принадлежит шкале и правилам
|
||||||
|
формы, а не буквам.
|
||||||
|
|
||||||
|
## Ссылка на язык из конвенции
|
||||||
|
|
||||||
|
Каждая конвенция называет язык одной строкой во вводной прозе:
|
||||||
|
|
||||||
|
> Ключевые слова ДОЛЖЕН, НЕ ДОЛЖЕН, СЛЕДУЕТ, НЕ СЛЕДУЕТ, ДОПУСКАЕТСЯ и
|
||||||
|
> отметка МЕХАНИЗИРОВАНО толкуются как описано в языке конвенций версии 1 —
|
||||||
|
> тогда и только тогда, когда написаны заглавными.
|
||||||
|
|
||||||
|
Слова в строке — из словаря того языка, на котором написан набор. Для
|
||||||
|
англоязычного набора та же строка выглядит так:
|
||||||
|
|
||||||
|
> The key words MUST, MUST NOT, SHOULD, SHOULD NOT, MAY and the mark
|
||||||
|
> MECHANIZED are to be interpreted as described in the conventions language,
|
||||||
|
> version 1, and only when written in capitals.
|
||||||
|
|
||||||
|
Форма скопирована у BCP 14, где та же задача решается тем же способом:
|
||||||
|
спецификация не прикладывает к себе словарь и не указывает путь к нему, а
|
||||||
|
называет документ и версию. Пути в этой строке нет намеренно — конвенция
|
||||||
|
уезжает в чужой репозиторий, где путей канона не существует, а норму
|
||||||
|
исполнить всё равно можно: строка сама перечисляет ключевые слова набора и
|
||||||
|
сама несёт правило заглавных.
|
||||||
|
|
||||||
|
## Обязательность и способ проверки — разные атрибуты
|
||||||
|
|
||||||
|
Механизация не входит в шкалу модальности: она говорит не о том, насколько
|
||||||
|
правило обязательно, а о том, чем эта обязательность обеспечена. В 29148 это
|
||||||
|
два разных атрибута требования, и здесь тоже два.
|
||||||
|
|
||||||
|
Когда правило механизировано у всех потребителей, его норма из канона
|
||||||
|
удаляется, а модальность и обоснование остаются:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
### MIGR-6. Дефолтов времени в схеме БД нет
|
||||||
|
|
||||||
|
**ДОЛЖЕН. МЕХАНИЗИРОВАНО.** Проверяется общим правилом линтера;
|
||||||
|
формулировка удалена, потому что дублировала работающую проверку.
|
||||||
|
|
||||||
|
**Почему.** Дефолт превращает забытую вставку в тихо работающий код…
|
||||||
|
```
|
||||||
|
|
||||||
|
- Идентификатор и заголовок сохраняются: ссылки из репозиториев продолжают
|
||||||
|
указывать на то же утверждение.
|
||||||
|
- Модальность сохраняется, поэтому «все ли ДОЛЖЕН механизированы»
|
||||||
|
остаётся вычислимым вопросом, а не предметом чтения всего канона.
|
||||||
|
- «Почему» остаётся навсегда — линтер сообщает, что нарушено, но не
|
||||||
|
сообщает, зачем правило существует, и без обоснования нельзя понять,
|
||||||
|
когда проверку пора отменять.
|
||||||
|
|
||||||
|
Факт «механизировано у всех» устанавливается вручную: канон по построению
|
||||||
|
не знает списка подписчиков, и обойти репозитории перед удалением нормы —
|
||||||
|
часть работы, а не то, что можно проверить автоматически.
|
||||||
|
|
||||||
|
## Таблицы решений
|
||||||
|
|
||||||
|
Часть правил **классифицирует ситуации**: какой уровень лога, какая
|
||||||
|
категория директории, что делать с невалидным вводом в зависимости от его
|
||||||
|
источника. Каноническая форма для них — таблица «ситуация → вердикт», строки
|
||||||
|
которой нумеруются как подпункты правила (`SLOG-8.1`).
|
||||||
|
|
||||||
|
Таблица плотнее прозы и не даёт пропустить ветку: пустая клетка видна, а
|
||||||
|
неупомянутый случай в абзаце — нет. Два свойства такой таблицы взяты из DMN,
|
||||||
|
где они называются и проверяются:
|
||||||
|
|
||||||
|
- **Политика совпадения.** По умолчанию строки взаимоисключающи: любой
|
||||||
|
ситуации соответствует ровно одна. Если это не так, таблица объявляет
|
||||||
|
порядок строкой над собой — «применяется первое совпадение». Молчание об
|
||||||
|
этом означает, что при двух подходящих строках читатель выбирает сам, и
|
||||||
|
два автора выберут по-разному.
|
||||||
|
- **Полнота.** Перечислены все случаи, попадающие в область действия. Если
|
||||||
|
возможен случай вне перечисленных, он назван отдельной строкой, а не
|
||||||
|
оставлен на догадку.
|
||||||
|
|
||||||
|
Прозаический сценарий остаётся точечным инструментом — для **стыка правил**,
|
||||||
|
когда два правила вместе дают неочевидный результат:
|
||||||
|
|
||||||
|
```
|
||||||
|
WHEN зависимость недоступна и ретраи вызова исчерпаны → ext-запись ERROR
|
||||||
|
AND тик фонового цикла упал по той же причине → доменная запись WARN
|
||||||
|
```
|
||||||
|
|
||||||
|
Такой блок ставится после обоих правил и ссылается на их идентификаторы.
|
||||||
|
Если стыков нет — сценариев в файле нет.
|
||||||
|
|
||||||
## Идентификаторы
|
## Идентификаторы
|
||||||
|
|
||||||
@@ -104,6 +294,8 @@
|
|||||||
чтобы по нему искать, а не чтобы его разбирать. Выводимый префикс вдобавок
|
чтобы по нему искать, а не чтобы его разбирать. Выводимый префикс вдобавок
|
||||||
привязал бы идентификатор к таксономии, которую канон перестраивает, и
|
привязал бы идентификатор к таксономии, которую канон перестраивает, и
|
||||||
упёрся бы в потолок из числа букв алфавита.
|
упёрся бы в потолок из числа букв алфавита.
|
||||||
|
- Префиксы на букву `X` каноном не занимаются: они принадлежат локальным
|
||||||
|
правилам репозиториев-потребителей.
|
||||||
- Перенос правила в другой файл — смысловое изменение, а не переименование:
|
- Перенос правила в другой файл — смысловое изменение, а не переименование:
|
||||||
новый файл означает новый префикс и новую нумерацию. Переезд самого файла
|
новый файл означает новый префикс и новую нумерацию. Переезд самого файла
|
||||||
между осями идентификаторы не трогает.
|
между осями идентификаторы не трогает.
|
||||||
@@ -111,69 +303,10 @@
|
|||||||
Порядок правил в файле выбирается по читаемости, не по номерам: номер — это
|
Порядок правил в файле выбирается по читаемости, не по номерам: номер — это
|
||||||
идентификатор, а не позиция.
|
идентификатор, а не позиция.
|
||||||
|
|
||||||
## Правило, чья норма уехала в линтер
|
|
||||||
|
|
||||||
Когда правило механизировано у всех потребителей, его норма из канона
|
|
||||||
удаляется, а обоснование — нет. Остаётся **правило без модальности**, и
|
|
||||||
чтобы оно не выглядело недописанным, место нормы занимает отметка:
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
### MIGR-6. Дефолтов времени в схеме БД нет
|
|
||||||
|
|
||||||
**МЕХАНИЗИРОВАНО.** Проверяется общим правилом линтера; формулировка
|
|
||||||
удалена, потому что дублировала работающую проверку.
|
|
||||||
|
|
||||||
**Почему.** Дефолт превращает забытую вставку в тихо работающий код…
|
|
||||||
```
|
|
||||||
|
|
||||||
- Идентификатор и заголовок сохраняются: ссылки из репозиториев продолжают
|
|
||||||
указывать на то же утверждение.
|
|
||||||
- «Почему» остаётся навсегда — линтер сообщает, что нарушено, но не
|
|
||||||
сообщает, зачем правило существует, и без обоснования нельзя понять,
|
|
||||||
когда проверку пора отменять.
|
|
||||||
- **МЕХАНИЗИРОВАНО** — не шестое модальное слово: оно не задаёт
|
|
||||||
обязательность, а сообщает, что обязательность теперь обеспечена машиной.
|
|
||||||
В остальном такое правило равно ДОЛЖЕН.
|
|
||||||
|
|
||||||
Факт «механизировано у всех» устанавливается вручную: канон по построению
|
|
||||||
не знает списка подписчиков, и обойти репозитории перед удалением нормы —
|
|
||||||
часть работы, а не то, что можно проверить автоматически.
|
|
||||||
|
|
||||||
## Таблицы вместо сценариев
|
|
||||||
|
|
||||||
Часть правил **классифицирует ситуации**: какой уровень лога, какая
|
|
||||||
категория директории, что делать с невалидным вводом в зависимости от его
|
|
||||||
источника. Для них каноническая форма — таблица «ситуация → вердикт»,
|
|
||||||
строки которой при необходимости нумеруются.
|
|
||||||
|
|
||||||
Таблица плотнее прозы и не даёт пропустить ветку: пустая клетка видна, а
|
|
||||||
неупомянутый случай в абзаце — нет.
|
|
||||||
|
|
||||||
## Чего мы не берём из OpenSpec
|
|
||||||
|
|
||||||
**GIVEN/WHEN/THEN.** У спецификации субъект — система, и её поведение
|
|
||||||
разворачивается во времени: состояние, событие, исход. У конвенции субъект
|
|
||||||
— автор кода, и разворачивать нечего: есть ситуация выбора и вердикт. Это
|
|
||||||
таблица, а не траектория.
|
|
||||||
|
|
||||||
**SHALL.** См. выше про словарь.
|
|
||||||
|
|
||||||
**Сценарии как общая форма.** Прозаический сценарий остаётся точечным
|
|
||||||
инструментом — для **стыка правил**, когда два правила вместе дают
|
|
||||||
неочевидный результат:
|
|
||||||
|
|
||||||
```
|
|
||||||
WHEN зависимость недоступна и ретраи вызова исчерпаны → ext-запись ERROR
|
|
||||||
AND тик фонового цикла упал по той же причине → доменная запись WARN
|
|
||||||
```
|
|
||||||
|
|
||||||
Такой блок ставится после обоих правил и ссылается на их номера. Если
|
|
||||||
стыков нет — сценариев в файле нет.
|
|
||||||
|
|
||||||
## Что правилом не является
|
## Что правилом не является
|
||||||
|
|
||||||
Модальные слова в этих частях **не употребляются** — иначе перестанет быть
|
Заглавные модальные слова в этих частях **не употребляются** — иначе
|
||||||
понятно, что адресуемо, а что нет:
|
перестанет быть понятно, что адресуемо, а что нет:
|
||||||
|
|
||||||
- **Область действия** — на что конвенция распространяется во времени
|
- **Область действия** — на что конвенция распространяется во времени
|
||||||
(«новые таблицы; существующие не переписываются»). Это рамка для всех
|
(«новые таблицы; существующие не переписываются»). Это рамка для всех
|
||||||
@@ -201,24 +334,35 @@ MIGR-6 не соблюдается в легаси-таблицах `show_histor
|
|||||||
|
|
||||||
## Что стоит проверять машиной
|
## Что стоит проверять машиной
|
||||||
|
|
||||||
Сейчас не реализовано; список — на будущее для `conv`:
|
Проверки применяются к файлам конвенций; обвязка канона в них не входит —
|
||||||
|
она ключевые слова цитирует, а не употребляет. Ни одна пока не реализована,
|
||||||
|
поэтому при ревью их выполняют чтением.
|
||||||
|
|
||||||
|
Разбором текста:
|
||||||
|
|
||||||
|
- модальные слова принадлежат объявленному словарю канона, а не смеси
|
||||||
|
словарей;
|
||||||
- префикс в шапке файла совпадает с реестром, состоит из четырёх заглавных
|
- префикс в шапке файла совпадает с реестром, состоит из четырёх заглавных
|
||||||
латинских букв и не значится в списке выбывших;
|
латинских букв, не начинается на `X` и не значится в списке выбывших;
|
||||||
- заголовки правил файла используют только его собственный префикс;
|
- заголовки правил файла используют только его собственный префикс;
|
||||||
- номера уникальны внутри файла и не имеют пропусков вниз (новое правило
|
- номера уникальны внутри файла и не имеют пропусков вниз (новое правило
|
||||||
берёт следующий свободный, а не первый освободившийся);
|
берёт следующий свободный, а не первый освободившийся);
|
||||||
- у каждого `### <ПРЕФИКС>-<n>` есть модальное слово (или отметка
|
- у каждого `### <ПРЕФИКС>-<n>` есть модальное слово и блок «Почему»;
|
||||||
МЕХАНИЗИРОВАНО) и блок «Почему»;
|
отметка МЕХАНИЗИРОВАНО стоит рядом с модальностью, а не вместо неё;
|
||||||
|
- вводная проза содержит строку о версии языка;
|
||||||
- ссылки вида `<ПРЕФИКС>-<n>` — хоть в тексте канона, хоть в локальной части
|
- ссылки вида `<ПРЕФИКС>-<n>` — хоть в тексте канона, хоть в локальной части
|
||||||
копии — указывают на правила, которые ещё существуют;
|
копии — указывают на правила, которые ещё существуют;
|
||||||
- префиксы локальных правил копии начинаются на `X` и не совпадают с
|
- префиксы локальных правил копии начинаются на `X`;
|
||||||
реестром канона;
|
- заглавные модальные слова не встречаются вне правил — кроме строки о
|
||||||
- чужой префикс не встречается в абзаце с модальностью (META-20);
|
версии языка, которая их перечисляет по назначению;
|
||||||
- путь файла канона не встречается в тексте конвенции (META-21);
|
- префикс **чужой темы** не встречается в абзаце с модальностью (META-20);
|
||||||
- модальные слова не встречаются вне правил.
|
префикс своего же базового слоя там допустим — в собранной копии это
|
||||||
|
соседняя секция того же файла;
|
||||||
|
- путь файла канона не встречается в тексте конвенции (META-21).
|
||||||
|
|
||||||
## Порядок перевода
|
Чтением, потому что машине не даётся:
|
||||||
|
|
||||||
Все конвенции канона записаны на этом языке. Новая конвенция пишется на нём
|
- строки таблицы взаимоисключающи либо политика совпадения объявлена;
|
||||||
сразу; смешение форм в каноне больше не предполагается.
|
- перечисленные в таблице случаи покрывают область действия;
|
||||||
|
- норма исполнима без обращения к другим файлам;
|
||||||
|
- обоснование отвечает на «что сломается», а не пересказывает норму.
|
||||||
|
|||||||
@@ -16,8 +16,9 @@
|
|||||||
| `conv` | сборка копий |
|
| `conv` | сборка копий |
|
||||||
|
|
||||||
Обвязка живёт только в каноне и в репозитории не оказывается — в копию едет
|
Обвязка живёт только в каноне и в репозитории не оказывается — в копию едет
|
||||||
лишь содержимое `conventions/`. Пока это осознанное ограничение: копия
|
лишь содержимое `conventions/`. Самодостаточность копии это не нарушает:
|
||||||
конвенции ссылается на `LANGUAGE.md` как на внешний документ.
|
конвенция называет язык записи одной строкой с номером версии и не ссылается
|
||||||
|
на путь (`LANGUAGE.md`, раздел «Ссылка на язык из конвенции»).
|
||||||
|
|
||||||
Правило то же, что у ролей: **деплоится и читается только то, что лежит в
|
Правило то же, что у ролей: **деплоится и читается только то, что лежит в
|
||||||
git репозитория**. Канон никем не подключается на лету.
|
git репозитория**. Канон никем не подключается на лету.
|
||||||
|
|||||||
@@ -3,42 +3,18 @@
|
|||||||
Черновик для следующего разговора: вопросы и варианты, а не принятые
|
Черновик для следующего разговора: вопросы и варианты, а не принятые
|
||||||
решения.
|
решения.
|
||||||
|
|
||||||
## 1. Ссылка на `LANGUAGE.md` не переживает сборку
|
## 1. Ссылка на язык — закрыто
|
||||||
|
|
||||||
Все двенадцать конвенций во вводной прозе пишут «Форма записи —
|
Заменено boilerplate-строкой по образцу BCP 14: каждая конвенция называет
|
||||||
`LANGUAGE.md`». Обвязка в репозиторий не едет (`conv` синхронизирует только
|
ключевые слова, версию языка и правило заглавных, но не путь. Строка стоит
|
||||||
`conventions/`), поэтому в собранной копии эта ссылка указывает в никуда.
|
отдельным абзацем после вводной прозы во всех двенадцати файлах, «Форма
|
||||||
|
записи — `LANGUAGE.md`» удалена. Точный текст — в `LANGUAGE.md`, раздел
|
||||||
|
«Ссылка на язык из конвенции».
|
||||||
|
|
||||||
Это тот же класс дефекта, который вчера закрыло META-21 для ссылок между
|
Побочно: строка перечисляет модальные слова заглавными, то есть сама
|
||||||
темами: путь, верный в каноне, молча умирает при сборке. Разница в том, что
|
нарушает проверку «заглавные модальные слова не встречаются вне правил».
|
||||||
META-21 предлагает заменить путь на имя темы — а здесь заменять не на что,
|
Исключение записано в список проверок — так же, как оно устроено в BCP 14,
|
||||||
целевого документа в репозитории просто нет.
|
где boilerplate тоже содержит ключевые слова.
|
||||||
|
|
||||||
Варианты, которые видно сейчас:
|
|
||||||
|
|
||||||
- **Убрать упоминание из тел конвенций.** Язык записи — забота того, кто
|
|
||||||
пишет канон, а не того, кто читает конвенцию в своём репозитории. Читателю
|
|
||||||
достаточно самого текста: модальные слова и «Почему» самоописательны.
|
|
||||||
Дешевле всего, но копия теряет указание, по каким правилам её править.
|
|
||||||
- **Возить обвязку вместе с конвенциями.** Тогда `LANGUAGE.md` и, возможно,
|
|
||||||
`GUIDE.md` появляются в `docs/conventions/` как ещё одни синхронизируемые
|
|
||||||
файлы. Честно, но противоречит нынешнему разделению «канон — конвенции,
|
|
||||||
корень — обвязка» и добавляет в репозиторий текст, который агенту при
|
|
||||||
чтении конвенции не нужен.
|
|
||||||
- **Вкладывать короткую преамбулу в собранный файл.** Сборщик пишет в шапку
|
|
||||||
три-четыре строки: что такое модальное слово, что «Почему» обязательно,
|
|
||||||
где лежит полный документ. Самодостаточно и не тащит весь язык, но
|
|
||||||
преамбула дублируется в каждом файле темы.
|
|
||||||
|
|
||||||
Появился четвёртый вариант, и он выглядит лучше трёх: **boilerplate-строка
|
|
||||||
как в RFC 8174**. Каждая конвенция несёт одну фразу — «ключевые слова …
|
|
||||||
толкуются как описано в „Языке конвенций“ версии 1 — тогда и только тогда,
|
|
||||||
когда написаны заглавными». Пути нет, документа рядом нет, а норму исполнить
|
|
||||||
можно: строка сама несёт и словарь, и правило капса. Разбирается в заходе
|
|
||||||
про язык записи, вместе с версией — она же цепляет вопрос 9.
|
|
||||||
|
|
||||||
Сопутствующее: `GUIDE.md` в телах конвенций не упоминается ни разу —
|
|
||||||
проверено, так что вопрос только про `LANGUAGE.md`.
|
|
||||||
|
|
||||||
## 2. Тулинг: две разные задачи в одном `conv`
|
## 2. Тулинг: две разные задачи в одном `conv`
|
||||||
|
|
||||||
@@ -144,11 +120,12 @@ META-21 предлагает заменить путь на имя темы —
|
|||||||
|
|
||||||
Проверка перед вложением в тулинг сделана. По слоям:
|
Проверка перед вложением в тулинг сделана. По слоям:
|
||||||
|
|
||||||
- **Язык записи** — велосипед, но собранный из проверенных деталей: словарь
|
- **Язык записи** — совпал со стандартами почти во всём: шкала и правило
|
||||||
совпадает с RFC 2119/8174 вплоть до правила «нормативен только капс»,
|
«нормативно только заглавное» — BCP 14, обязательное обоснование и
|
||||||
обязательное «Почему» — дисциплина из requirements engineering (ISO/IEC/IEEE
|
единичность нормы — ISO/IEC/IEEE 29148, категории — ISO/IEC Directives
|
||||||
29148), стабильные идентификаторы — из semgrep/ESLint. Менять архитектуру
|
Part 2, таблицы решений — DMN, стабильные идентификаторы — semgrep/ESLint.
|
||||||
нечего, остались шесть точечных дельт — отдельным заходом.
|
Шесть точечных дельт применены, опора на источники записана в `LANGUAGE.md`
|
||||||
|
разделом «Опора на стандарты».
|
||||||
- **Оси и сборка** — аналога не нашлось. Ближайшие соседи (каскад `extends`
|
- **Оси и сборка** — аналога не нашлось. Ближайшие соседи (каскад `extends`
|
||||||
в ESLint, слои стилей Vale) дают праву слоя **отменять** базу; наш запрет
|
в ESLint, слои стилей Vale) дают праву слоя **отменять** базу; наш запрет
|
||||||
строже, и это содержательная часть. Вкладываться сюда.
|
строже, и это содержательная часть. Вкладываться сюда.
|
||||||
@@ -175,19 +152,28 @@ META-21 предлагает заменить путь на имя темы —
|
|||||||
манифеста, и `vendir.yml` — как пример того, где проходит граница между
|
манифеста, и `vendir.yml` — как пример того, где проходит граница между
|
||||||
«чего хочу» и «что получил».
|
«чего хочу» и «что получил».
|
||||||
|
|
||||||
## 8. Мультиязычность ключевых слов
|
## 8. Мультиязычность ключевых слов — закрыто по механике
|
||||||
|
|
||||||
Модальные слова сейчас русские, и это осознанно: разный словарь держит
|
Вопрос был поставлен как «нужен ли английский набор параллельно русскому».
|
||||||
границу «конвенция — не спецификация» бесплатно. Вопрос — нужен ли
|
Ответ оказался другой формы: словарь — **параметр естественного языка
|
||||||
английский набор параллельно.
|
набора**, а не часть языка конвенций. Шкала из пяти ступеней инвариантна,
|
||||||
|
слова под неё подбираются: для английского готовый словарь даёт BCP 14, для
|
||||||
|
любого другого языка слова берут из перевода стандарта или переводят сами.
|
||||||
|
|
||||||
За: канон может однажды понадобиться на английском; агенты натренированы на
|
Отсюда следствия, снимающие исходный вопрос:
|
||||||
MUST/SHOULD плотнее, чем на ДОЛЖЕН/СЛЕДУЕТ. Против: два набора — это два
|
|
||||||
способа записать одно, и проверка «модальные слова не встречаются вне
|
|
||||||
правил» усложняется вдвое.
|
|
||||||
|
|
||||||
Если делать, то таблица ключевых слов должна принадлежать **описанию
|
- **параллельных наборов не бывает.** Словарь один на канон: два словаря
|
||||||
языка**, а не каждой конвенции — то есть вопрос завязан на следующий.
|
дают две формы записи одного требования и удваивают каждую проверку;
|
||||||
|
- **версия языка при смене словаря не меняется** — версия принадлежит шкале
|
||||||
|
и правилам формы, а не буквам. Прежняя оценка «английский набор = версия 2»
|
||||||
|
неверна;
|
||||||
|
- **`SHALL` не берётся ни в одном словаре**, потому что занято OpenSpec; для
|
||||||
|
английского это выбор в пользу `MUST` из BCP 14, а не `shall` из ISO;
|
||||||
|
- отметка о механизации стандартом не даётся ни в одном языке и подбирается
|
||||||
|
так же, как остальные слова (`МЕХАНИЗИРОВАНО` / `MECHANIZED`).
|
||||||
|
|
||||||
|
Открытым остаётся только прикладное: понадобится ли этому канону английская
|
||||||
|
версия вообще. Механика для неё уже описана, заводить заранее нечего.
|
||||||
|
|
||||||
## 9. Описание языка отдельно от набора конвенций
|
## 9. Описание языка отдельно от набора конвенций
|
||||||
|
|
||||||
@@ -207,12 +193,14 @@ MUST/SHOULD плотнее, чем на ДОЛЖЕН/СЛЕДУЕТ. Проти
|
|||||||
Цена — ещё одна сущность и ещё одна синхронизация. Проверить, не выйдет ли
|
Цена — ещё одна сущность и ещё одна синхронизация. Проверить, не выйдет ли
|
||||||
лечение хуже болезни при одном пользователе.
|
лечение хуже болезни при одном пользователе.
|
||||||
|
|
||||||
Оценка выросла: у выноса появилась вторая, независимая причина. Boilerplate-
|
Срочность снята: версия появилась у `LANGUAGE.md` (ключ `version:` в шапке),
|
||||||
строка из вопроса 1 обязана назвать язык **с версией** — иначе она врёт при
|
и boilerplate-строка из вопроса 1 уже ссылается на язык номером, а не путём —
|
||||||
первом же изменении словаря. Версия предполагает документ, у которого версия
|
не дожидаясь выноса. Отдельный репозиторий остаётся вопросом второго набора
|
||||||
бывает, то есть отдельный от набора. Так IETF и решил ровно эту задачу:
|
конвенций, а не вопросом самодостаточности копии.
|
||||||
RFC 2119 — самостоятельный документ, на который спецификации ссылаются
|
|
||||||
номером, а не путём.
|
Что осталось поводом: из одного описания по-прежнему нельзя собрать второй
|
||||||
|
набор, и тулинг валидирует правила, зашитые в код, а не объявленную версию
|
||||||
|
языка. Оба повода включаются, только когда появится второй набор.
|
||||||
|
|
||||||
## 10. Тулинг на Go, живущий независимо
|
## 10. Тулинг на Go, живущий независимо
|
||||||
|
|
||||||
@@ -241,15 +229,16 @@ Go-бинарь со своим релизным циклом, ставить ч
|
|||||||
никуда не ведёт — правило рядом. Ограничение META-20 писалось именно про
|
никуда не ведёт — правило рядом. Ограничение META-20 писалось именно про
|
||||||
**чужую тему**, так что формально это уже разрешено.
|
**чужую тему**, так что формально это уже разрешено.
|
||||||
|
|
||||||
Но стоит проговорить явно, потому что сейчас читается уже как запрет:
|
Формулировка проверки исправлена: в `LANGUAGE.md` теперь «префикс **чужой
|
||||||
|
темы** не встречается в абзаце с модальностью», и там же сказано, что
|
||||||
|
префикс своего базового слоя допустим. Ложного срабатывания на `GTIM` →
|
||||||
|
`TIME-3` больше нет.
|
||||||
|
|
||||||
- в `LANGUAGE.md` проверка сформулирована как «**чужой префикс** не
|
Осталось решить одно: добавлять ли в META-20 явную строку **ДОПУСКАЕТСЯ**
|
||||||
встречается в абзаце с модальностью» — по букве это ловит и `GTIM` →
|
про родительский слой. За — правило, которое читают строже, чем оно есть,
|
||||||
`TIME-3`, то есть ложно срабатывает на ровно том случае, который
|
заставляет авторов дублировать текст без нужды. Против — норма META-20 уже
|
||||||
разрешён. Должно быть «префикс **чужой темы**»;
|
говорит «чужой темы», и второе правило про то же место придётся держать
|
||||||
- обсудить, не добавить ли в META-20 явную строку **ДОПУСКАЕТСЯ** про
|
согласованным с первым.
|
||||||
родительский слой: правило, которое читают как более строгое, чем оно
|
|
||||||
есть, заставляет авторов дублировать текст без нужды.
|
|
||||||
|
|
||||||
## Из вчерашнего, не закрыто
|
## Из вчерашнего, не закрыто
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,11 @@ prefix: DIRS
|
|||||||
создания и ценности содержимого: конфигурация, данные, кеш. Категория сразу
|
создания и ценности содержимого: конфигурация, данные, кеш. Категория сразу
|
||||||
отвечает на два вопроса, которые иначе выясняются чтением кода приложения:
|
отвечает на два вопроса, которые иначе выясняются чтением кода приложения:
|
||||||
**кто создаёт** содержимое и **что будет, если его потерять**. Из категорий
|
**кто создаёт** содержимое и **что будет, если его потерять**. Из категорий
|
||||||
механически выводится состав бэкапа. Форма записи — `LANGUAGE.md`.
|
механически выводится состав бэкапа.
|
||||||
|
|
||||||
|
Ключевые слова ДОЛЖЕН, НЕ ДОЛЖЕН, СЛЕДУЕТ, НЕ СЛЕДУЕТ, ДОПУСКАЕТСЯ и отметка
|
||||||
|
МЕХАНИЗИРОВАНО толкуются как описано в языке конвенций версии 1 — тогда и
|
||||||
|
только тогда, когда написаны заглавными.
|
||||||
|
|
||||||
## Область действия
|
## Область действия
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,11 @@ prefix: CONF
|
|||||||
# Конфигурация приложения
|
# Конфигурация приложения
|
||||||
|
|
||||||
Как устроена конфигурация: где лежит, как попадает в процесс, что с
|
Как устроена конфигурация: где лежит, как попадает в процесс, что с
|
||||||
секретами и когда падает. Форма записи — `LANGUAGE.md`.
|
секретами и когда падает.
|
||||||
|
|
||||||
|
Ключевые слова ДОЛЖЕН, НЕ ДОЛЖЕН, СЛЕДУЕТ, НЕ СЛЕДУЕТ, ДОПУСКАЕТСЯ и отметка
|
||||||
|
МЕХАНИЗИРОВАНО толкуются как описано в языке конвенций версии 1 — тогда и
|
||||||
|
только тогда, когда написаны заглавными.
|
||||||
|
|
||||||
## Область действия
|
## Область действия
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,11 @@ prefix: KEYS
|
|||||||
|
|
||||||
# Идентификаторы сущностей
|
# Идентификаторы сущностей
|
||||||
|
|
||||||
Как выбираются и как выглядят первичные ключи сущностей. Форма записи —
|
Как выбираются и как выглядят первичные ключи сущностей.
|
||||||
`LANGUAGE.md`.
|
|
||||||
|
Ключевые слова ДОЛЖЕН, НЕ ДОЛЖЕН, СЛЕДУЕТ, НЕ СЛЕДУЕТ, ДОПУСКАЕТСЯ и отметка
|
||||||
|
МЕХАНИЗИРОВАНО толкуются как описано в языке конвенций версии 1 — тогда и
|
||||||
|
только тогда, когда написаны заглавными.
|
||||||
|
|
||||||
## Область действия
|
## Область действия
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,11 @@ prefix: TIME
|
|||||||
# Время
|
# Время
|
||||||
|
|
||||||
Как приложение записывает моменты и длительности: в каком формате, откуда
|
Как приложение записывает моменты и длительности: в каком формате, откуда
|
||||||
берётся значение и где появляется не-UTC. Форма записи —
|
берётся значение и где появляется не-UTC.
|
||||||
`LANGUAGE.md`.
|
|
||||||
|
Ключевые слова ДОЛЖЕН, НЕ ДОЛЖЕН, СЛЕДУЕТ, НЕ СЛЕДУЕТ, ДОПУСКАЕТСЯ и отметка
|
||||||
|
МЕХАНИЗИРОВАНО толкуются как описано в языке конвенций версии 1 — тогда и
|
||||||
|
только тогда, когда написаны заглавными.
|
||||||
|
|
||||||
## Область действия
|
## Область действия
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,11 @@ extends: arch/config.md
|
|||||||
# Конфигурация: реализация на Go
|
# Конфигурация: реализация на Go
|
||||||
|
|
||||||
Как базовый слой выглядит в Go-приложении: формат, загрузчик, границы
|
Как базовый слой выглядит в Go-приложении: формат, загрузчик, границы
|
||||||
запрета на окружение. Форма записи — `LANGUAGE.md`.
|
запрета на окружение.
|
||||||
|
|
||||||
|
Ключевые слова ДОЛЖЕН, НЕ ДОЛЖЕН, СЛЕДУЕТ, НЕ СЛЕДУЕТ, ДОПУСКАЕТСЯ и отметка
|
||||||
|
МЕХАНИЗИРОВАНО толкуются как описано в языке конвенций версии 1 — тогда и
|
||||||
|
только тогда, когда написаны заглавными.
|
||||||
|
|
||||||
Секретов Go-специфика не касается: они приходят из деплоя уже в файле, а
|
Секретов Go-специфика не касается: они приходят из деплоя уже в файле, а
|
||||||
проверка их непустоты идёт вместе с остальной валидацией — как описано в
|
проверка их непустоты идёт вместе с остальной валидацией — как описано в
|
||||||
|
|||||||
@@ -5,8 +5,11 @@ extends: arch/db-identifiers.md
|
|||||||
|
|
||||||
# Идентификаторы: реализация на Go
|
# Идентификаторы: реализация на Go
|
||||||
|
|
||||||
Как базовый слой выглядит в Go-приложении. Форма записи —
|
Как базовый слой выглядит в Go-приложении.
|
||||||
`LANGUAGE.md`.
|
|
||||||
|
Ключевые слова ДОЛЖЕН, НЕ ДОЛЖЕН, СЛЕДУЕТ, НЕ СЛЕДУЕТ, ДОПУСКАЕТСЯ и отметка
|
||||||
|
МЕХАНИЗИРОВАНО толкуются как описано в языке конвенций версии 1 — тогда и
|
||||||
|
только тогда, когда написаны заглавными.
|
||||||
|
|
||||||
Единая точка из `KEYS-3` — пакет `internal/ident`: он
|
Единая точка из `KEYS-3` — пакет `internal/ident`: он
|
||||||
порождает идентификаторы (`NewID`, `NewIDAt`) и он же их разбирает
|
порождает идентификаторы (`NewID`, `NewIDAt`) и он же их разбирает
|
||||||
|
|||||||
@@ -5,7 +5,11 @@ prefix: MIGR
|
|||||||
# Схема и миграции (SQLite, Go)
|
# Схема и миграции (SQLite, Go)
|
||||||
|
|
||||||
Как пишутся миграции и какие типы колонок выбираются для схемы SQLite в
|
Как пишутся миграции и какие типы колонок выбираются для схемы SQLite в
|
||||||
Go-приложении. Форма записи — `LANGUAGE.md`.
|
Go-приложении.
|
||||||
|
|
||||||
|
Ключевые слова ДОЛЖЕН, НЕ ДОЛЖЕН, СЛЕДУЕТ, НЕ СЛЕДУЕТ, ДОПУСКАЕТСЯ и отметка
|
||||||
|
МЕХАНИЗИРОВАНО толкуются как описано в языке конвенций версии 1 — тогда и
|
||||||
|
только тогда, когда написаны заглавными.
|
||||||
|
|
||||||
## Область действия
|
## Область действия
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,13 @@ prefix: GERR
|
|||||||
|
|
||||||
# Ошибки
|
# Ошибки
|
||||||
|
|
||||||
Как ошибки строятся, оборачиваются и проверяются. Форма записи —
|
Как ошибки строятся, оборачиваются и проверяются. Где и когда ошибку
|
||||||
`LANGUAGE.md`. Где и когда ошибку **логировать** — в конвенции `logging`
|
**логировать** — в конвенции `logging` (коротко: лог один раз на доменной
|
||||||
(коротко: лог один раз на доменной границе).
|
границе).
|
||||||
|
|
||||||
|
Ключевые слова ДОЛЖЕН, НЕ ДОЛЖЕН, СЛЕДУЕТ, НЕ СЛЕДУЕТ, ДОПУСКАЕТСЯ и отметка
|
||||||
|
МЕХАНИЗИРОВАНО толкуются как описано в языке конвенций версии 1 — тогда и
|
||||||
|
только тогда, когда написаны заглавными.
|
||||||
|
|
||||||
Две границы, о которых говорят правила ниже:
|
Две границы, о которых говорят правила ниже:
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,11 @@ extends: arch/time.md
|
|||||||
|
|
||||||
Как и когда писать логи. Это правила оформления кода (How), а не
|
Как и когда писать логи. Это правила оформления кода (How), а не
|
||||||
спецификация поведения: наблюдаемые требования к логам, входящие в контракт
|
спецификация поведения: наблюдаемые требования к логам, входящие в контракт
|
||||||
функциональности, живут в спеках. Форма записи — `LANGUAGE.md`.
|
функциональности, живут в спеках.
|
||||||
|
|
||||||
|
Ключевые слова ДОЛЖЕН, НЕ ДОЛЖЕН, СЛЕДУЕТ, НЕ СЛЕДУЕТ, ДОПУСКАЕТСЯ и отметка
|
||||||
|
МЕХАНИЗИРОВАНО толкуются как описано в языке конвенций версии 1 — тогда и
|
||||||
|
только тогда, когда написаны заглавными.
|
||||||
|
|
||||||
Лог читают инструментами, а не глазами: повседневно — `jq`
|
Лог читают инструментами, а не глазами: повседневно — `jq`
|
||||||
(`jq 'select(.download_id=="a1b2")' app.jsonl`), тяжёлое (агрегации, JOIN) —
|
(`jq 'select(.download_id=="a1b2")' app.jsonl`), тяжёлое (агрегации, JOIN) —
|
||||||
|
|||||||
@@ -5,9 +5,12 @@ extends: arch/time.md
|
|||||||
|
|
||||||
# Время: реализация на Go
|
# Время: реализация на Go
|
||||||
|
|
||||||
Как требования базового слоя выполняются в Go-коде: откуда берётся
|
Как требования базового слоя выполняются в Go-коде: откуда берётся «сейчас»,
|
||||||
«сейчас», в каком виде время попадает в базу и в логи, что делать с зонами.
|
в каком виде время попадает в базу и в логи, что делать с зонами.
|
||||||
Форма записи — `LANGUAGE.md`.
|
|
||||||
|
Ключевые слова ДОЛЖЕН, НЕ ДОЛЖЕН, СЛЕДУЕТ, НЕ СЛЕДУЕТ, ДОПУСКАЕТСЯ и отметка
|
||||||
|
МЕХАНИЗИРОВАНО толкуются как описано в языке конвенций версии 1 — тогда и
|
||||||
|
только тогда, когда написаны заглавными.
|
||||||
|
|
||||||
## Правила
|
## Правила
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,11 @@ extends: arch/app-directories.md
|
|||||||
|
|
||||||
# Категории директорий: реализация в Ansible
|
# Категории директорий: реализация в Ansible
|
||||||
|
|
||||||
Как категории из базового слоя раскладываются на сервере
|
Как категории из базового слоя раскладываются на сервере плейбуком.
|
||||||
плейбуком. Форма записи — `LANGUAGE.md`.
|
|
||||||
|
Ключевые слова ДОЛЖЕН, НЕ ДОЛЖЕН, СЛЕДУЕТ, НЕ СЛЕДУЕТ, ДОПУСКАЕТСЯ и отметка
|
||||||
|
МЕХАНИЗИРОВАНО толкуются как описано в языке конвенций версии 1 — тогда и
|
||||||
|
только тогда, когда написаны заглавными.
|
||||||
|
|
||||||
## Область действия
|
## Область действия
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,13 @@ prefix: HTMX
|
|||||||
|
|
||||||
# Веб-UI на htmx
|
# Веб-UI на htmx
|
||||||
|
|
||||||
Как пишется код веб-UI: частичный своп фрагментов, поллинг живых
|
Как пишется код веб-UI: частичный своп фрагментов, поллинг живых обновлений,
|
||||||
обновлений, обработчики действий, деградация без JS, ошибки. Что именно UI
|
обработчики действий, деградация без JS, ошибки. Что именно UI показывает и
|
||||||
показывает и какие действия поддерживает — в спеках, не здесь. Форма записи
|
какие действия поддерживает — в спеках, не здесь.
|
||||||
— `LANGUAGE.md`.
|
|
||||||
|
Ключевые слова ДОЛЖЕН, НЕ ДОЛЖЕН, СЛЕДУЕТ, НЕ СЛЕДУЕТ, ДОПУСКАЕТСЯ и отметка
|
||||||
|
МЕХАНИЗИРОВАНО толкуются как описано в языке конвенций версии 1 — тогда и
|
||||||
|
только тогда, когда написаны заглавными.
|
||||||
|
|
||||||
Логирование запросов — конвенция `logging` (HTTP-поля, рутинно-частое на
|
Логирование запросов — конвенция `logging` (HTTP-поля, рутинно-частое на
|
||||||
`DEBUG`). Трансляция доменных ошибок наружу — конвенция `errors`
|
`DEBUG`). Трансляция доменных ошибок наружу — конвенция `errors`
|
||||||
|
|||||||
Reference in New Issue
Block a user