guide: заведены критерии границы темы — META-33…META-36

- тема определяется решением, а не веществом (META-33) и нужна потребителю
  целиком (META-34); слой сужает базу, но не отменяет её (META-35), иначе
  это другая тема, а вид приложения называется в области действия (META-36)
- добавлен раздел «Как проверить границу темы»: пять вопросов со ссылками
  на правила, включая META-20; те же строки в CLAUDE.md, а в LANGUAGE.md
  оговорка, что граница темы языку не принадлежит
- в TODO заведён прогон восьми тем по критериям с разбором подозреваемых:
  шесть правил time выносят вердикты чужих тем, logging мешает три страта
This commit is contained in:
av
2026-07-26 21:25:24 +03:00
parent b516bfb02c
commit 11fc9e1fee
4 changed files with 125 additions and 2 deletions
+18 -1
View File
@@ -135,13 +135,30 @@ code in this repository.
живут в копии ниже маркера `<!-- conv:local -->` (META-22), который ставит
сборщик. Заводить пустые местные разделы в каноне не нужно.
## Граница темы
Пять вопросов, по которым тему проверяют на «не хапнули ли лишнего»; сначала
разрез темы, ось — потом.
- META-33: правило стоит в теме, чей вопрос оно решает. Тема — решение, а не
вещество: «время» проходит через несколько решений сразу, и правило о
колонках БД принадлежит схеме, а не времени.
- META-34: тема нужна потребителю целиком — подписка берёт её без остатка.
Если два правдоподобных потребителя хотят непересекающиеся части, между
ними и проходит граница.
- META-35: слой сужает базу, но не отменяет её. Приходится отменять — это не
слой, а другая тема; общим осталось слово, а не решение.
- META-36: вид приложения (веб-сервис, CLI, плейбуки, библиотека) называется
в области действия, если норма от него зависит. Осью он не является.
- META-20: норма исполнима без соседних тем.
## Выбор оси
Умирает при смене языка → `lang/<язык>/`. Умирает при смене инструмента,
хранилища или транспорта → `stack/<стек>/`. Не умирает ни от того, ни от
другого → `arch/`. Ось определяется природой правила, а не числом сегодняшних
потребителей. `extends: arch/<файл>.md` в шапке — документация связи, а не
механизм; слой только реализует и сужает базу, но не отменяет её.
механизм; слой только реализует и сужает базу, но не отменяет её (META-35).
## Оформление файла
+76
View File
@@ -63,6 +63,22 @@ prefix: META
канон, или документ, переставший быть копией, — тогда `origin:` из шапки
убирают.
## Как проверить границу темы
Готовая тема проходится по пяти вопросам; на каждый отвечает своё правило:
- на какой вопрос отвечает правило — и тот ли это вопрос, что у темы
(META-33);
- нужна ли тема правдоподобному потребителю целиком (META-34);
- слой сужает базу или отменяет её (META-35);
- зависит ли норма от вида приложения и назван ли он (META-36);
- исполнима ли норма, если соседних тем в репозитории нет (META-20).
Расхождение на любом из них означает, что граница проходит не там, где
нарисована: тема собрана вокруг вещества, склеила два решения или молча
предполагает вид приложения. Чинится это разрезом темы или областью
действия, а не смягчением нормы.
## Правила
### META-1. Одна конвенция — один файл
@@ -75,6 +91,66 @@ prefix: META
дорого: перенос правила в другой файл — это новый префикс и новая
нумерация, поэтому после разреза все внешние ссылки обходят руками.
### META-33. Правило стоит в теме, чей вопрос оно решает
**ДОЛЖЕН.** Тема правила определяется вердиктом, который правило выносит, а
не веществом, о котором оно говорит.
**ПОЧЕМУ.** Одно и то же вещество — время, идентификатор, конфигурация —
проходит через несколько решений сразу, и тема, собранная вокруг вещества,
склеивает чужие решения: «в каком виде хранить в базе», «что писать в лог»,
«что отдавать наружу» попадают в один файл на том основании, что все три
говорят о моментах. Подписка после этого промахивается в обе стороны:
репозиторий без базы получает правила о колонках, а репозиторий с базой, не
подписанный на время, правил о своих колонках не получает — хотя они про его
схему. Отличить одно от другого дёшево: вопрос темы выписывается одной
фразой, и норма читается как ответ на него; ответ на чужой вопрос означает,
что правило лежит не в своей теме.
### META-34. Тема нужна потребителю целиком
**СЛЕДУЕТ.** Тема нарезается так, чтобы правдоподобному потребителю
требовалась вся она, а не часть.
**ПОЧЕМУ.** Взять половину темы нечем: подписка перечисляется темами, и
сборщик кладёт файл целиком. Потребитель, которому нужна треть правил,
платит за остальные две трети вычиткой при каждом обновлении и пачкой
отступлений — а пачка отступлений неотличима от небрежности и обесценивает
список, по которому считают реальное соблюдение (META-14). Линия разреза
видна заранее: если два правдоподобных потребителя хотят непересекающиеся
части одной темы, между этими частями и проходит граница. Ступень ниже
высшей потому, что «правдоподобный потребитель» — суждение: двое разойдутся
в том, бывает ли такой репозиторий вообще.
### META-35. Слой сужает базу, но не отменяет её
**НЕ ДОЛЖЕН.** Правило языкового или стекового слоя не требует
противоположного норме арх-слоя своей темы и не снимает её требование.
**ПОЧЕМУ.** Слои темы приезжают в копию одним файлом, секция за секцией, и
исполняются подряд: база и отменяющее её уточнение стоят рядом без указания,
какое из них главнее, — читатель выбирает сам, и вердикт перестаёт быть
воспроизводимым (META-6). Отсюда же тест на границу: если ради нового случая
базу приходится отменять, это не слой, а другая тема — общим у них осталось
слово, а не решение. Сужение слоем остаётся: уточнить, ограничить, назвать
инструмент, разобрать случай, который база предусмотрела.
### META-36. Вид приложения называется, если норма от него зависит
**ДОЛЖЕН.** Норма, верная не для всякого приложения, сопровождается областью
действия, называющей вид приложения, для которого она написана.
**ПОЧЕМУ.** Вид приложения — веб-сервис, программа командной строки, набор
плейбуков, библиотека — меняет вердикт там, где язык и инструмент его не
меняют: лог сервиса читают через месяц запросом, вывод команды — сейчас и
глазами, поэтому уровень записи у них выбирается по-разному. Осями это
измерение не выражено: они отвечают на вопрос, от чего правило умирает, а не
к чему оно применяется, — и единственное место, где вид может быть назван,
область действия. Не названный, он остаётся молчаливым допущением автора:
потребитель другого вида не отличает «правило написано не про меня» от «мы
его нарушаем» и записывает второе, хотя чинится первое — условие
применимости в каноне (META-15.2).
### META-28. Тема объявляется в шапке файла и стоит в манифесте набора
**ДОЛЖЕН.** Шапка несёт ключ `topic:` с именем темы, и это имя стоит в
+4
View File
@@ -625,6 +625,10 @@ XMIG-6 не соблюдается в легаси-таблицах `show_histor
- примеры иллюстрируют норму и не расширяют её: деталь примера не читается
как требование.
Проверки выше — про запись правила. Граница самой темы (не собрала ли она
два решения сразу, нужна ли потребителю целиком) языку не принадлежит: её
вопросы стоят в документе, которым набор ведёт себя.
## Версия языка
Номер версии называется в каждой конвенции, поэтому он двигается, когда
+27 -1
View File
@@ -90,7 +90,33 @@ API, а норму при этом нельзя поправить, не зад
- Вынос арх-ядра из `errors` и `logging` закроет две хрупкие ссылки из
`web-ui` (стек) в go-слой — единственные ссылки стек → язык в каноне.
## 5. Подключение к репозиториям
## 5. Восемь тем не прогнаны по границе
Критерии границы записаны правилами (META-33 … META-36), но ни одна тема по
ним не прочитана. Работа по одной теме: выписать вопрос темы одной фразой и
пройти по правилам, помечая чужие.
Два подозреваемых видно уже сейчас.
`time` собрана вокруг вещества, а не решения (META-33): TIME-2 и TIME-3
(ширина и точность на носитель), TIME-6 (дефолтов в схеме БД нет), GTIM-4
(20 символов в БД), GTIM-8 и GTIM-9 (UTC и точность в логах) выносят вердикты
тем `db-schema` и `logging`. Остаток — представление момента, единая точка
«сейчас», длительность и часы, не-UTC на отображении — тема настоящая. Разрез
попутно снимает `extends: arch/time.md` из вопроса 4.
`logging` лежит целиком в `lang/go`, хотя внутри три страта: уровень по
адресату, «ошибка логируется один раз на границе», секреты — не про Go;
`JSONHandler`, `stdout`, разбор через `jq`/DuckDB — про стек; SLOG-30…33
(входящий запрос, healthcheck, 4xx) — про вид приложения (META-36), то есть
про веб-сервис. Здесь же лежит невыделенное арх-ядро из вопроса 4.
Отдельно проверить обратное: `errors` без арх-слоя — не дефект. Обработка
отказа в плейбуке (`failed_when`, `block`/`rescue`, идемпотентность) го-шные
правила не сужает, а решает другую задачу, значит для плейбуков это своя
тема, а не слой в `errors` (META-35).
## 6. Подключение к репозиториям
Ничего ещё не подключено. Кандидаты — jellybit и pet-project-server.
Понадобится: заполнить локальную часть копий тем, что сейчас в этих