Files
dev-conventions/TODO.md
T
av 9c86d9f2de компоненты как адресат сборки и плоский набор
- компонент — область репозитория, где выбранные слои действуют
  одновременно; сборка идёт по разу на компонент, у каждого своя директория
  копий, подписка и локальная часть, секции [components.<имя>] в манифесте
- плоский набор описан как низкий конец модели, а не отдельный режим: тема с
  одним слоем собирается копированием, ключи оси и lang/stack не пишутся
- в TODO заведён вопрос о реестре значений осей и судьбе extends:
2026-07-26 22:01:39 +03:00

145 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# К обсуждению
Черновик для следующего разговора: вопросы и варианты, а не принятые
решения. Закрытый вопрос отсюда удаляется — принятое решение живёт в
`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` каждого потребителя про то, что файлы в директориях
конвенций — копии. Компонент у обоих кандидатов один, но записывается явно.