diff --git a/CLAUDE.md b/CLAUDE.md index 4eb564c..96fae41 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -135,13 +135,30 @@ code in this repository. живут в копии ниже маркера `` (META-22), который ставит сборщик. Заводить пустые местные разделы в каноне не нужно. +## Граница темы + +Пять вопросов, по которым тему проверяют на «не хапнули ли лишнего»; сначала +разрез темы, ось — потом. + +- META-33: правило стоит в теме, чей вопрос оно решает. Тема — решение, а не + вещество: «время» проходит через несколько решений сразу, и правило о + колонках БД принадлежит схеме, а не времени. +- META-34: тема нужна потребителю целиком — подписка берёт её без остатка. + Если два правдоподобных потребителя хотят непересекающиеся части, между + ними и проходит граница. +- META-35: слой сужает базу, но не отменяет её. Приходится отменять — это не + слой, а другая тема; общим осталось слово, а не решение. +- META-36: вид приложения (веб-сервис, CLI, плейбуки, библиотека) называется + в области действия, если норма от него зависит. Осью он не является. +- META-20: норма исполнима без соседних тем. + ## Выбор оси Умирает при смене языка → `lang/<язык>/`. Умирает при смене инструмента, хранилища или транспорта → `stack/<стек>/`. Не умирает ни от того, ни от другого → `arch/`. Ось определяется природой правила, а не числом сегодняшних потребителей. `extends: arch/<файл>.md` в шапке — документация связи, а не -механизм; слой только реализует и сужает базу, но не отменяет её. +механизм; слой только реализует и сужает базу, но не отменяет её (META-35). ## Оформление файла diff --git a/GUIDE.md b/GUIDE.md index 180f619..2696ab8 100644 --- a/GUIDE.md +++ b/GUIDE.md @@ -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:` с именем темы, и это имя стоит в diff --git a/LANGUAGE.md b/LANGUAGE.md index 57aa17a..c711123 100644 --- a/LANGUAGE.md +++ b/LANGUAGE.md @@ -625,6 +625,10 @@ XMIG-6 не соблюдается в легаси-таблицах `show_histor - примеры иллюстрируют норму и не расширяют её: деталь примера не читается как требование. +Проверки выше — про запись правила. Граница самой темы (не собрала ли она +два решения сразу, нужна ли потребителю целиком) языку не принадлежит: её +вопросы стоят в документе, которым набор ведёт себя. + ## Версия языка Номер версии называется в каждой конвенции, поэтому он двигается, когда diff --git a/TODO.md b/TODO.md index fb539f9..340364c 100644 --- a/TODO.md +++ b/TODO.md @@ -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. Понадобится: заполнить локальную часть копий тем, что сейчас в этих