- «Почему» не пересказывает норму словами обязательства: у оригинала есть идентификатор, у копии нет, и расходятся они при первой правке оригинала, а отступление от копии адресовать нечем - модальность рекомендательная по META-6: греп находит слово, а не нарушение — «за попыткой следует повтор» и «становится обязанностью вызывающего» описывают ход событий; утверждения о невозможности («нельзя») правилом не затрагиваются, это ISO-евская возможность в прозе - SLOG-12 починен: факт о том, что `slog` не разделяет CRITICAL и FATAL, уехал из нормы в «Почему», а норма теперь говорит то же, что заголовок
152 lines
13 KiB
Markdown
152 lines
13 KiB
Markdown
# CLAUDE.md
|
||
|
||
This file provides guidance to Claude Code (claude.ai/code) when working with
|
||
code in this repository.
|
||
|
||
Всё содержимое репозитория и общение по нему — на русском.
|
||
|
||
## Что это
|
||
|
||
Канон конвенций разработки для личных проектов. Сами конвенции лежат в
|
||
`conventions/{arch,lang/<язык>,stack/<стек>}/`; обвязка канона (`README.md`,
|
||
`LANGUAGE.md`, `GUIDE.md`, `prefixes.toml`, `conv`) живёт в корне и в
|
||
репозитории-потребители не едет.
|
||
|
||
Ниже — короткие инварианты с идентификаторами; детали и обоснования в
|
||
`LANGUAGE.md` (форма записи) и `GUIDE.md` (процесс, префикс META).
|
||
|
||
## Форма правила
|
||
|
||
- Четыре обязательные части: `### <ПРЕФИКС>-<N>. Заголовок`, абзац
|
||
`**МОДАЛЬНОСТЬ.** норма`, абзац `**Почему.** …`. Правило без «Почему» не
|
||
принимается.
|
||
- Норма — одна фраза; если в неё не влезает, это два правила.
|
||
- Шкала инвариантна, словарь — параметр языка набора. Канон русский, значит
|
||
слова: **ДОЛЖЕН**, **НЕ ДОЛЖЕН**, **СЛЕДУЕТ**, **НЕ СЛЕДУЕТ**,
|
||
**ДОПУСКАЕТСЯ**. Словарь один на канон, синонимов на ступень нет.
|
||
- `SHALL` не используется ни в одном словаре — занято OpenSpec.
|
||
- Нормативно только заглавное написание (правило RFC 8174): строчное
|
||
«должен» в прозе нормой не является.
|
||
- ДОЛЖЕН требует двух условий сразу: назван вред от нарушения (META-25) и
|
||
норма проверяема машиной (META-6). Проверяемость сама по себе до ДОЛЖЕН не
|
||
повышает — иначе шкала наполняется проверяемыми мелочами.
|
||
- ДОПУСКАЕТСЯ адресовано рецензенту: помеченный им выбор на ревью не
|
||
обсуждается.
|
||
- **МЕХАНИЗИРОВАНО** — не модальность, а способ проверки: отметка стоит
|
||
рядом с модальным словом (`**ДОЛЖЕН. МЕХАНИЗИРОВАНО.**`), а не вместо него.
|
||
- Заглавные модальные слова не употребляются вне правил: ни в «Область
|
||
действия», ни в «Связано», ни в локальной части копии, ни во вводной прозе.
|
||
Исключение — строка о версии языка, которая их перечисляет.
|
||
- «Почему» отвечает на «что сломается, если сделать иначе», а не
|
||
пересказывает норму. «Потому что так принято» — не обоснование.
|
||
- META-26: «Почему» не повторяет норму словами обязательства — на неё
|
||
ссылаются идентификатором. Утверждения о невозможности (`нельзя`) — факт, а
|
||
не запрет, и допустимы. Модальность рекомендательная: греп по `должен`,
|
||
`обязан`, `следует` даёт кандидатов, но слова омонимичны.
|
||
- Служебные слова сценарного блока — тоже словарь набора: **КОГДА**,
|
||
**ТОГДА**, **И**, **ИЛИ** (по-английски `WHEN`/`THEN`/`AND`/`OR`). Одна
|
||
форма на роль, заглавными. Модальностью не являются, в строку о версии
|
||
языка не попадают.
|
||
- Правило, классифицирующее ситуации, пишется таблицей «ситуация → вердикт»;
|
||
строки нумеруются `KEYS-5.1`. Строки взаимоисключающи по умолчанию; иной
|
||
порядок объявляется явно, а перечисленные случаи покрывают область
|
||
действия.
|
||
- Модальность принадлежит правилу, а не файлу: `status:` в шапке отменён.
|
||
|
||
## Идентификаторы и префиксы
|
||
|
||
- Формат `<ПРЕФИКС>-<номер>`, нумерация сквозная внутри файла. Порядок правил
|
||
в файле — по читаемости: номер это идентификатор, а не позиция.
|
||
- Идентификаторы не переиспользуются. Удалённое правило оставляет дыру, новое
|
||
берёт следующий свободный номер, а не первый освободившийся.
|
||
- Новый файл конвенции — новый префикс: четыре заглавные латинские буквы,
|
||
уникальные по всему канону, выбираются под файл, а не выводятся по формуле.
|
||
Объявляется в шапке (`prefix: KEYS`) и регистрируется в `prefixes.toml`,
|
||
секция `[live]`, путём от корня репозитория.
|
||
- Удаление или разделение файла: префикс уходит в `[retired]` с причиной и
|
||
датой, а не освобождается.
|
||
- Префиксы на букву `X` канон не занимает: они зарезервированы за локальными
|
||
правилами репозиториев-потребителей.
|
||
- Перенос правила в другой файл — смысловое изменение: новый префикс и новый
|
||
номер. Переезд самого файла между осями идентификаторы не трогает.
|
||
|
||
## Ссылки
|
||
|
||
- META-20: норму можно исполнить, имея один этот файл. Ссылка на правило
|
||
чужой темы допустима в «Почему», в «Связано» и в разграничении области
|
||
действия — но не в самой норме. Нужен концепт соседней темы — коротко
|
||
повторить его здесь, соседа назвать в «Почему».
|
||
- META-21: на соседнюю конвенцию ссылаются именем темы (конвенция
|
||
`logging`), на правило — идентификатором (`SLOG-27`). Пути файлов канона в
|
||
тексте конвенции нет (в обвязке — можно).
|
||
- META-24: слой `lang/` или `stack/` называет идентификатор правила арх-слоя
|
||
**своей** темы прямо в норме — базовый слой в собранной копии всегда рядом.
|
||
На слои других языков и стеков это не распространяется: их состав зависит
|
||
от манифеста.
|
||
|
||
## Что в каноне писать нельзя
|
||
|
||
- META-4: в тексте конвенции нет утверждений о состоянии конкретного
|
||
репозитория; норма — в настоящем предписывающем времени.
|
||
- META-5: расхождение кода с правилом — отступление, а не повод переписать
|
||
правило. Направление всегда конвенция → код; факт «в приложении уже иначе»
|
||
не является аргументом.
|
||
- META-6: ДОЛЖЕН без механической проверки либо механизируется, либо
|
||
понижается в СЛЕДУЕТ. Правило, непроверяемое машиной в принципе (вкус
|
||
формулировки, суждение о ситуации), — СЛЕДУЕТ по построению.
|
||
- META-10: блок «Почему» не удаляется никогда, в том числе после того, как
|
||
норма уехала в линтер.
|
||
- META-1: один файл — ровно один повторяющийся выбор. META-2: конвенция
|
||
заводится, когда решение принимается третий раз.
|
||
- Репозиторного в каноне нет вовсе: механизация, отступления и ссылки на код
|
||
живут в копии ниже маркера `<!-- conv:local -->` (META-22), который ставит
|
||
сборщик. Заводить пустые местные разделы в каноне не нужно.
|
||
|
||
## Выбор оси
|
||
|
||
Умирает при смене языка → `lang/<язык>/`. Умирает при смене инструмента,
|
||
хранилища или транспорта → `stack/<стек>/`. Не умирает ни от того, ни от
|
||
другого → `arch/`. Ось определяется природой правила, а не числом сегодняшних
|
||
потребителей. `extends: arch/<файл>.md` в шапке — документация связи, а не
|
||
механизм; слой только реализует и сужает базу, но не отменяет её.
|
||
|
||
## Оформление файла
|
||
|
||
Шапка `prefix:` (плюс `extends:`) → `# Тема` → вводная проза → отдельным
|
||
абзацем строка о версии языка (её точный текст — в `LANGUAGE.md`, раздел
|
||
«Ссылка на язык из конвенции») → `## Область действия` (обязателен для
|
||
трудноизменяемых слоёв — META-11) → правила → `## Связано`, если
|
||
канонические ссылки есть (META-17; пустого раздела не заводят). Имя файла —
|
||
kebab-case по теме. Проза
|
||
переносится по ~76 колонок; таблицы и блоки кода не переносятся.
|
||
|
||
## Ревью формы
|
||
|
||
Список того, что подлежит проверке, — в `LANGUAGE.md`, раздел «Что стоит
|
||
проверять машиной». Ни одна из проверок не реализована, поэтому при ревью их
|
||
выполняют чтением.
|
||
|
||
## Коммиты
|
||
|
||
Русский, строчная буква, без точки в конце, прошедшее время или страдательный
|
||
залог: «заведён реестр префиксов, правила канона перенумерованы». Изредка
|
||
область через двоеточие (`guide:`, `errors:`). Тело — маркированный список на
|
||
2–3 пункта с переносом по ~76 колонок; объясняет почему и цитирует
|
||
идентификаторы правил. Conventional Commits не используются.
|
||
|
||
## Состояние репозитория
|
||
|
||
- Тестов, линтеров и CI нет. `conv` — python3 CLI на одной stdlib; запускают
|
||
его из корня репозитория-потребителя (`~/projects/private/dev-conventions/`
|
||
плюс команда).
|
||
- Модель копий, описанная в `README.md`, согласована, но не реализована:
|
||
`conv` собран под прежнюю (зеркальное дерево, именованные регионы,
|
||
`origin_hash`, команды `status`/`diff`/`push`). Сами конвенции к новой
|
||
модели приведены — регионов в каноне нет. При правке обвязки истина —
|
||
README, а не код `conv`.
|
||
- Ни один репозиторий-потребитель ещё не подключён: копий с шапкой `origin:`
|
||
в природе нет.
|
||
- `TODO.md` — площадка для обсуждения на будущее, а не принятые решения; при
|
||
работе над обвязкой его стоит прочесть, но истина о текущем устройстве —
|
||
`README.md`.
|