Files
dev-conventions/TODO.md
T
av 11fc9e1fee guide: заведены критерии границы темы — META-33…META-36
- тема определяется решением, а не веществом (META-33) и нужна потребителю
  целиком (META-34); слой сужает базу, но не отменяет её (META-35), иначе
  это другая тема, а вид приложения называется в области действия (META-36)
- добавлен раздел «Как проверить границу темы»: пять вопросов со ссылками
  на правила, включая META-20; те же строки в CLAUDE.md, а в LANGUAGE.md
  оговорка, что граница темы языку не принадлежит
- в TODO заведён прогон восьми тем по критериям с разбором подозреваемых:
  шесть правил time выносят вердикты чужих тем, logging мешает три страта
2026-07-26 21:25:24 +03:00

9.6 KiB
Raw Blame History

К обсуждению

Черновик для следующего разговора: вопросы и варианты, а не принятые решения. Закрытый вопрос отсюда удаляется — принятое решение живёт в 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. Пары слоёв и темы без базы

Отложено сознательно, но список стоит держать перед глазами:

  • 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-слой — единственные ссылки стек → язык в каноне.

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. Понадобится: заполнить локальную часть копий тем, что сейчас в этих репозиториях записано по факту; обёртка в раннере (inv conventions / task conventions, единый интерфейс команд у трёх ansible-репозиториев); строка в AGENTS.md каждого потребителя про то, что файлы в docs/conventions/ — копии.