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