Files
transcriber/docs/conventions/README.md
T
av 539ed926cb docs: сняты проверки над проверками
- Из «Любой узел» в review.md убраны три свойства о годности самих проверок:
  мутация теста, мутация оракула критерия, требование без сценария.
- Из go-linters.md снята «Лестница механизации», ссылки на неё переписаны
  в конвенциях, их индексе и журнале дефектов.
2026-08-13 16:45:12 +03:00

62 lines
5.3 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.
# Конвенции кода
Как мы пишем код — в отличие от `openspec/specs/`, который описывает, что
система делает, и от [../architecture.md](../architecture.md), который описывает,
как она сложена.
**Прозой остаётся только то, что не выражается правилом.** Свойство, ставшее
правилом линтера или тестом-сканером, отсюда **удаляется** и переезжает в
перечень «Механизировано» записи [go-linters.md](go-linters.md) — дома правил,
которыми машина читает код. Причина: файл на несколько сотен строк
размазывает внимание по тривиальному — и модель, и человек добросовестно
проверят именование и не дойдут до формы решения.
Обоснование «почему именно так» живёт в [../adr/](../adr/README.md); инварианты с
severity — в [CLAUDE.md](../../CLAUDE.md).
## Откуда взяты и что с расхождениями
Четыре записи перенесены из проекта jellybit — тот же Go, тот же автор, те же
задачи. Код transcriber написан раньше и **части правил не следует**: ключи —
UUID вместо ULID, лог пишется на каждом шаге и дублируется воркером, `msg`
предложение с заглавной буквы вместо константной категории.
Из этого перечня закрыты два. Доменные ошибки проверялись приведением типа до
2026-08-11, задача `errors-as-instead-of-typecast`. Время брали `time.Now()` по
месту до 2026-08-13 — теперь его читает единая точка `internal/clock`, и правило
держит линтер. Оба места больше не долг, а регрессия.
Пятая, `web-ui.md`, тоже пришла оттуда, но не прижилась: jellybit работает на
htmx, а здесь решено делать SPA — и перенесённый текст снят целиком.
Каждое такое место названо в своей записи строкой «*Расхождение:*». Читается оно
как **долг, а не как нарушение**: правила действуют на новый код, переписывание
существующего — отдельная работа. Проходу ревью строка «Расхождение» говорит, что
находка на этом месте уже известна и новой не считается.
## Записи
- [logging.md](logging.md) — логирование: уровень по адресату, единая логирующая
точка на доменной границе, словарь полей, `ext.*`, что не логируем.
- [errors.md](errors.md) — ошибки: stdlib, обёртка `%w`, `errors.Is` и
`errors.As`, трансляция доменной ошибки на внешней границе, sentinel против
типизированной.
- [config.md](config.md) — конфигурация: TOML, секреты рендерит выкладка в файл
`0600`, самодокументируемый `config.dist.toml`, проверка на старте.
- [database.md](database.md) — БД и идентификаторы: время в UTC RFC 3339, TEXT
ULID, разбор на входной границе, естественные ключи у деталей.
- [web-ui.md](web-ui.md) — веб-UI: Vue 3 с Vite и статикой в бинарнике,
однофайловые компоненты, таблица маршрутов, состояние в экране, одна обёртка
над `fetch`, показ ошибок и состояний списка.
- [go-linters.md](go-linters.md) — линтеры и механизированные проверки: два круга
(pre-commit и гейт), перечень правил и подавлений, порядок заведения нового
правила. Про инструменты, а не про то, как писать тесты.
## Что из этого проверяет машина
Перечень правил, доведённых до проверки, и место настройки каждого — в записи
[go-linters.md](go-linters.md). Там же сказано, что из перечисленного в прочих
записях осталось прозой и потому проверяется человеком на каждом ревью заново, и
там же названы остатки правил — то, что правило не ловит. Числа механизированного
здесь нет намеренно: оно протухает при каждом новом правиле.