common: добавлен язык записи конвенций

- правило = номер + модальность (ДОЛЖЕН / СЛЕДУЕТ / ДОПУСКАЕТСЯ) плюс
  обязательный блок «Почему»; из OpenSpec взяты идентификаторы правил, но
  не SHALL и не GIVEN/WHEN/THEN
- файловый статус отменён: обязательность живёт на правиле, а в шапке ещё
  не переведённых конвенций ключ остаётся меткой «это проза»
This commit is contained in:
av
2026-07-25 18:56:29 +03:00
parent 4a59c71737
commit 22c6855968
2 changed files with 206 additions and 24 deletions
+25 -24
View File
@@ -1,16 +1,12 @@
---
status: обязательная
---
# Как мы ведём конвенции
Конвенция описывает повторяющийся выбор: как называть директории, как
раскладывать данные, как оформлять ошибки. Она отвечает на вопрос «как
принято», а не «что здесь происходит». Одна конвенция — один файл.
Механической проверки у самой этой конвенции нет — осознанное исключение:
проверять «правильно ли написана конвенция» нечем, а обязательный статус
нужен, чтобы правила ниже не обсуждались заново в каждом репозитории.
Как записывается сама конвенция — правила, модальность, обоснования — в
[language.md](language.md). Здесь — про то, зачем они заводятся, где живут
и как соотносятся с соседними видами документов.
## Канон и копии
@@ -54,17 +50,16 @@ status: обязательная
текущем состоянии репозитория. «Так сделано у нас» — это регион
отступлений; норма пишется в настоящем предписывающем времени.
## Статус
## Насколько правило обязательно
Каждая конвенция объявляет статус в шапке:
Обязательность живёт **на правиле**, а не на файле: один документ почти
всегда смешивает жёсткие требования с советами, и общая пометка на нём
неизбежно врёт про часть содержимого. Шкала модальных слов — в
[language.md](language.md).
- **рекомендуемая** — так стоит делать в новом коде; существующий переезжает
по мере касания, отдельной кампанией не переписывается;
- **обязательная** — нарушение считается ошибкой; по возможности проверяется
линтером или хуком, а не вниманием.
Конвенция без механической проверки держится только на внимании — это
нормально для рекомендуемой и плохо для обязательной.
Правило без механической проверки держится только на внимании. Для
**СЛЕДУЕТ** это нормально, для **ДОЛЖЕН** — плохо: такое правило либо
механизируется, либо честно понижается.
## Когда заводить
@@ -89,14 +84,19 @@ status: обязательная
- **из канона формулировка не удаляется**, пока правило не механизировано
у всех потребителей: иначе те, у кого линтера нет, останутся без правила;
- **факт механизации** фиксируется в локальном регионе `механизировано`
со ссылкой на конкретное правило;
со ссылкой на номер правила и на конкретную проверку;
- когда механизация стала общей (правило уехало в общий конфиг линтера или
в общую роль), формулировка удаляется из канона одним `push`.
Обоснование правила («Почему») не удаляется никогда, даже когда сама норма
уехала в линтер: линтер сообщает, что нарушено, но не сообщает, зачем
правило существует, — а именно это нужно, чтобы понять, когда его пора
отменить.
## Трудноизменяемые слои
У схемы БД, формата хранения и раскладки директорий шкала
«рекомендуемая → переезжает по мере касания» не работает: таблица не
У схемы БД, формата хранения и раскладки директорий не работает привычное
«новое пишем правильно, старое переезжает по мере касания»: таблица не
переезжает от того, что её потрогали. Для таких конвенций:
- **область действия пишется явно** — «применяется к новым таблицам и
@@ -108,10 +108,11 @@ status: обязательная
## Честный список отступлений
В локальном регионе перечисляем отступления, которые уже есть в коде, —
иначе репозиторий делает вид, что правилу следует. У рекомендуемой
конвенции пустой список отступлений почти всегда означает, что их просто не
искали.
В локальном регионе перечисляем отступления, которые уже есть в коде, — со
ссылкой на номера правил. Иначе репозиторий делает вид, что конвенции
следует, а проверить это можно только чтением всего кода.
Пустой список отступлений почти всегда означает, что их не искали.
Отступление — это «правилу не следуем здесь и вот почему». Если регион
разросся до «мы это правило вообще не применяем», значит либо у правила
@@ -129,7 +130,7 @@ status: обязательная
- **Короткие инварианты дублируются туда, что агент читает безусловно**
(`AGENTS.md` / `CLAUDE.md`): сама по себе конвенция агенту не видна, он
дойдёт до неё, только если его туда отправили. Детали остаются здесь,
в файл-точку-входа едет одна строка на правило.
в файл-точку-входа едет одна строка на правило с его номером.
<!-- local:точки-входа -->
<!-- /local -->