docs: autotests.md стал переносимым документом об автопроверках

- лестница механизации из пяти ступеней, два круга проверок, перечень правил
  таблицами по родам, перечень подавлений с причинами, порядок заведения
  правила; названы остатки правил и отклонённые подъёмы
- утверждения «Механизировано» в четырёх записях конвенций и единые точки в
  architecture.md приведены к сегодняшнему состоянию; изъятие «транспорт знает
  адаптер хранилища» названо строкой
- в журнал дефектов записаны две находки: узнавание конца потока по тексту и
  правило гейта, обходимое одной лишней строкой
This commit is contained in:
av
2026-08-13 09:02:19 +03:00
parent e1dfe662ea
commit 37ccda3677
9 changed files with 278 additions and 57 deletions
+9 -7
View File
@@ -18,12 +18,13 @@ severity — в [CLAUDE.md](../../CLAUDE.md).
Четыре записи перенесены из проекта jellybit — тот же Go, тот же автор, те же
задачи. Код transcriber написан раньше и **части правил не следует**: ключи —
UUID вместо ULID, время берётся `time.Now()` по месту, лог пишется на каждом
шаге и дублируется воркером.
UUID вместо ULID, лог пишется на каждом шаге и дублируется воркером, `msg`
предложение с заглавной буквы вместо константной категории.
Из этого перечня одно уже закрыто: доменные ошибки проверялись приведением типа
до 2026-08-11, задача `errors-as-instead-of-typecast`. Приведение типа на этом
месте больше не долг, а регрессия.
Из этого перечня закрыты два. Доменные ошибки проверялись приведением типа до
2026-08-11, задача `errors-as-instead-of-typecast`. Время брали `time.Now()` по
месту до 2026-08-13 — теперь его читает единая точка `internal/clock`, и правило
держит линтер. Оба места больше не долг, а регрессия.
Пятая, `web-ui.md`, тоже пришла оттуда, но не прижилась: jellybit работает на
htmx, а здесь решено делать SPA — и перенесённый текст снят целиком.
@@ -52,8 +53,9 @@ htmx, а здесь решено делать SPA — и перенесённы
Перечень правил, доведённых до проверки, и место настройки каждого — в
[../autotests.md](../autotests.md). Там же сказано, что из перечисленного в
записях осталось прозой и потому проверяется человеком на каждом ревью заново:
сегодня правилом выражено ровно одно свойство из всех записей.
записях осталось прозой и потому проверяется человеком на каждом ревью заново, и
там же названы остатки правил — то, что правило не ловит. Числа механизированного
здесь нет намеренно: оно протухает при каждом новом правиле.
Здесь этот перечень не повторяется. Дом у него один, и он не тут: конвенции
говорят, как писать код, а не какими инструментами его читают.
+4 -3
View File
@@ -8,9 +8,10 @@
комментариями снабжена половина полей; валидации на старте нет вовсе, кроме
проверки пустых ключей внутри адаптеров.
**Механизировано:** ничего. Запрет `os.Getenv` для конфигурации правилом линтера
не выражен, и `godotenv` в `main.go` загружает `.env` — то есть окружение сейчас
участвует.
**Механизировано:** запрет `os.Getenv` `forbidigo` в `.golangci.yml`
([../autotests.md](../autotests.md), «Механизировано»). Он держит правило «настройки
приезжают из TOML»; `godotenv` в `main.go` по-прежнему загружает `.env`, но кладёт
его в окружение процесса, а не в настройки приложения.
## Принципы
+9 -8
View File
@@ -2,16 +2,17 @@
Как мы устраиваем таблицы и ключи. Актуальная схема — [../database.md](../database.md).
**Взято из проекта jellybit целиком.** Сегодняшний код transcriber этому не
следует ни в одном пункте: ключи — UUID v4, а не ULID; время — `time.Now()` по
месту вызова в локальной зоне, а не единой точкой в UTC; единой точки генерации
и разбора нет. Правила действуют на новый код; переписывание существующего —
**Взято из проекта jellybit целиком.** Сегодняшний код transcriber следует
этому частью: ключи — UUID v4, а не ULID, и единой точки их генерации нет. Время
единой точкой читается с 2026-08-13 — `internal/clock`, метка в UTC, — и правило
держит линтер. Правила действуют на новый код; переписывание существующего —
отдельная работа, и до неё расхождение читается как долг, а не как нарушение.
**Механизировано:** одно — сверка изменённого шага схемы с
[../database.md](../database.md), шаг гейта `docs.py check`
([../autotests.md](../autotests.md), «Механизировано»). Под прочие пункты ни правила
линтера, ни теста-сканера в transcriber нет.
**Механизировано:** сверка изменённого шага схемы с
[../database.md](../database.md) (`docs.py check`), чтение времени единой точкой
(`forbidigo` плюс `internal/clock`) и согласованность колонок очереди
(тест-сканер `internal/archrules`). Прочие пункты — прозой; адреса —
[../autotests.md](../autotests.md), «Механизировано».
## Первичные ключи — ULID, не автоинкремент
+4 -3
View File
@@ -9,9 +9,10 @@
Главное: единой точки отображения доменной ошибки в ответ нет, обработчики
решают сами.
**Механизировано:** приведение типа и `err == ErrX` ловит `errorlint` в
`.golangci.yml`. Запрета сторонних пакетов ошибок (`depguard`) нет — сторонних
пакетов ошибок в проекте и так нет.
**Механизировано:** приведение типа и `err == ErrX` ловит `errorlint`,
сторонние пакеты ошибок `depguard`, узнавание ошибки по тексту сообщения —
тест-сканер `internal/archrules`. Перечень и адреса —
[../autotests.md](../autotests.md), «Механизировано».
## Базовая идиома: stdlib
+7 -4
View File
@@ -11,10 +11,13 @@ OpenSpec.
категория; шаг конвейера логирует и себя, и свой исход, и при этом возвращает
ошибку выше, где её логируют снова.
**Механизировано:** ничего из перечисленного ниже. `forbidigo` в `.golangci.yml`
включён, но правило у него одно и о другом — чем судят ответ в проверках
([../autotests.md](../autotests.md), «Механизировано»); `sloglint` не заведён, и ни один
пункт этой записи правилом не выражен.
**Механизировано:** форма вызова — `sloglint`: только пары
«ключ-значение», `msg` константой, **атрибуты (`slog.String` и прочие) не
употребляются вовсе**. Запрет `fmt.Print*` и встроенных `print`/`println`
`forbidigo`; вывод в stdout через `fmt.Fprintln(os.Stdout, …)` правилом не
ловится и остаётся прозой этой записи. Прозой остаются также уровень по адресату,
единая логирующая точка и словарь имён полей: оракула у них нет. Адреса —
[../autotests.md](../autotests.md), «Механизировано».
## Принципы