# К обсуждению Черновик для следующего разговора: вопросы и варианты, а не принятые решения. Закрытый вопрос отсюда удаляется — принятое решение живёт в `README.md`, `GUIDE.md`, `LANGUAGE.md` или `TOOL.md`, а не в этом файле. Вопросы про инструмент здесь не живут — они собраны в `TOOL.md`, раздел «Открытые вопросы». Две секции: сначала язык и подход, потом сам набор и подключение. # Язык и подход ## 1. Одиннадцать таблиц не прочитаны на взаимоисключительность `LANGUAGE.md` объявил, что строки таблицы решений взаимоисключающи по умолчанию, а иной порядок объявляется явно. Объявление не делает таблицы такими: нумерованные строки есть в одиннадцати файлах канона, и ни одна таблица под новое требование не прочитана. Конкретный подозреваемый — SLOG-11: «по реальному действию или изменению» против «повторяющаяся служебная, по таймеру или поллингу». Периодическая операция, которая всё-таки меняет данные, подходит под обе строки, и уровень из таблицы не выводится однозначно. Работа читательская, машине не даётся; в список проверок она уже записана в разделе «Чтением, потому что машине не даётся». ## 2. Шесть сниппетов сидят в блоке нормы С появлением блока ПРИМЕРЫ у кода в правиле есть своё место, но шесть правил несут сниппет **внутри блока нормы** — там, где он по границе правила читается как «требуется ровно такой код»: GCFG-7, GCFG-9, SLOG-20, GTIM-8, HTMX-7, HTMX-24. Кода внутри обоснований в каноне нет ни одного, так что разбирать нужно только эти шесть. Разбор по одному, вердикт из двух: сниппет — часть требования или иллюстрация к нему. У GTIM-8 (`ReplaceAttr` с приведением к UTC) это похоже на норму: там важна конкретная точка вмешательства. У HTMX-7 и SLOG-20 — скорее иллюстрация формы вызова, и ей место в ПРИМЕРЫ. Цена ошибки в обе стороны понятна. Оставленный в норме пример превращает деталь кода в требование, которое никто не имел в виду, и устаревает вместе с API, а норму при этом нельзя поправить, не задев требование. Унесённая в ПРИМЕРЫ норма, наоборот, перестаёт быть обязательной — блок иллюстративный. ## 3. Описание языка отдельно от набора конвенций `LANGUAGE.md` и `GUIDE.md` описывают, **как** пишутся конвенции; `conventions/` — **один конкретный** набор. Сейчас они склеены в одном репозитории, и из одного описания нельзя собрать второй набор (рабочий, доменный, чужой). Срочности нет: версия языка объявлена в самом `LANGUAGE.md` (ключ `version:`), и конвенции ссылаются на неё номером, а не путём, — то есть самодостаточность копии выноса не требует. Примеры в `LANGUAGE.md` вдобавок переведены на вымышленные `X`-правила, так что на конкретный набор описание языка больше не ссылается вовсе. Что осталось поводом: - из одного описания по-прежнему нельзя собрать второй набор; - тулинг валидирует правила, зашитые в его код, а не объявленную версию языка. Оба повода включаются, только когда появится второй набор. Цена — ещё одна сущность и ещё одна синхронизация; при одном наборе лечение выходит хуже болезни. # Канон и подключение ## 4. Значения осей нигде не зарегистрированы Ось теперь объявлена в шапке (META-38), но её значения не сверяются ни с чем: `lang: golang` вместо `lang: go` соберётся молча — слой просто не попадёт ни в одну копию. Это ровно та болезнь, от которой лечили тему (META-28): объявление без реестра проверяется только глазами. Напрашивается секция в `suite.toml` рядом с `[topics.live]` и `[prefixes.live]` — перечень живых языков и стеков с однострочным описанием, и те же правила выбытия. Против: третий реестр в манифесте, а значений сегодня три (`go`, `ansible`, `htmx`). За: словарь общий у двух сторон — им же потребитель пишет `lang` и `stack` в своём компоненте, и опечатка там стоит столько же. Заодно решается судьба `extends:`: с объявленной осью база находится сама — это слой той же темы без ключей оси, — так что ключ остался подсказкой человеку и кандидат на снятие. ## 5. Пары слоёв и темы без базы Отложено сознательно, но список стоит держать перед глазами: - `SLOG` объявляет `extends: arch/time.md` — расширение **чужой** темы. Сборщик темы `logging` на это наткнётся: базового слоя с темой `logging` нет, а `arch/time.md` он тянуть не должен. Чинится переводом в обычную ссылку «связано». Вдобавок это ломает гарантию META-24: она верна только для базы своей темы, а `arch/time.md` объявляет тему `time`, не `logging`. С объявленной темой расхождение стало проверяемым машинно. - Темы без арх-слоя: `db-schema`, `errors`, `web-ui`. Собираются в файл с одной секцией — само по себе не ломается, но это и есть тот невыделенный арх-слой из известного долга. - Имена тем в паре не совпадают: `arch/db-identifiers.md` против `lang/go/db-schema.md`. При сборке по имени темы это две разные темы — проверить, что так и задумано. - В `lang/go/db-schema.md` сидит целый пласт `stack/sqlite/` (типы колонок), тоже из известного долга README. - Вынос арх-ядра из `errors` и `logging` закроет две хрупкие ссылки из `web-ui` (стек) в go-слой — единственные ссылки стек → язык в каноне. ## 6. Восемь тем не прогнаны по границе Критерии границы записаны правилами (META-33 … META-37), но ни одна тема по ним не прочитана. Работа по одной теме: выписать вопрос темы одной фразой и пройти по правилам, помечая чужие. Два подозреваемых видно уже сейчас. `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` из вопроса 5. `logging` лежит целиком в `lang/go`, хотя внутри три страта: уровень по адресату, «ошибка логируется один раз на границе», секреты — не про Go; `JSONHandler`, `stdout`, разбор через `jq`/DuckDB — про стек; SLOG-30…33 (входящий запрос, healthcheck, 4xx) — про вид приложения (META-36), то есть про веб-сервис. Здесь же лежит невыделенное арх-ядро из вопроса 5. Отдельно проверить обратное: `errors` без арх-слоя — не дефект. Обработка отказа в плейбуке (`failed_when`, `block`/`rescue`, идемпотентность) го-шные правила не сужает, а решает другую задачу, значит для плейбуков это своя тема, а не слой в `errors` (META-35). ## 7. Подключение к репозиториям Ничего ещё не подключено. Кандидаты — jellybit и pet-project-server. Понадобится: заполнить локальную часть копий тем, что сейчас в этих репозиториях записано по факту; обёртка в раннере (`inv conventions` / `task conventions`, единый интерфейс команд у трёх ansible-репозиториев); строка в `AGENTS.md` каждого потребителя про то, что файлы в директориях конвенций — копии. Компонент у обоих кандидатов один, но записывается явно.