- TOOL.md был стартовой точкой разработки инструмента и свою задачу выполнил: решения о нём теперь живут в его собственном репозитории, открытые вопросы перенесены туда же - питоновский conv собран под прежнюю модель копий (зеркальное дерево, именованные регионы, origin_hash) и удалён вместе с ней - команды в README.md переписаны на convy, включая suite-сторону и sync
145 lines
11 KiB
Markdown
145 lines
11 KiB
Markdown
# К обсуждению
|
||
|
||
Черновик для следующего разговора: вопросы и варианты, а не принятые
|
||
решения. Закрытый вопрос отсюда удаляется — принятое решение живёт в
|
||
`README.md`, `GUIDE.md` или `LANGUAGE.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): объявление
|
||
без реестра проверяется только глазами.
|
||
|
||
Напрашивается секция в `.conventions-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` каждого потребителя про то, что файлы в директориях
|
||
конвенций — копии. Компонент у обоих кандидатов один, но записывается явно.
|