язык: объявлена граница правила
- область правила — от его заголовка до следующего заголовка любого уровня; метка открывает блок, хвост после ПОЧЕМУ — продолжение обоснования, а таблица после модальной метки — часть нормы - проверка «заглавных модальных слов вне правил нет» стала реализуемой: прозой считается то, что лежит вне областей правил - нормы, сидевшие в хвостах, подняты в блок нормы: заведены SLOG-25.4 и GERR-26.3, у GTIM-12 «базовый слой» заменён на TIME-12
This commit is contained in:
@@ -21,6 +21,11 @@ code in this repository.
|
|||||||
`**МОДАЛЬНОСТЬ.** норма`, абзац `**ПОЧЕМУ.** …`. Правило без обоснования не
|
`**МОДАЛЬНОСТЬ.** норма`, абзац `**ПОЧЕМУ.** …`. Правило без обоснования не
|
||||||
принимается.
|
принимается.
|
||||||
- Норма — одна фраза; если в неё не влезает, это два правила.
|
- Норма — одна фраза; если в неё не влезает, это два правила.
|
||||||
|
- Область правила — от его заголовка до следующего заголовка любого уровня;
|
||||||
|
метка открывает блок, блок длится до следующей метки или до конца области.
|
||||||
|
Абзацы после `**ПОЧЕМУ.**` — продолжение обоснования: требований в них не
|
||||||
|
живёт, требование ставят в блок нормы. Таблица и список после модальной
|
||||||
|
метки — часть нормы.
|
||||||
- Шкала инвариантна, словарь — параметр языка набора. Канон русский, значит
|
- Шкала инвариантна, словарь — параметр языка набора. Канон русский, значит
|
||||||
слова: **ДОЛЖЕН**, **НЕ ДОЛЖЕН**, **СЛЕДУЕТ**, **НЕ СЛЕДУЕТ**,
|
слова: **ДОЛЖЕН**, **НЕ ДОЛЖЕН**, **СЛЕДУЕТ**, **НЕ СЛЕДУЕТ**,
|
||||||
**ДОПУСКАЕТСЯ**. Словарь один на канон, синонимов на ступень нет.
|
**ДОПУСКАЕТСЯ**. Словарь один на канон, синонимов на ступень нет.
|
||||||
|
|||||||
+50
-3
@@ -92,6 +92,45 @@ version: 1
|
|||||||
принадлежат словарю набора: скелет правила читается одинаково в любом языке,
|
принадлежат словарю набора: скелет правила читается одинаково в любом языке,
|
||||||
на который канон переведён.
|
на который канон переведён.
|
||||||
|
|
||||||
|
**Правило кончается перед следующим заголовком.** Область правила — от его
|
||||||
|
заголовка до следующего заголовка любого уровня. Внутри области текст
|
||||||
|
принадлежит последнему открытому блоку: метка блок открывает, и блок длится
|
||||||
|
до следующей метки или до конца области.
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
### XKEY-3. Заголовок правила
|
||||||
|
|
||||||
|
**ДОЛЖЕН.** Норма одной фразой.
|
||||||
|
|
||||||
|
| № | ситуация | вердикт | ← блок нормы: таблица уточняет её
|
||||||
|
|
||||||
|
**ПОЧЕМУ.** Причина.
|
||||||
|
|
||||||
|
Продолжение причины, пример, ← блок обоснования продолжается
|
||||||
|
ссылка на внешнюю практику.
|
||||||
|
|
||||||
|
### XKEY-4. Следующее правило ← здесь область кончилась
|
||||||
|
```
|
||||||
|
|
||||||
|
Отсюда три следствия:
|
||||||
|
|
||||||
|
- **Хвост после ПОЧЕМУ — обоснование**, а не безымянная часть правила и не
|
||||||
|
проза вокруг. Требований в нём не живёт: то, что подлежит исполнению, стоит
|
||||||
|
в блоке нормы, где у него есть модальность и адрес. Требование, оставленное
|
||||||
|
в хвосте, требованием не является — сослаться на него нельзя и отступление
|
||||||
|
от него записать нельзя.
|
||||||
|
- **Таблица и список после модальной метки — часть нормы.** Правило,
|
||||||
|
классифицирующее ситуации, ровно так и записывается («Таблицы решений»), а
|
||||||
|
вердикт из такой таблицы адресуется номером строки.
|
||||||
|
- **Проза — это то, что лежит вне областей правил.** Тем самым проверка
|
||||||
|
«заглавных модальных слов вне правил нет» становится реализуемой: границу
|
||||||
|
считает разметка, а не читательское суждение о том, где правило кончилось.
|
||||||
|
|
||||||
|
Заглавное модальное слово внутри области правила законно, когда это
|
||||||
|
упоминание ступени в обосновании («для СЛЕДУЕТ это честно»). Метку от
|
||||||
|
упоминания отличает положение: метка стоит первой в своём абзаце, полужирным
|
||||||
|
и с точкой.
|
||||||
|
|
||||||
## Обоснование обязательно
|
## Обоснование обязательно
|
||||||
|
|
||||||
Правило без блока ПОЧЕМУ не принимается. Это требование к форме, а не
|
Правило без блока ПОЧЕМУ не принимается. Это требование к форме, а не
|
||||||
@@ -378,6 +417,10 @@ Directives, Part 2, по одной форме записи на ступень,
|
|||||||
- **Локальная часть копии** — содержимое принадлежит репозиторию.
|
- **Локальная часть копии** — содержимое принадлежит репозиторию.
|
||||||
- Вводная проза, объясняющая предмет конвенции.
|
- Вводная проза, объясняющая предмет конвенции.
|
||||||
|
|
||||||
|
Все четыре части лежат вне областей правил: до первого заголовка правила или
|
||||||
|
после заголовка, которым область закрылась. Хвост обоснования сюда не
|
||||||
|
относится — он внутри правила, и модальные слова в нём законны как упоминания.
|
||||||
|
|
||||||
## Как на правила ссылаются копии
|
## Как на правила ссылаются копии
|
||||||
|
|
||||||
Ниже маркера локальной части, в репозитории:
|
Ниже маркера локальной части, в репозитории:
|
||||||
@@ -416,8 +459,11 @@ MIGR-6 не соблюдается в легаси-таблицах `show_histor
|
|||||||
- ссылки вида `<ПРЕФИКС>-<n>` — хоть в тексте канона, хоть в локальной части
|
- ссылки вида `<ПРЕФИКС>-<n>` — хоть в тексте канона, хоть в локальной части
|
||||||
копии — указывают на правила, которые ещё существуют;
|
копии — указывают на правила, которые ещё существуют;
|
||||||
- префиксы локальных правил копии начинаются на `X`;
|
- префиксы локальных правил копии начинаются на `X`;
|
||||||
- заглавные модальные слова не встречаются вне правил — кроме строки о
|
- заглавные модальные слова не встречаются вне областей правил (область —
|
||||||
версии языка, которая их перечисляет по назначению;
|
от заголовка правила до следующего заголовка) — кроме строки о версии
|
||||||
|
языка, которая их перечисляет по назначению;
|
||||||
|
- модальная метка стоит первой в своём абзаце: заглавное слово в середине
|
||||||
|
фразы — упоминание ступени, а не вторая норма правила;
|
||||||
- префикс **чужой темы** не встречается в абзаце с модальностью (META-20);
|
- префикс **чужой темы** не встречается в абзаце с модальностью (META-20);
|
||||||
префикс арх-слоя своей темы там допустим (META-24), префикс другого языка
|
префикс арх-слоя своей темы там допустим (META-24), префикс другого языка
|
||||||
или стека — нет;
|
или стека — нет;
|
||||||
@@ -428,7 +474,8 @@ MIGR-6 не соблюдается в легаси-таблицах `show_histor
|
|||||||
- строки таблицы взаимоисключающи либо политика совпадения объявлена;
|
- строки таблицы взаимоисключающи либо политика совпадения объявлена;
|
||||||
- перечисленные в таблице случаи покрывают область действия;
|
- перечисленные в таблице случаи покрывают область действия;
|
||||||
- норма исполнима без обращения к другим файлам;
|
- норма исполнима без обращения к другим файлам;
|
||||||
- обоснование отвечает на «что сломается», а не пересказывает норму.
|
- обоснование отвечает на «что сломается», а не пересказывает норму;
|
||||||
|
- хвост обоснования не вводит требований, которых нет в блоке нормы.
|
||||||
|
|
||||||
## Версия языка
|
## Версия языка
|
||||||
|
|
||||||
|
|||||||
@@ -4,32 +4,12 @@
|
|||||||
решения. Закрытый вопрос отсюда удаляется — принятое решение живёт в
|
решения. Закрытый вопрос отсюда удаляется — принятое решение живёт в
|
||||||
`README.md`, `GUIDE.md` или `LANGUAGE.md`, а не в этом файле.
|
`README.md`, `GUIDE.md` или `LANGUAGE.md`, а не в этом файле.
|
||||||
|
|
||||||
Две секции: сначала язык и подход, потом канон с тулингом. Пункты 1–8
|
Две секции: сначала язык и подход, потом канон с тулингом. Пункты 1–7
|
||||||
пришли из внешнего ревью описания языка и проверены по файлам на месте.
|
пришли из внешнего ревью описания языка и проверены по файлам на месте.
|
||||||
|
|
||||||
# Язык и подход
|
# Язык и подход
|
||||||
|
|
||||||
## 1. Граница правила не определена
|
## 1. Примеры в LANGUAGE.md сидят на живых идентификаторах
|
||||||
|
|
||||||
Форма объявляет четыре части, но почти каждое крупное правило несёт абзацы
|
|
||||||
**после** блока ПОЧЕМУ: KEYS-5, SLOG-25, MIGR-11, GERR-26. Язык не говорит,
|
|
||||||
чем эти абзацы являются — частью правила, продолжением обоснования или
|
|
||||||
вводной прозой, где заглавные модальные слова запрещены.
|
|
||||||
|
|
||||||
В хвостах прячутся настоящие нормы без модальности и без адреса: у SLOG-25 —
|
|
||||||
«логируется `ERROR` с признаком непокрытой», у GERR-26 — «Продолжать, не
|
|
||||||
исключив упавший элемент, нельзя». Это ровно тот неадресуемый текст, против
|
|
||||||
которого язык построен: сослаться нельзя, отступление записать нельзя.
|
|
||||||
|
|
||||||
Побочно это блокирует главную машинную проверку. «Заглавные модальные слова
|
|
||||||
не встречаются вне правил» нереализуема, пока не сказано, где правило
|
|
||||||
кончается: парсер «от `###` до следующего заголовка» включит хвосты, парсер
|
|
||||||
«две метки и всё» объявит хвосты прозой и покраснеет на законных пояснениях.
|
|
||||||
|
|
||||||
Решить надо две вещи: где кончается правило и что делать с нормами, которые
|
|
||||||
уже сидят в хвостах.
|
|
||||||
|
|
||||||
## 2. Примеры в LANGUAGE.md сидят на живых идентификаторах
|
|
||||||
|
|
||||||
Учебные примеры используют настоящие префиксы канона с номерами, которые в
|
Учебные примеры используют настоящие префиксы канона с номерами, которые в
|
||||||
каноне означают другое:
|
каноне означают другое:
|
||||||
@@ -48,7 +28,7 @@
|
|||||||
Лечится дёшево: примеры берут префиксы на `X`, зарезервированные как раз под
|
Лечится дёшево: примеры берут префиксы на `X`, зарезервированные как раз под
|
||||||
то, что каноном не занято.
|
то, что каноном не занято.
|
||||||
|
|
||||||
## 3. «Тема» — несущий идентификатор без определения и реестра
|
## 2. «Тема» — несущий идентификатор без определения и реестра
|
||||||
|
|
||||||
META-21 велит ссылаться на соседнюю конвенцию именем темы, манифест
|
META-21 велит ссылаться на соседнюю конвенцию именем темы, манифест
|
||||||
подписывается `topics = ["time", …]`, сборка собирает файл темы из слоёв —
|
подписывается `topics = ["time", …]`, сборка собирает файл темы из слоёв —
|
||||||
@@ -61,13 +41,13 @@ META-21 велит ссылаться на соседнюю конвенцию
|
|||||||
файла темы тихо осиротит все текстовые ссылки во всех копиях.
|
файла темы тихо осиротит все текстовые ссылки во всех копиях.
|
||||||
|
|
||||||
Вопрос уже не гипотетический: пара `arch/db-identifiers.md` против
|
Вопрос уже не гипотетический: пара `arch/db-identifiers.md` против
|
||||||
`lang/go/db-schema.md` (см. вопрос 12) показывает, что имена слоёв одной
|
`lang/go/db-schema.md` (см. вопрос 11) показывает, что имена слоёв одной
|
||||||
темы могут не совпадать. Смежно: `extends: arch/time.md` у SLOG ломает
|
темы могут не совпадать. Смежно: `extends: arch/time.md` у SLOG ломает
|
||||||
гарантию META-24 («базовый слой отсутствовать не может») — она верна только
|
гарантию META-24 («базовый слой отсутствовать не может») — она верна только
|
||||||
для базы своей темы, а машинной проверке негде узнать тему, кроме имени
|
для базы своей темы, а машинной проверке негде узнать тему, кроме имени
|
||||||
файла.
|
файла.
|
||||||
|
|
||||||
## 4. GUIDE выведен из-под проверок ложным основанием
|
## 3. GUIDE выведен из-под проверок ложным основанием
|
||||||
|
|
||||||
`LANGUAGE.md` исключает обвязку из проверок формулировкой «она ключевые слова
|
`LANGUAGE.md` исключает обвязку из проверок формулировкой «она ключевые слова
|
||||||
цитирует, а не употребляет». Для `GUIDE.md` это неверно: META-правила
|
цитирует, а не употребляет». Для `GUIDE.md` это неверно: META-правила
|
||||||
@@ -83,7 +63,7 @@ META-21 велит ссылаться на соседнюю конвенцию
|
|||||||
Честнее развести: `GUIDE.md` язык **употребляет** и проверяется как
|
Честнее развести: `GUIDE.md` язык **употребляет** и проверяется как
|
||||||
конвенция, `LANGUAGE.md` и `README.md` — цитируют.
|
конвенция, `LANGUAGE.md` и `README.md` — цитируют.
|
||||||
|
|
||||||
## 5. МЕХАНИЗИРОВАНО не переживает нового подписчика
|
## 4. МЕХАНИЗИРОВАНО не переживает нового подписчика
|
||||||
|
|
||||||
META-8 запрещает удалять норму, пока механизирована не у всех, и защищает
|
META-8 запрещает удалять норму, пока механизирована не у всех, и защищает
|
||||||
тем самым потребителей, существующих **на момент удаления**. Будущих не
|
тем самым потребителей, существующих **на момент удаления**. Будущих не
|
||||||
@@ -101,7 +81,7 @@ META-8 запрещает удалять норму, пока механизир
|
|||||||
в тексте канона, то есть ровно то, что запрещает META-4. Либо это законное
|
в тексте канона, то есть ровно то, что запрещает META-4. Либо это законное
|
||||||
исключение, и тогда его надо назвать, либо конфликт.
|
исключение, и тогда его надо назвать, либо конфликт.
|
||||||
|
|
||||||
## 6. Семантика ключевых слов в копию не едет
|
## 5. Семантика ключевых слов в копию не едет
|
||||||
|
|
||||||
Строка о версии языка перечисляет слова, но не их значения, а всё
|
Строка о версии языка перечисляет слова, но не их значения, а всё
|
||||||
нетривиальное в шкале живёт только в `LANGUAGE.md`, который в репозиторий не
|
нетривиальное в шкале живёт только в `LANGUAGE.md`, который в репозиторий не
|
||||||
@@ -117,7 +97,7 @@ META-8 запрещает удалять норму, пока механизир
|
|||||||
копиями короткую выжимку семантики; расширить строку о версии до
|
копиями короткую выжимку семантики; расширить строку о версии до
|
||||||
двух-трёх предложений; или признать ограничение и записать его явно.
|
двух-трёх предложений; или признать ограничение и записать его явно.
|
||||||
|
|
||||||
## 7. Две «механические» проверки без источника данных
|
## 6. Две «механические» проверки без источника данных
|
||||||
|
|
||||||
В списке «разбором текста» стоят два пункта, которые без дополнительного
|
В списке «разбором текста» стоят два пункта, которые без дополнительного
|
||||||
реестра нерешаемы:
|
реестра нерешаемы:
|
||||||
@@ -133,7 +113,7 @@ META-8 запрещает удалять норму, пока механизир
|
|||||||
реестр снятых номеров не объявлен частью языка, оба пункта принадлежат
|
реестр снятых номеров не объявлен частью языка, оба пункта принадлежат
|
||||||
списку «чтением».
|
списку «чтением».
|
||||||
|
|
||||||
## 8. Натяжки в опоре на стандарты
|
## 7. Натяжки в опоре на стандарты
|
||||||
|
|
||||||
Три места, где источнику приписано чуть больше, чем в нём есть:
|
Три места, где источнику приписано чуть больше, чем в нём есть:
|
||||||
|
|
||||||
@@ -152,7 +132,7 @@ META-8 запрещает удалять норму, пока механизир
|
|||||||
Остальное в таблице проверку выдержало, включая вторую половину `MAY` из
|
Остальное в таблице проверку выдержало, включая вторую половину `MAY` из
|
||||||
BCP 14 и списки эквивалентных словесных форм ISO Directives.
|
BCP 14 и списки эквивалентных словесных форм ISO Directives.
|
||||||
|
|
||||||
## 9. Одиннадцать таблиц не прочитаны на взаимоисключительность
|
## 8. Одиннадцать таблиц не прочитаны на взаимоисключительность
|
||||||
|
|
||||||
`LANGUAGE.md` объявил, что строки таблицы решений взаимоисключающи по
|
`LANGUAGE.md` объявил, что строки таблицы решений взаимоисключающи по
|
||||||
умолчанию, а иной порядок объявляется явно. Объявление не делает таблицы
|
умолчанию, а иной порядок объявляется явно. Объявление не делает таблицы
|
||||||
@@ -167,7 +147,7 @@ BCP 14 и списки эквивалентных словесных форм IS
|
|||||||
Работа читательская, машине не даётся; в список проверок она уже записана в
|
Работа читательская, машине не даётся; в список проверок она уже записана в
|
||||||
разделе «Чтением, потому что машине не даётся».
|
разделе «Чтением, потому что машине не даётся».
|
||||||
|
|
||||||
## 10. Описание языка отдельно от набора конвенций
|
## 9. Описание языка отдельно от набора конвенций
|
||||||
|
|
||||||
`LANGUAGE.md` и `GUIDE.md` описывают, **как** пишутся конвенции;
|
`LANGUAGE.md` и `GUIDE.md` описывают, **как** пишутся конвенции;
|
||||||
`conventions/` — **один конкретный** набор. Сейчас они склеены в одном
|
`conventions/` — **один конкретный** набор. Сейчас они склеены в одном
|
||||||
@@ -190,7 +170,7 @@ BCP 14 и списки эквивалентных словесных форм IS
|
|||||||
|
|
||||||
# Канон, тулинг, подключение
|
# Канон, тулинг, подключение
|
||||||
|
|
||||||
## 11. Тулинг: две разные задачи в одном `conv`
|
## 10. Тулинг: две разные задачи в одном `conv`
|
||||||
|
|
||||||
Сейчас в `conv` смешаны две категории работы, и они расходятся по всему —
|
Сейчас в `conv` смешаны две категории работы, и они расходятся по всему —
|
||||||
по частоте запуска, по тому, кто запускает, и по тому, что считается
|
по частоте запуска, по тому, кто запускает, и по тому, что считается
|
||||||
@@ -221,22 +201,22 @@ BCP 14 и списки эквивалентных словесных форм IS
|
|||||||
ссылках: это установка, а не целостность, но список подписок ему нужен из
|
ссылках: это установка, а не целостность, но список подписок ему нужен из
|
||||||
манифеста.
|
манифеста.
|
||||||
|
|
||||||
Часть проверок из этого списка сейчас нереализуема по причинам из вопросов 1
|
Часть проверок из этого списка сейчас нереализуема по причине из вопроса 6,
|
||||||
и 7, так что порядок такой: сначала язык, потом чекер.
|
так что порядок такой: сначала язык, потом чекер.
|
||||||
|
|
||||||
Перед тем как переписывать, стоит посмотреть на два готовых прототипа:
|
Перед тем как переписывать, стоит посмотреть на два готовых прототипа:
|
||||||
дистрибуцию пакетов Vale (`.vale.ini` → `vale sync` → `styles/`) как образец
|
дистрибуцию пакетов Vale (`.vale.ini` → `vale sync` → `styles/`) как образец
|
||||||
манифеста и `vendir.yml` — как пример того, где проходит граница между «чего
|
манифеста и `vendir.yml` — как пример того, где проходит граница между «чего
|
||||||
хочу» и «что получил».
|
хочу» и «что получил».
|
||||||
|
|
||||||
## 12. Пары слоёв и темы без базы
|
## 11. Пары слоёв и темы без базы
|
||||||
|
|
||||||
Отложено сознательно, но список стоит держать перед глазами:
|
Отложено сознательно, но список стоит держать перед глазами:
|
||||||
|
|
||||||
- `SLOG` объявляет `extends: arch/time.md` — расширение **чужой** темы.
|
- `SLOG` объявляет `extends: arch/time.md` — расширение **чужой** темы.
|
||||||
Сборщик темы `logging` на это наткнётся: базового слоя с темой `logging`
|
Сборщик темы `logging` на это наткнётся: базового слоя с темой `logging`
|
||||||
нет, а `arch/time.md` он тянуть не должен. Чинится переводом в обычную
|
нет, а `arch/time.md` он тянуть не должен. Чинится переводом в обычную
|
||||||
ссылку «связано». Вдобавок это ломает гарантию META-24 — см. вопрос 3.
|
ссылку «связано». Вдобавок это ломает гарантию META-24 — см. вопрос 2.
|
||||||
- Темы без арх-слоя: `db-schema`, `errors`, `web-ui`. Собираются в файл с
|
- Темы без арх-слоя: `db-schema`, `errors`, `web-ui`. Собираются в файл с
|
||||||
одной секцией — само по себе не ломается, но это и есть тот невыделенный
|
одной секцией — само по себе не ломается, но это и есть тот невыделенный
|
||||||
арх-слой из известного долга.
|
арх-слой из известного долга.
|
||||||
@@ -248,7 +228,7 @@ BCP 14 и списки эквивалентных словесных форм IS
|
|||||||
- Вынос арх-ядра из `errors` и `logging` закроет две хрупкие ссылки из
|
- Вынос арх-ядра из `errors` и `logging` закроет две хрупкие ссылки из
|
||||||
`web-ui` (стек) в go-слой — единственные ссылки стек → язык в каноне.
|
`web-ui` (стек) в go-слой — единственные ссылки стек → язык в каноне.
|
||||||
|
|
||||||
## 13. Подключение к репозиториям
|
## 12. Подключение к репозиториям
|
||||||
|
|
||||||
Ничего ещё не подключено. Кандидаты — jellybit и pet-project-server.
|
Ничего ещё не подключено. Кандидаты — jellybit и pet-project-server.
|
||||||
Понадобится: заполнить локальную часть копий тем, что сейчас в этих
|
Понадобится: заполнить локальную часть копий тем, что сейчас в этих
|
||||||
@@ -257,7 +237,7 @@ BCP 14 и списки эквивалентных словесных форм IS
|
|||||||
строка в `AGENTS.md` каждого потребителя про то, что файлы в
|
строка в `AGENTS.md` каждого потребителя про то, что файлы в
|
||||||
`docs/conventions/` — копии.
|
`docs/conventions/` — копии.
|
||||||
|
|
||||||
## 14. Тулинг на Go, живущий независимо
|
## 13. Тулинг на Go, живущий независимо
|
||||||
|
|
||||||
Сейчас `conv` — питоновский скрипт внутри канона, то есть тулинг и данные в
|
Сейчас `conv` — питоновский скрипт внутри канона, то есть тулинг и данные в
|
||||||
одном репозитории и правятся одним движением. Мысль: вынести в отдельный
|
одном репозитории и правятся одним движением. Мысль: вынести в отдельный
|
||||||
@@ -266,10 +246,10 @@ Go-бинарь со своим релизным циклом, ставить ч
|
|||||||
|
|
||||||
Что за этим стоит помимо вкуса: независимый бинарь физически не даёт править
|
Что за этим стоит помимо вкуса: независимый бинарь физически не даёт править
|
||||||
инструмент «заодно» с правкой конвенции, работает против **любого** канона и
|
инструмент «заодно» с правкой конвенции, работает против **любого** канона и
|
||||||
любого потребителя — что прямо требуется вопросом 10, — и снимает питон из
|
любого потребителя — что прямо требуется вопросом 9, — и снимает питон из
|
||||||
зависимостей репозиториев-потребителей.
|
зависимостей репозиториев-потребителей.
|
||||||
|
|
||||||
Порядок обратный ожидаемому: пока вопрос 10 не сделан, инструмент всё равно
|
Порядок обратный ожидаемому: пока вопрос 9 не сделан, инструмент всё равно
|
||||||
работает против одного конкретного канона, и независимый релизный цикл ему
|
работает против одного конкретного канона, и независимый релизный цикл ему
|
||||||
нечего обслуживать. Сначала 10, потом 14. Разделение из вопроса 11 при этом
|
нечего обслуживать. Сначала 9, потом 13. Разделение из вопроса 10 при этом
|
||||||
дешевле заложить сразу, чем отпиливать потом.
|
дешевле заложить сразу, чем отпиливать потом.
|
||||||
|
|||||||
@@ -344,8 +344,9 @@ HTTP-клиентов, файловой системы, внешних SDK.
|
|||||||
|
|
||||||
| № | Где перехвачена паника | Что дальше |
|
| № | Где перехвачена паника | Что дальше |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| GERR-26.1 | обработчик HTTP-запроса | ответ 500, если он ещё не начат; процесс и прочие запросы не затрагиваются |
|
| GERR-26.1 | обработчик HTTP-запроса, паника любая, кроме сигнала намеренного прерывания | ответ 500, если он ещё не начат; процесс и прочие запросы не затрагиваются |
|
||||||
| GERR-26.2 | итерация цикла обработки — бот, воркер | цикл продолжается со следующего элемента, упавший элемент повторно не берётся |
|
| GERR-26.2 | итерация цикла обработки — бот, воркер | цикл продолжается со следующего элемента, упавший элемент повторно не берётся |
|
||||||
|
| GERR-26.3 | обработчик HTTP-запроса, паника — сигнал намеренного прерывания (`http.ErrAbortHandler`) | значение пробрасывается дальше, ответ не подменяется |
|
||||||
|
|
||||||
**ПОЧЕМУ.** Паника внутри обработки одного элемента почти всегда говорит о
|
**ПОЧЕМУ.** Паника внутри обработки одного элемента почти всегда говорит о
|
||||||
баге в работе с данными этого элемента, а не о порче общего состояния, —
|
баге в работе с данными этого элемента, а не о порче общего состояния, —
|
||||||
@@ -356,10 +357,11 @@ HTTP-клиентов, файловой системы, внешних SDK.
|
|||||||
обязательным (GERR-22): неперехваченная паника в любой горутине завершает весь
|
обязательным (GERR-22): неперехваченная паника в любой горутине завершает весь
|
||||||
процесс.
|
процесс.
|
||||||
|
|
||||||
Продолжать, не исключив упавший элемент, нельзя: детерминированная паника
|
Исключение упавшего элемента в GERR-26.2 — не осторожность, а условие
|
||||||
даёт бесконечный цикл — тот же элемент, тот же стек, залитый лог и нулевой
|
прогресса: детерминированная паника даёт бесконечный цикл — тот же элемент,
|
||||||
прогресс. Это классический poison message, и лекарство берём то же, что
|
тот же стек, залитый лог и нулевой прогресс. Это классический poison message,
|
||||||
принято в очередях: элемент выводится из оборота, а не берётся снова. У
|
и лекарство здесь то же, что принято в очередях: элемент выводится из
|
||||||
|
оборота, а не берётся снова. У
|
||||||
цикла, который и так подтверждает прогресс — сдвигает офсет, помечает
|
цикла, который и так подтверждает прогресс — сдвигает офсет, помечает
|
||||||
строку состоянием, — механизм для этого уже есть, заводить отдельный не
|
строку состоянием, — механизм для этого уже есть, заводить отдельный не
|
||||||
нужно.
|
нужно.
|
||||||
@@ -369,9 +371,10 @@ HTTP-клиентов, файловой системы, внешних SDK.
|
|||||||
клиент получит обрывок с кодом 200. Отсюда же общее предпочтение собирать
|
клиент получит обрывок с кодом 200. Отсюда же общее предпочтение собирать
|
||||||
ответ целиком до записи там, где это возможно.
|
ответ целиком до записи там, где это возможно.
|
||||||
|
|
||||||
Из GERR-26.1 есть одно исключение: `http.ErrAbortHandler` — сигнал «прервать
|
Отдельная строка GERR-26.3 нужна потому, что `http.ErrAbortHandler` — не
|
||||||
обработку намеренно», и recover-обёртка пробрасывает его дальше, а не
|
отказ, а сигнал «прервать обработку намеренно»: подмена его на 500 превратила
|
||||||
превращает в 500. Так поступают и стандартные обёртки вроде chi.
|
бы штатный разрыв в ложную ошибку в логе и в метриках. Так поступают и
|
||||||
|
стандартные обёртки вроде chi.
|
||||||
|
|
||||||
### GERR-24. Независимые ошибки собираются `errors.Join`
|
### GERR-24. Независимые ошибки собираются `errors.Join`
|
||||||
|
|
||||||
|
|||||||
@@ -337,6 +337,7 @@ ctx = logctx.With(ctx, log) // достаём логгер из ctx в кажд
|
|||||||
| SLOG-25.1 | штатный конфликт состояния или некорректный ввод | пользователю, он уже получил ответ | `DEBUG` |
|
| SLOG-25.1 | штатный конфликт состояния или некорректный ввод | пользователю, он уже получил ответ | `DEBUG` |
|
||||||
| SLOG-25.2 | расхождение производного или учётного состояния, первичные данные целы | владельцу, «может стать проблемой» | `WARN` |
|
| SLOG-25.2 | расхождение производного или учётного состояния, первичные данные целы | владельцу, «может стать проблемой» | `WARN` |
|
||||||
| SLOG-25.3 | сбой БД, ФС, недоступность зависимости | владельцу, в разбор | `ERROR` |
|
| SLOG-25.3 | сбой БД, ФС, недоступность зависимости | владельцу, в разбор | `ERROR` |
|
||||||
|
| SLOG-25.4 | класса нет: отказ в классификацию не заведён | владельцу, как пропуск в классификации | `ERROR` с отметкой о непокрытом классе |
|
||||||
|
|
||||||
**ПОЧЕМУ.** Это применение SLOG-8 к отказам: пользователь уже увидел причину на
|
**ПОЧЕМУ.** Это применение SLOG-8 к отказам: пользователь уже увидел причину на
|
||||||
экране — владельцу разбирать нечего; целостность первичных данных отделяет
|
экране — владельцу разбирать нечего; целостность первичных данных отделяет
|
||||||
@@ -349,9 +350,11 @@ ctx = logctx.With(ctx, log) // достаём логгер из ctx в кажд
|
|||||||
таблицу не входит: это не доменный отказ, и логирует его recover-граница
|
таблицу не входит: это не доменный отказ, и логирует его recover-граница
|
||||||
вместе со стеком (конвенция `errors`). Искать его класс здесь не нужно.
|
вместе со стеком (конвенция `errors`). Искать его класс здесь не нужно.
|
||||||
|
|
||||||
Мимо таблицы идёт и доменная ошибка, которой нет в маппинге: класса у неё
|
Строка SLOG-25.4 говорит не о классе отказа, а о пропуске в самой
|
||||||
нет, потому что её просто забыли завести. Она логируется `ERROR` с
|
классификации: ошибку забыли завести в маппинге. `ERROR` здесь — громкость,
|
||||||
признаком непокрытой (`GERR-25`).
|
по которой пропуск находят фильтром, а не оценка тяжести отказа; саму отметку
|
||||||
|
о непокрытом классе ставит трансляция ошибки (`GERR-25` в конвенции
|
||||||
|
`errors`).
|
||||||
|
|
||||||
### SLOG-26. Тот же отказ в асинхронной стадии — уровнем выше
|
### SLOG-26. Тот же отказ в асинхронной стадии — уровнем выше
|
||||||
|
|
||||||
|
|||||||
@@ -180,8 +180,8 @@ func utcTime(_ []string, a slog.Attr) slog.Attr {
|
|||||||
текущего значения настройки: смена зоны задним числом сдвигает границы
|
текущего значения настройки: смена зоны задним числом сдвигает границы
|
||||||
суток у того, что давно посчитано и сохранено.
|
суток у того, что давно посчитано и сохранено.
|
||||||
|
|
||||||
Календарные вычисления бизнес-логики берут зону явно — как описано в
|
Явную зону в календарных вычислениях требует TIME-12 — это его правило, а не
|
||||||
базовом слое.
|
второе такое же здесь.
|
||||||
|
|
||||||
## Связано
|
## Связано
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user