темы: определение, объявление в шапке и манифест набора

- тема — набор правил об одном фокусе разработки, имя латиницей (нижний
  kebab-case рекомендуется, годится любой идентификатор, пригодный для имени
  файла); определение в LANGUAGE.md и README.md
- заведены META-28 и META-29: тема объявляется в шапке (`topic:`), стоит в
  манифесте набора и не переиспользуется; `topic:` добавлен во все 12 файлов
- prefixes.toml и topics.toml слиты в manifest.toml — манифест набора против
  манифеста подключения `.conventions.toml`, разделы topics/prefixes с live
  и retired
This commit is contained in:
av
2026-07-26 15:27:55 +03:00
parent d5118336cb
commit c1cb240540
19 changed files with 274 additions and 126 deletions
+54 -16
View File
@@ -12,7 +12,7 @@
| `README.md` | устройство канона, оси, сборка копий, жизненный цикл |
| [LANGUAGE.md](LANGUAGE.md) | язык записи правил: идентификаторы, модальность, обоснование |
| [GUIDE.md](GUIDE.md) | как ведут конвенции: когда заводить, механизация, отступления |
| `prefixes.toml` | реестр префиксов правил |
| [manifest.toml](manifest.toml) | манифест набора: темы и префиксы правил |
| `conv` | сборка копий |
Обвязка живёт только в каноне и в репозитории не оказывается — в копию едет
@@ -55,8 +55,9 @@ conventions/
тему. Пути файлов даются относительно `conventions/`
(`arch/db-identifiers.md`) и адресуют исходник канона, а не место в копии.
На **правила** ссылаются идентификатором без пути: `KEYS-5`. Префикс
уникален по всему канону (реестр — `prefixes.toml`), поэтому идентификатор
не зависит ни от оси, ни от того, как собран файл у потребителя.
уникален по всему канону (он перечислен в манифесте набора), поэтому
идентификатор не зависит ни от оси, ни от того, как собран файл у
потребителя.
Тест — по тому, замена чего убивает правило:
@@ -81,6 +82,31 @@ conventions/
пласт `stack/sqlite/` (типы колонок). Это не принцип, а незавершённая
работа.
## Темы
**Тема — набор правил об одном фокусе разработки:** время, конфигурация,
схема БД. Она же единица подписки и единица сборки: потребитель берёт тему
целиком, а сборщик складывает в один файл все её слои.
Имя темы записывается латиницей; рекомендуется нижний kebab-case, но годится
любой идентификатор, пригодный для имени файла — имя попадает и в файловую
систему потребителя, и в его манифест. Файл конвенции объявляет тему в шапке:
```yaml
topic: db-identifiers
prefix: KEYS
```
Слои одной темы несут одно и то же имя — по нему они и собираются в один
документ, как бы ни назывались их файлы. Имя файла повторяет тему из
удобства, но истина — в шапке.
Темы перечислены в манифесте набора — [`manifest.toml`](manifest.toml),
секция `[topics.live]`: имя и однострочное описание. Имя темы не
переиспользуется по той же причине, что и префикс: оно живёт в чужих
репозиториях — в шапке `origin:` каждой копии, в подписке манифеста, в тексте
ссылок, — и выданное второй теме начинает указывать на другой набор правил.
## Префиксы
Каждый файл канона объявляет в шапке свой префикс правил:
@@ -89,10 +115,11 @@ conventions/
prefix: KEYS
```
Четыре заглавные латинские буквы, уникальные по всему канону; реестр —
[`prefixes.toml`](prefixes.toml). Префикс выбирается под файл, а не выводится
по формуле, и не переиспользуется никогда. Правила адресуются идентификатором
`KEYS-5` — без пути к файлу. Подробности формы — `LANGUAGE.md`.
Четыре заглавные латинские буквы, уникальные по всему канону; перечислены в
манифесте набора, секция `[prefixes.live]`. Префикс выбирается под файл, а не
выводится по формуле, и не переиспользуется никогда. Правила адресуются
идентификатором `KEYS-5` — без пути к файлу. Подробности формы —
`LANGUAGE.md`.
Буква `X` в начале префикса зарезервирована за репозиториями: канон её не
занимает никогда, а локальные правила потребителя берут префиксы только на
@@ -140,10 +167,11 @@ origin: time
---
```
Больше в шапке ничего нет. Отпечатка канона и даты синхронизации в ней не
хранится: обновление перезаписывает файл в рабочем дереве, и что именно
изменилось, показывает `git diff` до коммита. Второй механизм сравнения
рядом с git не нужен.
В `origin:` стоит имя темы — то же, что в манифесте набора и в шапках
`topic:` слоёв, из которых файл собран. Больше в шапке ничего нет: отпечатка
канона и даты синхронизации в ней не хранится, потому что обновление
перезаписывает файл в рабочем дереве, и что именно изменилось, показывает
`git diff` до коммита. Второй механизм сравнения рядом с git не нужен.
**Маркер локальной части** — единственная машинно значимая разметка внутри
файла:
@@ -170,10 +198,18 @@ MIGR-6 не соблюдается в `show_history`, `queue`: составны
репозитория. Файл, оставивший шапку, при следующем обновлении потеряет
всё, что выше маркера.
## Манифест
## Два манифеста
Откуда взяты копии и где брать обновления — `.conventions.toml` в корне
репозитория-потребителя:
Манифестов в модели два, и они отвечают на разные вопросы:
| Файл | Где лежит | Что описывает |
|---|---|---|
| `manifest.toml` | в наборе | сам набор: темы и префиксы правил |
| `.conventions.toml` | в проекте | подключение: откуда копии, какие темы, язык, стек |
Манифест набора — единственное место, где перечислены оба идентификатора
канона; правила у них общие, поэтому и файл один. Манифест подключения
отвечает, откуда взяты копии и где брать обновления:
```toml
source = "ssh://git@git.vakhrushev.me:2222/av/dev-conventions.git"
@@ -185,8 +221,10 @@ topics = ["time", "config", "db-identifiers"]
```
`lang` и `stack` выбирают строку разреженной матрицы: файл темы собирает
только те слои, которые репозиторию подходят. `topics` — подписка; списка
подписчиков у канона по-прежнему нет, список тем есть только у потребителя.
только те слои, которые репозиторию подходят. `topics` — подписка, именами из
манифеста набора; списка подписчиков у канона по-прежнему нет, список подписок
есть
только у потребителя.
Как именно инструмент добирается до канона — путь на диске, git, HTTP —
дело инструмента, а не модели. Манифест отвечает на два вопроса: откуда это