diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..5d0bb2f --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,119 @@ +# 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). + +## Форма правила + +- Четыре обязательные части: `### <ПРЕФИКС>-. Заголовок`, абзац + `**МОДАЛЬНОСТЬ.** норма`, абзац `**Почему.** …`. Правило без «Почему» не + принимается. +- Норма — одна фраза; если в неё не влезает, это два правила. +- Модальные слова: **ДОЛЖЕН**, **НЕ ДОЛЖЕН**, **СЛЕДУЕТ**, **НЕ СЛЕДУЕТ**, + **ДОПУСКАЕТСЯ**, плюс не-модальная отметка **МЕХАНИЗИРОВАНО**. Английские + ключевые слова (SHALL, MUST) не используются — они заняты OpenSpec. +- Модальные слова не употребляются вне правил: ни в «Область действия», ни в + «Связано», ни в локальных регионах, ни во вводной прозе. +- «Почему» отвечает на «что сломается, если сделать иначе», а не + пересказывает норму. «Потому что так принято» — не обоснование. +- Правило, классифицирующее ситуации, пишется таблицей «ситуация → вердикт»; + строки нумеруются `KEYS-5.1`. +- Модальность принадлежит правилу, а не файлу: `status:` в шапке отменён. + +## Идентификаторы и префиксы + +- Формат `<ПРЕФИКС>-<номер>`, нумерация сквозная внутри файла. Порядок правил + в файле — по читаемости: номер это идентификатор, а не позиция. +- Идентификаторы не переиспользуются. Удалённое правило оставляет дыру, новое + берёт следующий свободный номер, а не первый освободившийся. +- Новый файл конвенции — новый префикс: четыре заглавные латинские буквы, + уникальные по всему канону, выбираются под файл, а не выводятся по формуле. + Объявляется в шапке (`prefix: KEYS`) и регистрируется в `prefixes.toml`, + секция `[live]`, путём от корня репозитория. +- Удаление или разделение файла: префикс уходит в `[retired]` с причиной и + датой, а не освобождается. +- Перенос правила в другой файл — смысловое изменение: новый префикс и новый + номер. Переезд самого файла между осями идентификаторы не трогает. + +## Ссылки + +- META-20: норму можно исполнить, имея один этот файл. Ссылка на правило + чужой темы допустима в «Почему», в «Связано» и в разграничении области + действия — но не в самой норме. Нужен концепт соседней темы — коротко + повторить его здесь, соседа назвать в «Почему». +- META-21: на соседнюю конвенцию ссылаются именем темы (конвенция + `logging`), на правило — идентификатором (`SLOG-27`), на другой слой своей + темы — словами «базовый слой». Пути файлов канона в тексте конвенции нет + (в обвязке — можно). + +## Что в каноне писать нельзя + +- META-4: в тексте конвенции нет утверждений о состоянии конкретного + репозитория; норма — в настоящем предписывающем времени. +- META-5: расхождение кода с правилом — отступление, а не повод переписать + правило. Направление всегда конвенция → код; факт «в приложении уже иначе» + не является аргументом. +- META-6: ДОЛЖЕН без механической проверки либо механизируется, либо + понижается в СЛЕДУЕТ. Правило, непроверяемое машиной в принципе (вкус + формулировки, суждение о ситуации), — СЛЕДУЕТ по построению. +- META-10: блок «Почему» не удаляется никогда, в том числе после того, как + норма уехала в линтер. +- META-1: один файл — ровно один повторяющийся выбор. META-2: конвенция + заводится, когда решение принимается третий раз. +- Локальные регионы `` в каноне остаются + пустыми: их содержимое принадлежит репозиторию-потребителю. Имя региона и + путь файла — API, переименование осиротит все копии. + +## Выбор оси + +Умирает при смене языка → `lang/<язык>/`. Умирает при смене инструмента, +хранилища или транспорта → `stack/<стек>/`. Не умирает ни от того, ни от +другого → `arch/`. Ось определяется природой правила, а не числом сегодняшних +потребителей. `extends: arch/<файл>.md` в шапке — документация связи, а не +механизм; слой только реализует и сужает базу, но не отменяет её. + +## Оформление файла + +Шапка `prefix:` (плюс `extends:`) → `# Тема` → вводная проза со строкой +«Форма записи — `LANGUAGE.md`» → `## Область действия` (обязателен для +трудноизменяемых слоёв — META-11) → правила → `## Связано` с пустым +``. Имя файла — kebab-case по теме. Проза переносится +по ~76 колонок; таблицы и блоки кода не переносятся. + +## Ревью формы + +Список того, что подлежит проверке, — в `LANGUAGE.md`, раздел «Что стоит +проверять машиной». Ни одна из проверок не реализована, поэтому при ревью их +выполняют чтением. + +## Коммиты + +Русский, строчная буква, без точки в конце, прошедшее время или страдательный +залог: «заведён реестр префиксов, правила канона перенумерованы». Изредка +область через двоеточие (`guide:`, `errors:`). Тело — маркированный список на +2–3 пункта с переносом по ~76 колонок; объясняет почему и цитирует +идентификаторы правил. Conventional Commits не используются. + +## Состояние репозитория + +- Тестов, линтеров и CI нет. `conv` — python3 CLI на одной stdlib; запускают + его из корня репозитория-потребителя (`~/projects/private/dev-conventions/` + плюс `conv status`). `status` и `diff` всегда возвращают 0 — это отчёт, а не + проверка. +- Ни один репозиторий-потребитель ещё не подключён: копий с шапкой `origin:` + в природе нет, все локальные регионы канона пусты. +- `TODO.md` не коммитится. Это площадка для обсуждения на будущее, а не + принятые решения; при работе над обвязкой его стоит прочесть, но истина о + текущем устройстве — `README.md`.