diff --git a/CLAUDE.md b/CLAUDE.md index 2222cde..89e857b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -25,7 +25,7 @@ code in this repository. **ДОПУСКАЕТСЯ**, плюс не-модальная отметка **МЕХАНИЗИРОВАНО**. Английские ключевые слова (SHALL, MUST) не используются — они заняты OpenSpec. - Модальные слова не употребляются вне правил: ни в «Область действия», ни в - «Связано», ни в локальных регионах, ни во вводной прозе. + «Связано», ни в локальной части копии, ни во вводной прозе. - «Почему» отвечает на «что сломается, если сделать иначе», а не пересказывает норму. «Потому что так принято» — не обоснование. - Правило, классифицирующее ситуации, пишется таблицей «ситуация → вердикт»; @@ -44,6 +44,8 @@ code in this repository. секция `[live]`, путём от корня репозитория. - Удаление или разделение файла: префикс уходит в `[retired]` с причиной и датой, а не освобождается. +- Префиксы на букву `X` канон не занимает: они зарезервированы за локальными + правилами репозиториев-потребителей. - Перенос правила в другой файл — смысловое изменение: новый префикс и новый номер. Переезд самого файла между осями идентификаторы не трогает. @@ -72,9 +74,9 @@ code in this repository. норма уехала в линтер. - META-1: один файл — ровно один повторяющийся выбор. META-2: конвенция заводится, когда решение принимается третий раз. -- Локальные регионы `` в каноне остаются - пустыми: их содержимое принадлежит репозиторию-потребителю. Имя региона и - путь файла — API, переименование осиротит все копии. +- Репозиторного в каноне нет вовсе: механизация, отступления и ссылки на код + живут в копии ниже маркера `` (META-22), который ставит + сборщик. Заводить пустые местные разделы в каноне не нужно. ## Выбор оси @@ -88,9 +90,9 @@ code in this repository. Шапка `prefix:` (плюс `extends:`) → `# Тема` → вводная проза со строкой «Форма записи — `LANGUAGE.md`» → `## Область действия` (обязателен для -трудноизменяемых слоёв — META-11) → правила → `## Связано` с пустым -``. Имя файла — kebab-case по теме. Проза переносится -по ~76 колонок; таблицы и блоки кода не переносятся. +трудноизменяемых слоёв — META-11) → правила → `## Связано` только с +каноническими ссылками (META-17). Имя файла — kebab-case по теме. Проза +переносится по ~76 колонок; таблицы и блоки кода не переносятся. ## Ревью формы @@ -110,10 +112,14 @@ code in this repository. - Тестов, линтеров и CI нет. `conv` — python3 CLI на одной stdlib; запускают его из корня репозитория-потребителя (`~/projects/private/dev-conventions/` - плюс `conv status`). `status` и `diff` всегда возвращают 0 — это отчёт, а не - проверка. + плюс команда). +- Модель копий, описанная в `README.md`, согласована, но не реализована: + `conv` собран под прежнюю (зеркальное дерево, именованные регионы, + `origin_hash`, команды `status`/`diff`/`push`), и в двенадцати файлах + канона ещё лежит 31 пустой регион `` — их предстоит + удалить. При правке обвязки истина — README, а не код `conv`. - Ни один репозиторий-потребитель ещё не подключён: копий с шапкой `origin:` - в природе нет, все локальные регионы канона пусты. + в природе нет. - `TODO.md` — площадка для обсуждения на будущее, а не принятые решения; при работе над обвязкой его стоит прочесть, но истина о текущем устройстве — `README.md`. diff --git a/GUIDE.md b/GUIDE.md index 920b6f8..c2f9b17 100644 --- a/GUIDE.md +++ b/GUIDE.md @@ -41,16 +41,20 @@ prefix: META ## Канон и копии Файлы в `docs/conventions/` с шапкой `origin:` — копии из общего канона -`dev-conventions`, а не собственные документы репозитория. Репозиторное -живёт только внутри локальных регионов ``: -они исключены из сравнения с каноном, и расхождение по ним — норма, а не -дрейф. Правка вне регионов означает одно из двух: улучшение, которое -возвращают в канон, или сознательное расхождение, записанное в ключ `local:` -шапки. Состояние копий показывает `conv status`, различия — `conv diff`, -обновление из канона — `conv pull`; всё через раннер репозитория. +`dev-conventions`, а не собственные документы репозитория. Копия собирается +из канона целиком, поэтому репозиторное живёт ниже маркера локальной части +в конце файла: обновление сохраняет всё, что ниже маркера, и переписывает +всё, что выше. Откуда взяты копии и где брать обновления — в манифесте +`.conventions.toml` в корне репозитория. -Имя региона обязательно и стабильно: перенос содержимого при обновлении -идёт по именам, и переименование осиротит содержимое во всех копиях. +Отдельного механизма отчёта о расхождении нет: обновление перезаписывает +файлы в рабочем дереве, а что именно изменилось, показывает `git diff` до +коммита. Поэтому в шапке копии хранится только `origin:` — отпечатков +канона и дат синхронизации в ней нет, историю держит git. + +Правка выше маркера означает одно из двух: улучшение, которое переносят в +канон, или документ, переставший быть копией, — тогда `origin:` из шапки +убирают. ## Правила @@ -58,11 +62,11 @@ prefix: META **ДОЛЖЕН.** Файл описывает ровно один повторяющийся выбор. -**Почему.** Подписка — это набор лежащих в репозитории файлов, и берут файл -целиком. Файл, собравший две темы, вынуждает репозиторий взять правила, -которые ему не нужны, и получать шум в `diff` по чужой половине. Разрезать -позже дорого: путь файла — часть адреса правила, и после разреза внешние -ссылки указывают не туда. +**Почему.** Подписка перечисляется по темам, и тему берут целиком. Файл, +собравший две темы, вынуждает репозиторий взять правила, которые ему не +нужны, и вычитывать чужую половину при каждом обновлении. Разрезать позже +дорого: перенос правила в другой файл — это новый префикс и новая +нумерация, поэтому после разреза все внешние ссылки обходят руками. ### META-2. Конвенция заводится, когда решение принимается третий раз @@ -152,9 +156,9 @@ prefix: META (вкус формулировки, выбор границы, суждение о ситуации), не может быть ДОЛЖЕН — его модальность СЛЕДУЕТ по построению, а не по слабости. -### META-7. Факт механизации фиксируется в локальном регионе со ссылкой на правило +### META-7. Факт механизации фиксируется в копии со ссылкой на правило -**ДОЛЖЕН.** Регион `механизировано` называет идентификатор правила и +**ДОЛЖЕН.** Запись о механизации называет идентификатор правила и конкретную проверку. **Почему.** Механизация — состояние конкретного репозитория, канон о ней не @@ -181,7 +185,7 @@ prefix: META ### META-9. Общая механизация разрешает удалить норму из канона **ДОПУСКАЕТСЯ.** Правило, уехавшее в общий конфиг линтера или в общую роль, -удаляется из канона одним `push`. +удаляется из канона. **Почему.** Формулировка, дублирующая работающую у всех проверку, размазывает внимание: файл на несколько сотен строк заставляет человека и @@ -232,15 +236,15 @@ prefix: META ### META-14. Отступления перечисляются поимённо, со ссылкой на правила -**ДОЛЖЕН.** В локальном регионе перечислены отступления, которые уже есть в -коде, с идентификатором правила и причиной. +**ДОЛЖЕН.** В локальной части копии перечислены отступления, которые уже +есть в коде, с идентификатором правила и причиной. **Почему.** Иначе репозиторий выглядит соблюдающим конвенцию, а проверить это можно только чтением всего кода. Со ссылками отступления счётны: видно, -сколько правил конвенции репозиторий реально не соблюдает. Пустой регион при +сколько правил конвенции репозиторий реально не соблюдает. Пустой список при этом почти всегда означает не отсутствие отступлений, а то, что их не искали. -### META-15. Запись в регионе отступлений разбирается по масштабу +### META-15. Запись об отступлении разбирается по масштабу **ДОЛЖЕН.** Судьба записи зависит от того, что в ней сказано: @@ -256,15 +260,35 @@ prefix: META правила в каноне, которую чинят один раз для всех, или лишнюю подписку, где файл просто не нужен. Оставленная отступлением, она прячет обе. -### META-17. Репо-специфичная часть «Связано» — в локальном регионе +### META-17. Ссылки на код репозитория стоят в локальной части, а не в «Связано» -**ДОЛЖЕН.** Раздел «Связано» стоит в конце файла; канонические ссылки — в -общем тексте, ссылки на ADR, код и файлы конкретного репозитория — в -локальном регионе. +**ДОЛЖЕН.** Раздел «Связано» канона содержит только ссылки, верные у всех +потребителей; ссылки на ADR, код и файлы конкретного репозитория — в +локальной части копии. -**Почему.** Общий текст уезжает `push`-ем ко всем потребителям, и ссылка на -чужой файл у них битая с первого дня. Регион исключён из сравнения, поэтому -та же ссылка внутри него никого не задевает и не даёт вечного шума в `diff`. +**Почему.** Текст канона приезжает ко всем потребителям, и ссылка на чужой +файл у них битая с первого дня. Ниже маркера та же ссылка никого не +задевает и переживает обновление, потому что обновление её не трогает. + +### META-22. Репозиторное в копии пишется ниже маркера локальной части + +**ДОЛЖЕН.** Правки репозитория вносятся ниже маркера, а не в текст, +пришедший из канона. + +**Почему.** Обновление перезаписывает всё, что выше маркера, поэтому правка +там живёт до первого `pull`. Заметить пропажу можно, только вычитав +`git diff` целиком — а он в этот момент и без того полон изменений канона, +и своя строка теряется среди чужих. + +### META-23. Документ, переставший быть копией, не носит `origin:` + +**НЕ ДОЛЖЕН.** Файл, который развели с каноном намеренно, шапку `origin:` +не сохраняет. + +**Почему.** По `origin:` решается, какие файлы пересобирать из канона. Форк, +оставивший шапку, при первом же обновлении теряет ровно то, ради чего его +заводили. Происхождение такого документа остаётся в истории коммита, где оно +никого не вводит в заблуждение. ### META-18. README директории перечисляет конвенции с однострочным описанием @@ -284,6 +308,3 @@ prefix: META идентификатором служит и напоминанием, и адресом, по которому за подробностями идут; перенос деталей туда же вернул бы задачу поддержки двух текстов. - - - diff --git a/LANGUAGE.md b/LANGUAGE.md index 924bed0..a467711 100644 --- a/LANGUAGE.md +++ b/LANGUAGE.md @@ -12,10 +12,10 @@ Не ради строгости. Три конкретные вещи, которые без адресуемых правил не работают: -- **Механизация.** Регион `механизировано` должен говорить «правило - `MIGR-4` проверяет `archrules`», а не «`AUTOINCREMENT` в новых миграциях — - `archrules`»: во втором случае читатель сам догадывается, к какому - утверждению это относится, и догадывается по-разному. +- **Механизация.** Запись о ней должна говорить «правило `MIGR-4` проверяет + `archrules`», а не «`AUTOINCREMENT` в новых миграциях — `archrules`»: во + втором случае читатель сам догадывается, к какому утверждению это + относится, и догадывается по-разному. - **Отступления.** «У нас не так» бесполезно, пока не сказано, что именно «не так». Со ссылкой на правило отступления становятся счётными: видно, сколько правил конвенции репозиторий реально не соблюдает. @@ -79,7 +79,7 @@ Модальность живёт на **правиле**, а не на файле. Прежний файловый статус (`status: рекомендуемая` / `обязательная` в шапке) отменён: он неизбежно врал, потому что один файл смешивает жёсткие требования с советами. В шапке -остаются только `prefix`, `extends` и служебные ключи копии. +остаются только `prefix` и `extends`. Мы **не используем SHALL и прочие английские ключевые слова**. Они заняты спецификациями (OpenSpec), и общий словарь стирал бы границу «конвенция — @@ -179,22 +179,21 @@ AND тик фонового цикла упал по той же причине («новые таблицы; существующие не переписываются»). Это рамка для всех правил файла, а не правило. - **Связано** — ссылки на смежные конвенции, ADR, код. -- **Локальные регионы** — содержимое принадлежит репозиторию. +- **Локальная часть копии** — содержимое принадлежит репозиторию. - Вводная проза, объясняющая предмет конвенции. ## Как на правила ссылаются копии -В репозитории: +Ниже маркера локальной части, в репозитории: ```markdown - -MIGR-2, MIGR-4 — `internal/archrules` (проверяются в новых миграциях). - + - -MIGR-6 — не соблюдается в легаси-таблицах `show_history`, `queue`: составные +MIGR-2, MIGR-4 механизированы — `internal/archrules` (проверяются в новых +миграциях). + +MIGR-6 не соблюдается в легаси-таблицах `show_history`, `queue`: составные ключи там появились до конвенции, переписывание требует миграции данных. - ``` Отсюда видно и то, чего раньше не было видно: конвенция из восьми правил, @@ -211,8 +210,10 @@ MIGR-6 — не соблюдается в легаси-таблицах `show_hi берёт следующий свободный, а не первый освободившийся); - у каждого `### <ПРЕФИКС>-` есть модальное слово (или отметка МЕХАНИЗИРОВАНО) и блок «Почему»; -- ссылки вида `<ПРЕФИКС>-` — хоть в тексте канона, хоть в локальных - регионах копии — указывают на правила, которые ещё существуют; +- ссылки вида `<ПРЕФИКС>-` — хоть в тексте канона, хоть в локальной части + копии — указывают на правила, которые ещё существуют; +- префиксы локальных правил копии начинаются на `X` и не совпадают с + реестром канона; - чужой префикс не встречается в абзаце с модальностью (META-20); - путь файла канона не встречается в тексте конвенции (META-21); - модальные слова не встречаются вне правил. diff --git a/README.md b/README.md index 55b8ef5..a03a6a6 100644 --- a/README.md +++ b/README.md @@ -3,22 +3,21 @@ Общие конвенции для личных проектов. Репозитории берут отсюда копии в свой `docs/conventions/`, коммитят их и живут дальше самостоятельно — как с `ansible-roles`: канон не источник истины во время работы, а лавка, из -которой берут и в которую возвращают улучшения. +которой берут. Сами конвенции лежат в `conventions/`, обвязка — в корне: | Файл | Что описывает | |---|---| -| `README.md` | устройство канона, оси, синхронизация, жизненный цикл | +| `README.md` | устройство канона, оси, сборка копий, жизненный цикл | | [LANGUAGE.md](LANGUAGE.md) | язык записи правил: идентификаторы, модальность, «Почему» | | [GUIDE.md](GUIDE.md) | как ведут конвенции: когда заводить, механизация, отступления | | `prefixes.toml` | реестр префиксов правил | -| `conv` | синхронизация копий | +| `conv` | сборка копий | -Обвязка живёт только в каноне и в репозитории не оказывается — `conv` -синхронизирует лишь содержимое `conventions/`. Пока это осознанное -ограничение: копия конвенции ссылается на `LANGUAGE.md` как на внешний -документ. +Обвязка живёт только в каноне и в репозитории не оказывается — в копию едет +лишь содержимое `conventions/`. Пока это осознанное ограничение: копия +конвенции ссылается на `LANGUAGE.md` как на внешний документ. Правило то же, что у ролей: **деплоится и читается только то, что лежит в git репозитория**. Канон никем не подключается на лету. @@ -28,7 +27,7 @@ git репозитория**. Канон никем не подключаетс Конвенция формулируется независимо от конкретного приложения. Она задаёт правило; код ему следует. Обратное направление запрещено: то, что приложение уже делает иначе, **не является аргументом против правила** — это -отступление, и его место в локальном регионе того репозитория, а не в +отступление, и его место в локальной части копии того репозитория, а не в переформулировке канона. Отсюда практические следствия: @@ -51,11 +50,12 @@ conventions/ stack/<стек>/ привязка к инструменту, хранилищу, транспорту ``` -Пути **файлов** даются относительно `conventions/`: `arch/db-identifiers.md`, -а не `conventions/arch/…` — так же, как они лягут в `docs/conventions/` -репозитория. На **правила** ссылаются идентификатором без пути: `KEYS-5`. -Префикс уникален по всему канону (реестр — `prefixes.toml`), поэтому -идентификатор не зависит от того, на какой оси файл лежит сегодня. +Оси — раскладка **канона**; в репозитории копия лежит плоско, файлом на +тему. Пути файлов даются относительно `conventions/` +(`arch/db-identifiers.md`) и адресуют исходник канона, а не место в копии. +На **правила** ссылаются идентификатором без пути: `KEYS-5`. Префикс +уникален по всему канону (реестр — `prefixes.toml`), поэтому идентификатор +не зависит ни от оси, ни от того, как собран файл у потребителя. Тест — по тому, замена чего убивает правило: @@ -93,6 +93,12 @@ prefix: KEYS по формуле, и не переиспользуется никогда. Правила адресуются идентификатором `KEYS-5` — без пути к файлу. Подробности формы — `LANGUAGE.md`. +Буква `X` в начале префикса зарезервирована за репозиториями: канон её не +занимает никогда, а локальные правила потребителя берут префиксы только на +неё (`XTIM`, `XLOG`). Так столкновение локального префикса с будущим +префиксом канона невозможно по построению, и согласовывать заранее ничего не +нужно. + ## Расширение Файл в `lang/` или `stack/` может объявить в шапке ещё и базу: @@ -106,67 +112,88 @@ extends: arch/db-identifiers.md неверно сформулировано условие применимости (чинится в каноне), либо репозиторий на базу просто не подписан. -`extends` — документация связи, а не механизм: `conv` о ней только -напоминает при `add` и никак не следит за тем, чтобы база лежала рядом. +`extends` — документация связи, а не механизм: за тем, чтобы база лежала +рядом, никто не следит. -## Служебная разметка +## Копия в репозитории -**Шапка копии** ставится при `conv add` и в каноне не хранится: - -```yaml ---- -origin: arch/time.md # откуда взято -origin_hash: a1b2c3d4 # отпечаток канона на момент синхронизации -synced: 2026-07-25 -local: нет # или: чем и почему разошлись ---- -``` - -`origin_hash` — контент-отпечаток, а не git-SHA. Он позволяет отличать -«канон обновился» от «изменено локально»; без него `status` умеет только -«differs», а такой отчёт быстро перестают читать. Прочие ключи шапки -(`prefix`, `extends`) — часть документа: они сравниваются наравне с телом. - -**Локальные регионы** — куски, принадлежащие репозиторию по определению. -Из сравнения исключаются, поэтому вечного шума в `diff` не дают: - -```markdown - -`AUTOINCREMENT` в новых миграциях — `internal/archrules`. - -``` - -Имя обязательно — перенос при `pull` идёт по именам, безымянные регионы -`conv` отвергает. Что всегда локально: - -- **механизация** — канон не знает, у кого линтер уже настроен; -- **отступления** — «у нас пока не так», честно и поимённо; -- **разрешение условия** — «Здесь: INTEGER PK, id наружу не выходят»; -- **эталоны и ссылки** — имена функций, файлов, ADR конкретного репозитория; -- **список конвенций** в README репозитория. - -Путь файла в каноне и имя региона — это API: переименование осиротит все -копии (`origin` строковый). Переименовывать — только вместе с обходом -потребителей. - -После `pull` копию нужно перечитать глазами: содержимое региона могло -устареть относительно переписанного вокруг текста, и автоматика этого не -увидит. - -## Раскладка в репозитории - -Копии повторяют структуру канона: +Копия плоская: **один файл на тему**, слои осей идут внутри него секциями в +порядке `arch` → язык → стек. Пути канона в копии не воспроизводятся. ``` docs/conventions/ - README.md собственный, не синхронизируется - arch/db-identifiers.md - lang/go/db-identifiers.md + README.md собственный, не собирается + time.md arch/time.md + lang/go/time.md + db-identifiers.md arch/db-identifiers.md + lang/go/db-identifiers.md + app-directories.md arch/… + stack/ansible/… ``` -Подписка не описана отдельным файлом — она **и есть** набор лежащих файлов, -видимый в `git ls-files`. README директории перечисляет их одной плоской -таблицей, чтобы вложенность не мешала навигации. +Так конвенция остаётся самодостаточным документом: тот, кто проверяет по ней +код — человек или агент, — читает один файл и не собирает тему из трёх мест. + +**Шапка копии** ставится при сборке и в каноне не хранится: + +```yaml +--- +origin: time +--- +``` + +Больше в шапке ничего нет. Отпечатка канона и даты синхронизации в ней не +хранится: обновление перезаписывает файл в рабочем дереве, и что именно +изменилось, показывает `git diff` до коммита. Второй механизм сравнения +рядом с git не нужен. + +**Маркер локальной части** — единственная машинно значимая разметка внутри +файла: + +```markdown + + +MIGR-2, MIGR-4 механизированы — `internal/archrules`. +MIGR-6 не соблюдается в `show_history`, `queue`: составные ключи там +появились до конвенции, миграция данных не окупается. +``` + +Всё ниже маркера принадлежит репозиторию и переживает обновление; всё выше — +пересобирается из канона. Маркер один и безымянный, поэтому у него нет +имени, которое можно осиротить переименованием. + +Ниже маркера живёт то, чего канон о репозитории не знает: механизация, +отступления, разрешение условий («Здесь: INTEGER PK, id наружу не выходят»), +ссылки на ADR и код, а также **собственные правила** — с префиксом на `X`, +по тем же правилам формы, что и канон. + +Если местных правок стало больше, чем каноничного текста, копия перестаёт +быть копией: `origin:` из шапки убирают, и дальше это обычный документ +репозитория. Файл, оставивший шапку, при следующем обновлении потеряет +всё, что выше маркера. + +## Манифест + +Откуда взяты копии и где брать обновления — `.conventions.toml` в корне +репозитория-потребителя: + +```toml +source = "ssh://git@git.vakhrushev.me:2222/av/dev-conventions.git" + +lang = ["go"] +stack = ["sqlite", "htmx"] + +topics = ["time", "config", "db-identifiers"] +``` + +`lang` и `stack` выбирают строку разреженной матрицы: файл темы собирает +только те слои, которые репозиторию подходят. `topics` — подписка; списка +подписчиков у канона по-прежнему нет, список тем есть только у потребителя. + +Как именно инструмент добирается до канона — путь на диске, git, HTTP — +дело инструмента, а не модели. Манифест отвечает на два вопроса: откуда это +взято и где искать обновления. + +Отдельного лок-файла нет. Он отвечал бы на «что было в прошлый раз», а на +это отвечает git: копии закоммичены, автоматического обновления не +существует, и любое изменение проходит через чтение диффа человеком. ## Контракт с агентом @@ -175,45 +202,53 @@ docs/conventions/ `AGENTS.md` каждого потребителя должен явно говорить: > Файлы в `docs/conventions/` с шапкой `origin:` — копии из канона -> `dev-conventions`. Репозиторное пишется только внутрь -> ``. Правка вне регионов — либо `conv push` в канон, либо -> запись причины в `local:`. +> `dev-conventions`. Репозиторное пишется только ниже ``; +> всё выше маркера перезаписывается при обновлении. Своё правило — с +> префиксом на `X`. ## Команды ```bash -conv list # что есть в каноне -conv add arch/time.md # взять к себе (можно несколько за раз) -conv status # ok / изменено локально / канон обновился / разошлись -conv diff [arch/time.md] # чем копия отличается, без учёта локальных регионов -conv pull arch/time.md # забрать обновление канона (регионы переносятся) -conv push arch/time.md # вернуть локальное улучшение в канон -conv push --new lang/go/x.md # завести в каноне новую конвенцию +conv list # какие темы есть в каноне +conv add time # добавить тему в манифест и собрать файл +conv pull # пересобрать всё, что перечислено в манифесте ``` -`status` и `diff` всегда завершаются кодом 0: это отчёт, а не проверка. -Расхождение — нормальное состояние, а постоянный шум в `diff` означает не -«догони канон», а «пора разрезать файл». Симметрично: разросшийся до спора -с базой локальный регион означает «пора чинить условие применимости в -каноне». +Отчёт о том, что изменилось, отдельной командой не выдаётся: после `pull` +его показывает `git diff`, а решение — принять, поправить или откатить — +принимает человек перед коммитом. + +Транспорт обратно в канон не предусмотрен. Улучшение, найденное в +репозитории, переносится в канон руками: это редкая операция, и её цена — +не аргумент против того, чтобы направление оставалось односторонним. Запускать из корня репозитория: ```bash -~/projects/private/dev-conventions/conv status +~/projects/private/dev-conventions/conv pull ``` -Обёртка в раннере репозитория (`inv conventions -- status` для ansible, -`task conventions -- status` для Go) — тонкий проброс аргументов, чтобы +Обёртка в раннере репозитория (`inv conventions -- pull` для ansible, +`task conventions -- pull` для Go) — тонкий проброс аргументов, чтобы логика не размножалась по репозиториям в двух диалектах. ## Жизненный цикл - **В канон.** Новая конвенция пишется в том репозитории, где заболело, и - продвигается `conv push --new`. Локальные регионы при этом опустошаются: - в канон едет только норма. + переносится в канон, когда стало ясно, что общего в ней больше, чем + местного. Локальная часть при этом не едет: в канон попадает только норма, + а префикс на `X` меняется на канонический — то есть правила получают новые + идентификаторы. - **Из канона.** Устаревшая конвенция удаляется вместе с обходом потребителей — тихо осиротить копии нельзя. -- **История.** Канон коммитится при каждом `push`: `origin_hash` отвечает - на «отличается ли», но только git канона отвечает на «почему база - сформулирована так». +- **История.** Канон коммитится при каждой правке: только git канона + отвечает на вопрос, почему база сформулирована так. + +## Состояние + +Модель выше — согласованная, а не реализованная. `conv` пока собран под +прежнюю: зеркальное дерево копий вместо плоского, именованные регионы +`` вместо одного маркера, `origin_hash` в шапке и команды +`status`, `diff`, `push`. Двенадцать файлов канона всё ещё несут 31 пустой +именованный регион. Ни один репозиторий-потребитель не подключён, поэтому +переход никого не ломает. diff --git a/prefixes.toml b/prefixes.toml index 10112a8..5d7b10a 100644 --- a/prefixes.toml +++ b/prefixes.toml @@ -21,8 +21,10 @@ # Пути даются от корня репозитория, а не от `conventions/`: реестр покрывает # и обвязку тоже. # -# Локальные правила репозиториев берут свои префиксы и объявляют их в -# `.conventions.toml` копии. Они обязаны не пересекаться с этим реестром. +# Буква `X` в начале префикса зарезервирована за репозиториями-потребителями: +# канон её не занимает никогда, локальные правила берут префиксы только на +# неё (XTIM, XLOG). Согласовывать их с этим реестром не нужно — столкновение +# невозможно по построению. [live] DIRS = "conventions/arch/app-directories.md"