docs: документация переведена на канон av-dev-pm

- беклог и план переехали в docs/tasks (38 задач, 11 целей), слаги
  переименованы с транслита на английские, 85 ссылок поправлены
- conventions.md разобран в docs/conventions/, local-research.md — в
  docs/research/, review-journal.md — в docs/review.md с разделом настройки
  конвейера; заведены security.md, adr/ и .pm.json
- шаг docs.py check добавлен в task gate; поведение в architecture.md помечено
  девятью маркерами долга, database.md получил настройки с числовым значением
This commit is contained in:
av
2026-08-03 17:14:53 +03:00
parent de7b15d48c
commit d79189be18
94 changed files with 1234 additions and 566 deletions
+46
View File
@@ -0,0 +1,46 @@
# Конвенции кода
Как мы пишем код — в отличие от `openspec/specs/`, который описывает, что
система делает, и [architecture.md](../architecture.md), который описывает, как
она сложена.
**Прозой остаётся только то, что не выражается правилом.** Свойство, ставшее
правилом линтера, отсюда удаляется и переезжает в перечень «Механизировано».
Язык документации и кода — в [CLAUDE.md](../../CLAUDE.md): это правило шире
кода, оно касается и коммитов, и документов.
## Записи
- [errors.md](errors.md) — ошибки: обёртка, sentinel против типа, трансляция на
границе, что глушим.
- [logging.md](logging.md) — логи: уровень по адресату, единственный логирующий
чекпоинт, что не попадает в лог никогда.
- [config.md](config.md) — конфигурация: TOML, валидация на старте,
самодокументируемый образец.
- [storage.md](storage.md) — база и идентификаторы: ULID и естественные ключи,
время в UTC, правило выбора между версиями, отпечаток витрины, миграции.
- [testing.md](testing.md) — тесты: реальные пакеты в `testdata`,
идемпотентность, перебор версий, замер на живом архиве.
## Механизировано
Проверяет `task lint` по [.golangci.yml](../../.golangci.yml). Пересказывать эти
правила прозой не нужно — линтер скажет точнее и всегда актуальнее.
| Правило | Где механизировано |
| --- | --- |
| `msg` лога — константная категория, данные атрибутами | `sloglint` |
| Без `fmt.Print*` — логируем через `slog` | `forbidigo` |
| Конфигурация только из TOML, без `os.Getenv` | `forbidigo` |
| Время генерирует `store.Now()`, не `time.Now()` | `forbidigo` |
| Сравнение ошибок через `errors.Is`/`As`, не `==` | `errorlint` |
| Ошибки только stdlib `errors` + `fmt.Errorf` | `depguard` |
| Стек-трейсы избыточны — контекст несёт `slog` | `depguard` |
Плюс шаги [`task gate`](../../Taskfile.yml): сборка, `go vet`, `gofmt`, тесты,
гонки, покрытие изменённых строк, миграции, образцы конфига, секреты в индексе,
данные о здоровье в индексе.
Непойманное место механизации означает, что проход по конвенциям будет
добросовестно проверять уже проверенное.