- TOOL.md был стартовой точкой разработки инструмента и свою задачу выполнил: решения о нём теперь живут в его собственном репозитории, открытые вопросы перенесены туда же - питоновский conv собран под прежнюю модель копий (зеркальное дерево, именованные регионы, origin_hash) и удалён вместе с ней - команды в README.md переписаны на convy, включая suite-сторону и sync
222 lines
20 KiB
Markdown
222 lines
20 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`, `READING.md`, `.conventions-suite.toml`) живёт в
|
||
корне. К потребителю из неё едет только `READING.md` — короткое описание языка
|
||
для читателя копий.
|
||
|
||
Ниже — короткие инварианты с идентификаторами; детали и обоснования в
|
||
`LANGUAGE.md` (форма записи) и `GUIDE.md` (процесс, префикс META).
|
||
|
||
## Форма правила
|
||
|
||
- Четыре обязательные части: `### <ПРЕФИКС>-<N>. Заголовок`, абзац
|
||
`**МОДАЛЬНОСТЬ.** норма`, абзац `**ПОЧЕМУ.** …`. Правило без обоснования не
|
||
принимается.
|
||
- `**ПРИМЕРЫ.**` — необязательный пятый блок после обоснования: код парой
|
||
«плохо → хорошо». Иллюстрация нормы, а не спецификация — требований в блоке
|
||
нет, дословным сниппетом он не является, при расхождении действует норма.
|
||
- Норма — одна фраза; если в неё не влезает, это два правила.
|
||
- Область правила — от его заголовка до следующего заголовка любого уровня;
|
||
метка открывает блок, блок длится до следующей метки или до конца области.
|
||
Абзацы после `**ПОЧЕМУ.**` — продолжение обоснования: требований в них не
|
||
живёт, требование ставят в блок нормы. Таблица и список после модальной
|
||
метки — часть нормы.
|
||
- Шкала инвариантна, словарь — параметр языка набора. Канон русский, значит
|
||
слова: **ДОЛЖЕН**, **НЕ ДОЛЖЕН**, **СЛЕДУЕТ**, **НЕ СЛЕДУЕТ**,
|
||
**ДОПУСКАЕТСЯ**. Словарь один на канон, синонимов на ступень нет.
|
||
- `SHALL` не используется ни в одном словаре — занято OpenSpec.
|
||
- Нормативно только заглавное написание (правило RFC 8174): строчное
|
||
«должен» в прозе нормой не является.
|
||
- ДОЛЖЕН требует двух условий сразу: назван вред от нарушения (META-25) и
|
||
вердикт о нарушении воспроизводим (META-6). Воспроизводимость сама по себе
|
||
до ДОЛЖЕН не повышает — иначе шкала наполняется проверяемыми мелочами.
|
||
- ДОПУСКАЕТСЯ адресовано рецензенту: помеченный им выбор на ревью не
|
||
обсуждается.
|
||
- **МЕХАНИЗИРОВАНО** — не модальность, а способ проверки, и свойство
|
||
репозитория, а не канона: в тексте конвенции отметки нет, она стоит при
|
||
записи о механизации в локальной части копии (META-7).
|
||
- META-8: норма не удаляется из канона никогда, чем бы её ни проверяли.
|
||
Механизация её не заменяет и не сокращает.
|
||
- Метки правила — **ПОЧЕМУ**, **ПРИМЕРЫ**, **МЕХАНИЗИРОВАНО** и **СНЯТО** —
|
||
тоже словарь набора и перечислены в строке о версии языка наравне с
|
||
модальными словами.
|
||
- META-30: правка словаря или состава частей правила доходит до `READING.md` —
|
||
документа, который едет к потребителю. Словари двух описаний совпадают.
|
||
- Заглавные модальные слова не употребляются вне правил: ни в «Область
|
||
действия», ни в «Связано», ни в локальной части копии, ни во вводной прозе.
|
||
Исключение — строка о версии языка, которая их перечисляет.
|
||
- Обоснование отвечает на «что сломается, если сделать иначе», а не
|
||
пересказывает норму. «Потому что так принято» — не обоснование.
|
||
- Форма обоснования не ограничена: рамки смысловые. Длина, рассуждение,
|
||
примеры, ссылки на внешние практики и чужие проекты — всё допустимо;
|
||
запрещённых слов нет. Обязательность несёт норма, и путаницу исключает
|
||
правило о заглавных.
|
||
- Служебные слова сценарного блока — тоже словарь набора: **КОГДА**,
|
||
**ТОГДА**, **И**, **ИЛИ** (по-английски `WHEN`/`THEN`/`AND`/`OR`). Одна
|
||
форма на роль, заглавными. Модальностью не являются, в строку о версии
|
||
языка не попадают.
|
||
- Правило, классифицирующее ситуации, пишется таблицей «ситуация → вердикт»;
|
||
строки нумеруются `KEYS-5.1`. Строки взаимоисключающи по умолчанию; иной
|
||
порядок объявляется явно, а перечисленные случаи покрывают область
|
||
действия.
|
||
- Модальность принадлежит правилу, а не файлу: `status:` в шапке отменён.
|
||
|
||
## Идентификаторы: тема и префикс
|
||
|
||
- Тема — набор правил об одном фокусе разработки и единица подписки. Имя —
|
||
латиницей, рекомендуется нижний kebab-case, годится любой идентификатор,
|
||
пригодный для имени файла.
|
||
- META-28: тема объявлена в шапке (`topic: time`) и стоит в манифесте набора
|
||
(`.conventions-suite.toml`, секция `[topics.live]`). Слои одной темы несут
|
||
одно имя — по нему собираются в один файл, как бы ни назывались их файлы;
|
||
имя файла повторяет тему из удобства.
|
||
- META-29: имя темы не переиспользуется, снятое уходит в `[topics.retired]`
|
||
с причиной и датой. Оно живёт в `origin:` копий и в подписках манифестов.
|
||
- Формат `<ПРЕФИКС>-<номер>`, нумерация сквозная внутри файла. Порядок правил
|
||
в файле — по читаемости: номер это идентификатор, а не позиция.
|
||
- Идентификаторы не переиспользуются: новое правило берёт номер, следующий за
|
||
наибольшим.
|
||
- META-31: нумерация в файле сплошная. Снятое правило не исчезает, а остаётся
|
||
заглушкой: заголовок с номером плюс блок `**СНЯТО <дата>.**` с причиной
|
||
вместо нормы и ПОЧЕМУ. Реестра снятых номеров нет — файл сам себе реестр.
|
||
- META-32: ссылок на несуществующие правила нет; неразрешённый идентификатор —
|
||
всегда ошибка, а не «правило, наверное, сняли».
|
||
- Новый файл конвенции — новый префикс: четыре заглавные латинские буквы,
|
||
уникальные по всему канону, выбираются под файл, а не выводятся по формуле.
|
||
Объявляется в шапке (`prefix: KEYS`) и регистрируется в манифесте набора,
|
||
секция `[prefixes.live]`, путём от корня репозитория.
|
||
- Удаление или разделение файла: префикс уходит в `[prefixes.retired]` с
|
||
причиной и датой, а не освобождается.
|
||
- Префиксы на букву `X` канон не занимает: они зарезервированы за локальными
|
||
правилами репозиториев-потребителей.
|
||
- Перенос правила в другой файл — смысловое изменение: новый префикс и новый
|
||
номер. Переезд самого файла между осями идентификаторы не трогает.
|
||
|
||
## Ссылки
|
||
|
||
- META-20: норму можно исполнить, имея один этот файл. Ссылка на правило
|
||
чужой темы допустима в обосновании, в «Связано» и в разграничении области
|
||
действия — но не в самой норме. Нужен концепт соседней темы — коротко
|
||
повторить его здесь, соседа назвать в обосновании.
|
||
- META-21: на соседнюю конвенцию ссылаются именем темы (конвенция
|
||
`logging`), на правило — идентификатором (`SLOG-27`). Пути файлов канона в
|
||
тексте конвенции нет (в обвязке — можно).
|
||
- META-24: слой `lang/` или `stack/` называет идентификатор правила арх-слоя
|
||
**своей** темы прямо в норме — базовый слой в собранной копии всегда рядом.
|
||
На слои других языков и стеков это не распространяется: их состав зависит
|
||
от манифеста.
|
||
|
||
## Что в каноне писать нельзя
|
||
|
||
- META-4: в тексте конвенции нет утверждений о состоянии конкретного
|
||
репозитория; норма — в настоящем предписывающем времени.
|
||
- META-5: расхождение кода с правилом — отступление, а не повод переписать
|
||
правило. Направление всегда конвенция → код; факт «в приложении уже иначе»
|
||
не является аргументом.
|
||
- META-6: ДОЛЖЕН требует воспроизводимого вердикта — двое проверяющих по
|
||
тексту правила отвечают одинаково. Правило, вердикт которого зависит от
|
||
суждения (вкус формулировки, уместность в конкретном месте), — СЛЕДУЕТ по
|
||
построению. META-27: машинная проверка желательна, но ступени не задаёт;
|
||
проверяющий по умолчанию — читатель правила, человек или агент.
|
||
- META-10: блок ПОЧЕМУ не удаляется никогда, в том числе после того, как
|
||
правило стало проверяться линтером.
|
||
- META-1: один файл — ровно один повторяющийся выбор. META-2: конвенция
|
||
заводится, когда решение принимается третий раз.
|
||
- Репозиторного в каноне нет вовсе: механизация, отступления и ссылки на код
|
||
живут в копии ниже маркера `<!-- conv:local -->` (META-22), который ставит
|
||
сборщик. Заводить пустые местные разделы в каноне не нужно.
|
||
|
||
## Граница темы
|
||
|
||
Пять вопросов, по которым тему проверяют на «не хапнули ли лишнего»; сначала
|
||
разрез темы, ось — потом.
|
||
|
||
- META-33: правило стоит в теме, чей вопрос оно решает. Тема — решение, а не
|
||
вещество: «время» проходит через несколько решений сразу, и правило о
|
||
колонках БД принадлежит схеме, а не времени.
|
||
- META-37: имя темы называет решение и адресата, а не роль части проекта:
|
||
`logging` и `client-logging`, но не `logging-backend`/`logging-frontend`.
|
||
- META-34: тема нужна потребителю целиком — подписка берёт её без остатка.
|
||
Если два правдоподобных потребителя хотят непересекающиеся части, между
|
||
ними и проходит граница.
|
||
- META-35: слой сужает базу, но не отменяет её. Приходится отменять — это не
|
||
слой, а другая тема; общим осталось слово, а не решение.
|
||
- META-36: вид приложения (веб-сервис, CLI, плейбуки, библиотека) называется
|
||
в области действия, если норма от него зависит. Осью он не является.
|
||
- META-20: норма исполнима без соседних тем.
|
||
|
||
## Выбор оси
|
||
|
||
Умирает при смене языка → `lang/<язык>/`. Умирает при смене инструмента,
|
||
хранилища или транспорта → `stack/<стек>/`. Не умирает ни от того, ни от
|
||
другого → `arch/`. Ось определяется природой правила, а не числом сегодняшних
|
||
потребителей. `extends: arch/<файл>.md` в шапке — документация связи, а не
|
||
механизм; слой только реализует и сужает базу, но не отменяет её (META-35).
|
||
|
||
META-38: ось объявлена в шапке ключами `lang:` и `stack:`, а не выведена из
|
||
пути; без обоих ключей файл — базовый слой темы. Директория повторяет
|
||
объявленное для человека. Осей может не быть вовсе: набор, где у темы один
|
||
слой, — низкий конец той же модели, а не особый режим.
|
||
|
||
## Компоненты
|
||
|
||
Компонент — область репозитория, где все выбранные слои действуют
|
||
одновременно (`sqlite` и `postgres` — да, go и javascript — никогда). Уровней
|
||
три: набор → проект → компонент. Сборка прогоняется по разу на компонент, у
|
||
каждого своя директория копий, своя подписка и своя локальная часть; в
|
||
`.conventions.toml` они записаны секциями `[components.<имя>]` с ключами
|
||
`dir`, `lang`, `stack`, `topics`. Компонент пишется всегда, даже когда он
|
||
один. Директории компонентов различны — этим копии и разводятся.
|
||
|
||
## Оформление файла
|
||
|
||
Шапка `topic:` и `prefix:` (плюс `extends:`) → `# Тема` → вводная проза →
|
||
отдельным абзацем строка о версии языка (её точный текст — в `LANGUAGE.md`,
|
||
раздел «Ссылка на язык из конвенции») → `## Область действия` (обязателен для
|
||
трудноизменяемых слоёв — META-11) → правила → `## Связано`, если канонические
|
||
ссылки есть (META-17; пустого раздела не заводят). Имя файла повторяет имя
|
||
темы. Проза переносится по ~76 колонок; таблицы и блоки кода не переносятся.
|
||
|
||
## Ревью формы
|
||
|
||
Список того, что подлежит проверке, — в `LANGUAGE.md`, раздел «Что стоит
|
||
проверять машиной». Ни одна из проверок не реализована, поэтому при ревью их
|
||
выполняют чтением.
|
||
|
||
Проверяется всё, что язык **употребляет**: конвенции и `GUIDE.md` (он несёт
|
||
правила META и строку о версии языка). `LANGUAGE.md` и `README.md` язык
|
||
цитируют — ключевые слова в них предмет описания, а не норма. Проверки
|
||
распространения (тема в шапке, самодостаточность нормы, отсутствие путей
|
||
канона) касаются только конвенций: обвязка к потребителю не едет.
|
||
|
||
## Коммиты
|
||
|
||
Русский, строчная буква, без точки в конце, прошедшее время или страдательный
|
||
залог: «заведён реестр префиксов, правила канона перенумерованы». Изредка
|
||
область через двоеточие (`guide:`, `errors:`). Тело — маркированный список на
|
||
2–3 пункта с переносом по ~76 колонок; объясняет почему и цитирует
|
||
идентификаторы правил. Conventional Commits не используются.
|
||
|
||
## Состояние репозитория
|
||
|
||
- Тестов, линтеров и CI здесь нет: репозиторий — данные, а не код. Проверяет
|
||
их `convy suite check`, живущий в своём репозитории и ставящийся бинарём.
|
||
- Модель копий, описанная в `README.md`, реализована в `convy`. Прежний
|
||
питоновский `conv` удалён вместе со своей моделью (зеркальное дерево,
|
||
именованные регионы, `origin_hash`). При расхождении обвязки с инструментом
|
||
истина — README, а не код.
|
||
- Ни один репозиторий-потребитель ещё не подключён: копий с шапкой `origin:`
|
||
в природе нет.
|
||
- `TODO.md` — площадка для обсуждения на будущее, а не принятые решения; при
|
||
работе над обвязкой его стоит прочесть, но истина о текущем устройстве —
|
||
`README.md`.
|