config: образец переименован в config.example.toml

- имя приведено к конвенции, которая сама называла его расхождением;
  ссылки поправлены в README, CLAUDE.md, конвенциях, docs/review.md и двух
  записях задач
- в шапке docs/conventions/config.md заодно поправлен второй пункт перечня:
  проверки на старте у `[auth]` и `[telegram]` уже есть
- архив openspec/changes/archive/ не тронут: это запись о прошлом
This commit is contained in:
av
2026-08-14 09:32:03 +03:00
parent 312caf0fa3
commit ce0ae76977
8 changed files with 29 additions and 27 deletions
+3 -3
View File
@@ -97,8 +97,8 @@ task gate # весь набор проверок разом
```
Локальный запуск требует `ffmpeg` и `ffprobe` в `PATH` и своего `config.toml`
скопируй `config.dist.toml` и заполни; известные прорехи образца перечислены в
[docs/conventions/config.md](docs/conventions/config.md) строками
скопируй `config.example.toml` и заполни; известные прорехи образца перечислены
в [docs/conventions/config.md](docs/conventions/config.md) строками
«*Расхождение:*».
## Гейт
@@ -194,7 +194,7 @@ task gate # весь набор проверок разом
роняет старт. Выключенного входа
для подъёма тоже мало: секции `[auth]` и `[yandex]` проверяются на старте, но
наружу при этом не ходят, так что годятся выдуманные непустые значения;
подробности строками в `config.dist.toml`.
подробности строками в `config.example.toml`.
- **Yandex Cloud за деньги.** Распознавание и хранение в Object Storage
оплачиваются по факту. Прогон на реальных ключах ради проверки кода запрещён —
подставляй `internal/adapter/recognizer/memory.go`.
+1 -1
View File
@@ -31,7 +31,7 @@
```
3. Скопируйте образец конфига и заполните его:
```bash
cp config.dist.toml config.toml
cp config.example.toml config.toml
```
4. Запустите приложение:
```bash
+3 -2
View File
@@ -24,7 +24,8 @@ UUID вместо ULID, лог пишется на каждом шаге и ду
Часть перечня закрыта. Доменные ошибки проверялись приведением типа до
2026-08-11, задача `errors-as-instead-of-typecast`. Время брали `time.Now()` по
месту до 2026-08-13 — теперь его читает единая точка `internal/clock`, и правило
держит линтер. Оба места больше не долг, а регрессия.
держит линтер. Образец конфига звался `config.dist.toml` до 2026-08-14, задача
`config-example-toml`. Эти места больше не долг, а регрессия.
Пятая, `web-ui.md`, тоже пришла оттуда, но не прижилась: jellybit работает на
htmx, а здесь решено делать SPA — и перенесённый текст снят целиком.
@@ -42,7 +43,7 @@ htmx, а здесь решено делать SPA — и перенесённы
`errors.As`, трансляция доменной ошибки на внешней границе, sentinel против
типизированной.
- [config.md](config.md) — конфигурация: TOML, секреты рендерит выкладка в файл
`0600`, самодокументируемый `config.dist.toml`, проверка на старте.
`0600`, самодокументируемый `config.example.toml`, проверка на старте.
- [database.md](database.md) — БД и идентификаторы: время в UTC RFC 3339, TEXT
ULID, разбор на входной границе, естественные ключи у деталей.
- [web-ui.md](web-ui.md) — веб-UI: Vue 3 с Vite и статикой в бинарнике,
+19 -18
View File
@@ -4,9 +4,9 @@
Правила оформления кода (How), не спецификация поведения.
**Взято из проекта jellybit.** Расхождения с сегодняшним кодом названы по месту.
Главные: образец называется `config.dist.toml`, а не `config.example.toml`;
комментариями снабжена половина полей; валидации на старте нет вовсе, кроме
проверки пустых ключей внутри адаптеров.
Главные: комментариями снабжена половина полей; единого места проверки на старте
нет: у секций `[auth]` и `[telegram]` свой `Validate()` в `main.go`, а пустые
ключи `[yandex]` ловит конструктор распознавателя.
**Механизировано:** запрет `os.Getenv``forbidigo` в `.golangci.yml`
([go-linters.md](go-linters.md), «Механизировано»). Он держит правило «настройки
@@ -29,13 +29,13 @@
- Имя конфига по умолчанию — **`config.toml`**, ищется в **рабочем каталоге**
процесса.
- Путь переопределяется опцией **`-c path`** или **`--config=path`**.
- Образец в репозитории — **`config.dist.toml`** (см. ниже); реальный
- Образец в репозитории — **`config.example.toml`** (см. ниже); реальный
`config.toml` не коммитится.
## config.dist.toml — самодокументируемый образец
## config.example.toml — самодокументируемый образец
`config.dist.toml` коммитим как единый справочник по конфигу: все секции и все
поля. **Каждое поле снабжаем комментарием**, из которого ясно:
`config.example.toml` коммитим как единый справочник по конфигу: все секции и
все поля. **Каждое поле снабжаем комментарием**, из которого ясно:
- **зачем** поле — что оно меняет в поведении;
- **допустимые значения** — перечисление или границы;
@@ -53,12 +53,12 @@ users_while_list = ["<@name>"] # кому отвечает бот; стр
комментария, а числа, совпадающие с фактом до цифры, от факта неотличимы и
начинают врать молча при смене умолчания. Действующие умолчания и их смысл живут
одним домом — таблица «Настройки с числовым значением» в
[../database.md](../database.md); `config.dist.toml` — источник истины по составу
полей.
[../database.md](../database.md); `config.example.toml` — источник истины по
составу полей.
Секретные поля оставляем пустыми — значение приходит из выкладки (см. «Секреты»).
*Расхождение:* секции `[server]` в `config.dist.toml` не хватает поля
*Расхождение:* секции `[server]` в `config.example.toml` не хватает поля
`users_while_list`, из-за чего бот на свежем конфиге отвечает отказом всем.
*Расхождение:* адреса провайдера в секции `[auth]` образца заполнены примерами
@@ -75,7 +75,7 @@ users_while_list = ["<@name>"] # кому отвечает бот; стр
- **Проверка — по `type`.** Для каждого поддерживаемого значения свой набор
обязательных полей; поля других значений не требуются. Неизвестное значение —
ошибка на старте с перечислением поддерживаемых.
- **Образец — по `type`.** В `config.dist.toml`:
- **Образец — по `type`.** В `config.example.toml`:
- основное (умолчательное) значение **предзаполнено** рабочими значениями;
- альтернативные — **блоками-комментариями ниже**, каждый со своим описанием
полей (зачем, границы, единицы — как у обычных полей);
@@ -96,7 +96,7 @@ Ansible из `pet-project-server`). Приложение просто читае
`yandex.object_storage_secret_access_key`, `auth.client_secret`.
- Отрендеренный `config.toml` (с секретами) **не коммитится**; права `0600`,
владелец — пользователь процесса (`1000:1000`).
- В `config.dist.toml` секретные поля — пустые строки.
- В `config.example.toml` секретные поля — пустые строки.
*Расхождение:* сейчас там стоят подсказки вида `your_..._here`, а не пустые
строки, и загрузчик их не отличает от настоящего значения.
- Загрузчик на старте проверяет, что обязательные секреты не пусты (ловит криво
@@ -151,10 +151,11 @@ TOML. Пустые ключи Yandex ловятся в конструкторе
## Структура в коде
- Весь разбор и проверка — в `internal/config`; наружу отдаётся готовая `Config`.
- Одна корневая структура `Config` с под-структурами по секциям. Перечень секций
и полей здесь не повторяем: источник истины по составу — `config.dist.toml`,
действующие числа — [../database.md](../database.md), «Настройки с числовым
значением». Каталог данных задаётся одним ключом `[storage] data_dir`
- Одна корневая структура `Config` с под-структурами по секциям. Перечень
секций и полей здесь не повторяем: источник истины по составу —
`config.example.toml`, действующие числа — [../database.md](../database.md),
«Настройки с числовым значением». Каталог данных задаётся одним ключом
`[storage] data_dir`
([ADR](../adr/ADR-2026-08-12-single-data-dir-config-key.md)).
- Умолчания задаются в `defaultConfig()`, файл их перекрывает. Новое поле
требует правки обоих мест.
@@ -164,5 +165,5 @@ TOML. Пустые ключи Yandex ловятся в конструкторе
комментария у самого поля), ни по нулевому значению типа; присутствие ключа
судит **разбор**`MetaData.IsDefined` из `toml.DecodeFile`, — потому что
значение отличить «не задано» от «задано нулём» не позволяет. В
`config.dist.toml` у поля стоит значение свежей установки. Первое такое поле —
`telegram.enabled`.
`config.example.toml` у поля стоит значение свежей установки. Первое такое
поле — `telegram.enabled`.
+1 -1
View File
@@ -216,7 +216,7 @@
- правка текста, который видит пользователь Telegram;
- новая метрика в `internal/metrics`;
- правка `config.dist.toml` и умолчаний `defaultConfig()` без нового поля;
- правка `config.example.toml` и умолчаний `defaultConfig()` без нового поля;
- правка документов канона.
Помни отрицательный тест: миграция, формат файла на диске, публичный контракт
+1 -1
View File
@@ -25,7 +25,7 @@
аргументом;
- `internal/controller/worker/worker.go` и `internal/service/transcribe.go`
протаскивание контекста в шаг;
- `config.dist.toml` и `internal/config` — числа таймаутов;
- `config.example.toml` и `internal/config` — числа таймаутов;
- `docs/database.md`, таблица настроек с числовым значением.
## Критерии приёмки
+1 -1
View File
@@ -17,7 +17,7 @@
- `internal/controller/tg`, проверка отправителя — сегодня `slices.Contains` по
строке автора;
- ключ конфигурации `[server] users_while_list` — он уходит;
- `config.dist.toml`, `internal/config`;
- `config.example.toml`, `internal/config`;
- `docs/security.md`, раздел «Что разграничивает доступ»;
- инвариант «Бот отвечает только тем, кто в белом списке» в `CLAUDE.md`.