docs: проект переведён на канон документов версии 4

- каталог задач: PLAN.md → ROADMAP.md с каноническими секциями, все 44
  записи получили тип, заголовки приведены к форме своего типа
- расхождения, найденные судьями канона: исключения инварианта «источник
  неприкосновенен», инвариант про один активный infohash, UTC в logging.md,
  поведение из architecture.md заменено ссылками на спеки
- триггеры профиля ревью переписаны под умолчание standard
This commit is contained in:
av
2026-08-06 13:32:06 +03:00
parent 905a1ee4d3
commit 66d39297c5
66 changed files with 334 additions and 204 deletions
+17 -12
View File
@@ -53,16 +53,20 @@ retry / delete / dismiss) идут командами к `worker`.
## Внешние границы и форматы
- **qBittorrent WebUI API** — единственный способ качать: источник (magnet, URL,
`.torrent`) **отдаём ему**, сами по пользовательскому URL не ходим (SSRF
исключён). Пути берём из API (`save_path` + относительные имена из
`/torrents/files`), не из константы.
- **LLM** — OpenAI-совместимый Chat Completions (`[llm].type = "openai-compat"`),
структурированный вывод через `response_format: json_object`; валидация ответа
своя, в Go.
- **qBittorrent WebUI API** — единственный способ качать: источник **отдаём
ему**, сами по пользовательскому URL не ходим (SSRF исключён). Какие виды
источника принимаются и как разбираются —
[ingest](../openspec/specs/ingest/spec.md); способ добавления по
`source_type` — [download-tracking](../openspec/specs/download-tracking/spec.md);
откуда берутся пути файлов —
[file-layout](../openspec/specs/file-layout/spec.md).
- **LLM** — OpenAI-совместимый Chat Completions за интерфейсом (`[llm].type`);
контракт вызова, формат вывода и разбор ответа —
[recognition](../openspec/specs/recognition/spec.md).
- **Метабазы** — TMDB, TVDB, TVMaze (последняя без ключа, только сериалы).
- **Jellyfin** — один вызов `POST /Library/Refresh`, авторизация заголовком
`X-Emby-Token`.
- **Jellyfin** — HTTP-триггер пересканирования медиатеки, опционален; когда он
дёргается и по каким переходам —
[file-layout](../openspec/specs/file-layout/spec.md).
- **Telegram Bot API** — приём сообщений и исходящие карточки/пинги.
- **Сообщение торрент-бота** — чужой текстовый формат, разбирается парсером
`tgbot`; наблюдения по формату — в
@@ -90,8 +94,9 @@ retry / delete / dismiss) идут командами к `worker`.
задаче, застрявшей в промежуточном состоянии; логи в stdout контейнера.
Автоматического алертинга нет, метрик нет — только уведомления в Telegram о
падении загрузки и о рассинхроне.
- **Характер потока:** непрерывный фон (тик поллинга qBittorrent, по умолчанию
5 с, и периодическая сверка) плюс редкие события по запросу человека. Объём —
- **Характер потока:** непрерывный фон (тик поллинга qBittorrent — период в
[database.md](database.md) → «Настройки с числовым значением» — и
периодическая сверка) плюс редкие события по запросу человека. Объём —
единицы загрузок в день, десятки одновременно; ориентир масштаба и его аудит —
задача в беклоге.
@@ -101,7 +106,7 @@ retry / delete / dismiss) идут командами к `worker`.
| Что | Где |
| --- | --- |
| Время | `store.Now()` — единственный источник, всегда UTC; формат хранения — RFC 3339 |
| Время | `store.Now()` — единственный источник меток времени в данных, всегда UTC; формат хранения — RFC 3339. Вторая санкционированная точка wall-clock — timestamp-часть ULID в `ident.NewID` (исключение в `.golangci.yml`) |
| Идентификаторы | `internal/ident` — генерация и нормализация ULID; `ident.Parse` на каждой входной границе |
| Целевые имена и превью раскладки | `internal/naming` — одна логика для превью в UI и для реального применения |
| Разбор источника | `internal/magnet` и `internal/torrent`; инфохэш извлекается только здесь |