diff --git a/CLAUDE.md b/CLAUDE.md index 4cec1cb..3b47634 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -104,8 +104,9 @@ code in this repository. Шапка `prefix:` (плюс `extends:`) → `# Тема` → вводная проза → отдельным абзацем строка о версии языка (её точный текст — в `LANGUAGE.md`, раздел «Ссылка на язык из конвенции») → `## Область действия` (обязателен для -трудноизменяемых слоёв — META-11) → правила → `## Связано` только с -каноническими ссылками (META-17). Имя файла — kebab-case по теме. Проза +трудноизменяемых слоёв — META-11) → правила → `## Связано`, если +канонические ссылки есть (META-17; пустого раздела не заводят). Имя файла — +kebab-case по теме. Проза переносится по ~76 колонок; таблицы и блоки кода не переносятся. ## Ревью формы @@ -129,9 +130,9 @@ code in this repository. плюс команда). - Модель копий, описанная в `README.md`, согласована, но не реализована: `conv` собран под прежнюю (зеркальное дерево, именованные регионы, - `origin_hash`, команды `status`/`diff`/`push`), и в двенадцати файлах - канона ещё лежит 31 пустой регион `` — их предстоит - удалить. При правке обвязки истина — README, а не код `conv`. + `origin_hash`, команды `status`/`diff`/`push`). Сами конвенции к новой + модели приведены — регионов в каноне нет. При правке обвязки истина — + README, а не код `conv`. - Ни один репозиторий-потребитель ещё не подключён: копий с шапкой `origin:` в природе нет. - `TODO.md` — площадка для обсуждения на будущее, а не принятые решения; при diff --git a/README.md b/README.md index bd6048f..0406783 100644 --- a/README.md +++ b/README.md @@ -250,6 +250,6 @@ conv pull # пересобрать всё, что переч Модель выше — согласованная, а не реализованная. `conv` пока собран под прежнюю: зеркальное дерево копий вместо плоского, именованные регионы `` вместо одного маркера, `origin_hash` в шапке и команды -`status`, `diff`, `push`. Двенадцать файлов канона всё ещё несут 31 пустой -именованный регион. Ни один репозиторий-потребитель не подключён, поэтому -переход никого не ломает. +`status`, `diff`, `push`. Сами конвенции уже приведены к новой модели — +именованных регионов в каноне нет. Ни один репозиторий-потребитель не +подключён, поэтому переход никого не ломает. diff --git a/TODO.md b/TODO.md index 508ec5e..791725d 100644 --- a/TODO.md +++ b/TODO.md @@ -41,22 +41,7 @@ манифеста и `vendir.yml` — как пример того, где проходит граница между «чего хочу» и «что получил». -## 2. Именованные регионы — удалить из канона - -Решение принято и записано: регионов нет, есть один маркер -``, который ставит сборщик в копии. Значит регионы не -переносятся в единую секцию, а **удаляются**: в каноне их нечем наполнять, -локальное принадлежит копии. - -Остаётся механическая работа — **31 регион в 12 файлах**: - -``` -7 связано 7 отступления 7 механизировано -1 эталон / эталоны / словарь / секреты / секретные-поля -1 проверки / поля / модель-владельца / маппинг / границы -``` - -## 3. Пары слоёв и темы без базы +## 2. Пары слоёв и темы без базы Отложено сознательно, но список стоит держать перед глазами: @@ -75,7 +60,7 @@ - Вынос арх-ядра из `errors` и `logging` закроет две хрупкие ссылки из `web-ui` (стек) в go-слой — единственные ссылки стек → язык в каноне. -## 4. Подключение к репозиториям +## 3. Подключение к репозиториям Ничего ещё не подключено. Кандидаты — jellybit и pet-project-server. Понадобится: заполнить локальную часть копий тем, что сейчас в этих @@ -84,7 +69,7 @@ строка в `AGENTS.md` каждого потребителя про то, что файлы в `docs/conventions/` — копии. -## 5. Описание языка отдельно от набора конвенций +## 4. Описание языка отдельно от набора конвенций `LANGUAGE.md` и `GUIDE.md` описывают, **как** пишутся конвенции; `conventions/` — **один конкретный** набор. Сейчас они склеены в одном @@ -105,7 +90,7 @@ сущность и ещё одна синхронизация; при одном наборе лечение выходит хуже болезни. -## 6. Тулинг на Go, живущий независимо +## 5. Тулинг на Go, живущий независимо Сейчас `conv` — питоновский скрипт внутри канона, то есть тулинг и данные в одном репозитории и правятся одним движением. Мысль: вынести в отдельный @@ -114,15 +99,15 @@ Go-бинарь со своим релизным циклом, ставить ч Что за этим стоит помимо вкуса: независимый бинарь физически не даёт править инструмент «заодно» с правкой конвенции, работает против **любого** канона и -любого потребителя — что прямо требуется вопросом 5, — и снимает питон из +любого потребителя — что прямо требуется вопросом 4, — и снимает питон из зависимостей репозиториев-потребителей. -Порядок обратный ожидаемому: пока вопрос 5 не сделан, инструмент всё равно +Порядок обратный ожидаемому: пока вопрос 4 не сделан, инструмент всё равно работает против одного конкретного канона, и независимый релизный цикл ему -нечего обслуживать. Сначала 5, потом 6. Разделение из вопроса 1 при этом +нечего обслуживать. Сначала 4, потом 5. Разделение из вопроса 1 при этом дешевле заложить сразу, чем отпиливать потом. -## 7. META-20 и родительский слой своей темы +## 6. META-20 и родительский слой своей темы Из `lang/` и `stack/` ссылаться на идентификаторы своего же арх-слоя безопасно: при сборке они оказываются секциями одного файла, и ссылка @@ -136,7 +121,7 @@ Go-бинарь со своим релизным циклом, ставить ч говорит «чужой темы», и второе правило про то же место придётся держать согласованным с первым. -## 8. `WHEN`/`AND` в блоке стыка правил +## 7. `WHEN`/`AND` в блоке стыка правил Блок для стыка двух правил записан английскими словами: @@ -162,7 +147,7 @@ OpenSpec. `WHEN` и `AND` — из того же набора и по той ж подпадают ли `WHEN`/`AND` под проверку «заглавные модальные слова не встречаются вне правил»: сейчас формально нет, потому что в словаре их нет. -## 9. Критерий «названного вреда» никого не обязывает +## 8. Критерий «названного вреда» никого не обязывает `LANGUAGE.md` говорит, что ДОЛЖЕН требует двух условий сразу: нарушение причиняет названный вред (критерий BCP 14) и норма проверяема машиной @@ -176,7 +161,7 @@ OpenSpec. `WHEN` и `AND` — из того же набора и по той ж META-6 её защищает. Против: критерий «вред назван» проверяется чтением, а не машиной, — то есть по META-6 сам он может быть только СЛЕДУЕТ. -## 10. Одиннадцать таблиц не прочитаны на взаимоисключительность +## 9. Одиннадцать таблиц не прочитаны на взаимоисключительность `LANGUAGE.md` объявил, что строки таблицы решений взаимоисключающи по умолчанию, а иной порядок объявляется явно. Объявление не делает таблицы @@ -191,7 +176,7 @@ META-6 её защищает. Против: критерий «вред назв Работа читательская, машине не даётся; в список проверок она уже записана в разделе «Чтением, потому что машине не даётся». -## 11. Возможность, записанная модальным словом +## 10. Возможность, записанная модальным словом Четвёртая категория ISO — возможность и осуществимость — ключевого слова не имеет: такие утверждения пишутся обычной прозой. Значит канон надо просмотреть diff --git a/conventions/arch/app-directories.md b/conventions/arch/app-directories.md index 2708045..480c872 100644 --- a/conventions/arch/app-directories.md +++ b/conventions/arch/app-directories.md @@ -153,14 +153,3 @@ prefix: DIRS предупреждения. Вдобавок директория конфигурации может быть подключена только на чтение — тогда запись отказывает в рантайме. Ни то ни другое не видно в момент, когда приложение настраивают. - - - - -## Связано - - - - - - diff --git a/conventions/arch/config.md b/conventions/arch/config.md index 27201a8..7fe43ad 100644 --- a/conventions/arch/config.md +++ b/conventions/arch/config.md @@ -85,8 +85,6 @@ prefix: CONF Приложение, которое запускается вообще без конфигурации, этой конвенцией не описывается: это отдельный случай и отдельная конвенция. - - ### CONF-4. В репозитории лежит образец, а не рабочий конфиг **НЕ ДОЛЖЕН.** Реальный конфиг не коммитится; в репозитории — образец. @@ -233,9 +231,6 @@ prefix: CONF записи. Типичный источник утечки — отладочный дамп разобранного конфига при старте. - - - ### CONF-17. Конфиг валидируется на старте, до приёма трафика **ДОЛЖЕН.** Невалидный конфиг — запись уровня `ERROR` и выход с ненулевым @@ -301,6 +296,3 @@ prefix: CONF конфигурируемый параметр времени, семантика описана там. - конвенция `app-directories` — конфиг лежит в категории «конфигурация» и доступен приложению только на чтение. - - - diff --git a/conventions/arch/db-identifiers.md b/conventions/arch/db-identifiers.md index a5b1d42..4f5fc9f 100644 --- a/conventions/arch/db-identifiers.md +++ b/conventions/arch/db-identifiers.md @@ -134,12 +134,6 @@ KEYS-1 требует **сортируемый** строковый иденти внутри одной миллисекунды порядок произволен, если генератор не монотонный, — на порядок событий это не влияет. - - - ## Связано - конвенция `time` — метки времени тоже генерирует приложение, а не схема. - - - diff --git a/conventions/arch/time.md b/conventions/arch/time.md index 5e7cae3..b1a3460 100644 --- a/conventions/arch/time.md +++ b/conventions/arch/time.md @@ -179,17 +179,8 @@ prefix: TIME Зона по умолчанию здесь та же, что и для отображения (TIME-11); календарная логика, которой нужна другая, получает её тем же явным аргументом. - - - - - - ## Связано - конвенция `config` — где задаётся зона отображения. - конвенция `db-identifiers` — то же правило «генерирует приложение» для идентификаторов. - - - diff --git a/conventions/lang/go/config.md b/conventions/lang/go/config.md index e359909..736ea70 100644 --- a/conventions/lang/go/config.md +++ b/conventions/lang/go/config.md @@ -220,16 +220,7 @@ zoneinfo, а сообщение указывает не на ту причину во внешний сервис и записать в базу от имени процесса, который потом объявит, что не стартовал. - - - - - - ## Связано - конвенция `time` — зона отображения и формат времени. - конвенция `logging` — `slog`, которым падает невалидный конфиг. - - - diff --git a/conventions/lang/go/db-identifiers.md b/conventions/lang/go/db-identifiers.md index ae7f420..5058c19 100644 --- a/conventions/lang/go/db-identifiers.md +++ b/conventions/lang/go/db-identifiers.md @@ -126,9 +126,3 @@ HTTP-кодов. В случае GKEY-8.1 снаружи это неотличи строка не найдена, потому что store её искал. Сфабрикованный транспортом, он утверждает непроверенное, и по типу ошибки перестаёт быть видно, был ли вообще поход в хранилище — а на этом держится вся диагностика по ошибкам. - - - - - - diff --git a/conventions/lang/go/db-schema.md b/conventions/lang/go/db-schema.md index 65d5fc9..98306e6 100644 --- a/conventions/lang/go/db-schema.md +++ b/conventions/lang/go/db-schema.md @@ -189,18 +189,9 @@ down останавливает сразу и заставляет пересо вставке — против этого пренебрежима. Для новых таблиц вопрос не возникает: там ключ строковый (MIGR-11). - - - - - - ## Связано - конвенция `time` — формат меток времени. - конвенция `db-identifiers` — выбор первичных ключей. - конвенция `errors` — граничные ошибки `database/sql` транслируются в доменные у источника, в слое store. - - - diff --git a/conventions/lang/go/errors.md b/conventions/lang/go/errors.md index 83298d2..b6ef410 100644 --- a/conventions/lang/go/errors.md +++ b/conventions/lang/go/errors.md @@ -224,9 +224,6 @@ HTTP-клиентов, файловой системы, внешних SDK. его в `ERROR` вместо `DEBUG`. Второе хуже первого — штатные отказы начинают шуметь в логе ровно там, где по нему ищут настоящие поломки. - - - ### GERR-25. Непокрытая маппингом ошибка — 500 и `ERROR` с признаком **ДОЛЖЕН.** Доменная ошибка, для которой в маппинге (GERR-15) нет ветви, отдаёт @@ -391,6 +388,3 @@ HTTP-клиентов, файловой системы, внешних SDK. - конвенция `logging` — где и когда ошибка попадает в лог. - `KEYS-7` — формат корреляционного ключа из `GERR-14`. - - - diff --git a/conventions/lang/go/logging.md b/conventions/lang/go/logging.md index 5008cde..34e55f4 100644 --- a/conventions/lang/go/logging.md +++ b/conventions/lang/go/logging.md @@ -238,9 +238,6 @@ dev-выводом перестаёшь ежедневно гонять собс появлением нескольких инстансов различающее поле (`service.version`) добавляется одной строкой при старте. - - - ## Корреляция ### SLOG-18. Ключ корреляции — идентификатор сущности, а не `trace_id` @@ -317,9 +314,6 @@ ctx = logctx.With(ctx, log) // достаём логгер из ctx в кажд знает лишь то, что ему вернули ошибку. Побочный эффект того же выбора: транспорты остаются тонкими. - - - ### SLOG-24. Транспорт не логирует ошибку повторно **НЕ ДОЛЖЕН.** Транспорт переводит возвращённую ошибку в свой ответ @@ -530,9 +524,6 @@ API-ключи и токены, `Authorization`-заголовки, аутент санитизацию в каждой такой точке, и одна забытая сводит остальные на нет. Заголовок снимает задачу в источнике: чего нет в URL, того нет и в ошибке. - - - ## Куда пишем ### SLOG-39. Логи идут в `stdout` одним потоком @@ -563,6 +554,3 @@ API-ключи и токены, `Authorization`-заголовки, аутент санитизации (SLOG-37). - конвенция `db-identifiers` — откуда берутся стабильные идентификаторы, на которых держится корреляция (SLOG-18). - - - diff --git a/conventions/lang/go/time.md b/conventions/lang/go/time.md index 5e596b6..b42257b 100644 --- a/conventions/lang/go/time.md +++ b/conventions/lang/go/time.md @@ -183,9 +183,6 @@ func utcTime(_ []string, a slog.Attr) slog.Attr { Календарные вычисления бизнес-логики берут зону явно — как описано в базовом слое. - - - ## Связано - базовый слой — UTC как формат хранения, нормализация чужого входа, явная diff --git a/conventions/stack/ansible/app-directories.md b/conventions/stack/ansible/app-directories.md index e742834..2483bd9 100644 --- a/conventions/stack/ansible/app-directories.md +++ b/conventions/stack/ansible/app-directories.md @@ -56,9 +56,6 @@ extends: arch/app-directories.md изоляцией по приложениям решают разные задачи, и навязывать одну модель обоим значит гарантировать вечное отступление. - - - ### ANSD-4. Список бэкапа собирается из тех же переменных **ДОЛЖЕН.** Плейбук кладёт в `base_dir` файл `backup-targets`, строки @@ -116,11 +113,3 @@ extends: arch/app-directories.md деплой такого приложения. Способ вынужденный: секрет попадает в метаданные контейнера и в compose-файл на диске. Приложение, научившееся читать секреты из файла, переводится на ANSD-8 при ближайшем касании. - - - - -## Связано - - - diff --git a/conventions/stack/htmx/web-ui.md b/conventions/stack/htmx/web-ui.md index e8a536d..7ace540 100644 --- a/conventions/stack/htmx/web-ui.md +++ b/conventions/stack/htmx/web-ui.md @@ -493,9 +493,3 @@ diff'е — у закоммиченного минифицированного третья сторона, видящая каждый запрос пользователя. Самодостаточный бинарь вдобавок разворачивается в сети без выхода наружу, где CDN просто не отвечает. - - - - - -