docs: документы дополнены материалом для ревью
- review.md: заведён род узла «вызов LLM и разбор ответа», добавлены вопросы тем autotests, security и operations, маршрут к уже механизированному - architecture.md: «Открытые вопросы» вместо «пока нет» — восемь областей знаемо тонкого устройства со ссылкой на задачу - security.md: снят указатель на несуществующую задачу про лимит ответа LLM
This commit is contained in:
+15
-2
@@ -170,5 +170,18 @@ Jellyfin указывают на `movies`/`series`, а не на корень
|
||||
|
||||
## Открытые вопросы
|
||||
|
||||
- Пока нет. Решённое разъехалось по ADR и capability-спекам; то, что требует
|
||||
работы, живёт задачами в [tasks/BACKLOG.md](tasks/BACKLOG.md).
|
||||
Места, где устройство знаемо тонкое: не дефекты, а принятые пока пробелы. Здесь
|
||||
только адрес и одна фраза — что именно не сделано; работа под каждым живёт
|
||||
задачей в [tasks/BACKLOG.md](tasks/BACKLOG.md). Список нужен ревью: правка,
|
||||
попавшая в такую область, стоит дороже, чем выглядит.
|
||||
|
||||
| Область | Чего нет сегодня | Задача |
|
||||
| --- | --- | --- |
|
||||
| Масштаб | ориентир 100/1000 загрузок не зафиксирован, узкие места SQLite, воркера и поллинга не измерены | `scale-100-downloads` |
|
||||
| Ретеншен | терминальные задачи и сырые ответы LLM копятся вечно, авточистки нет | `db-retention-cleanup` |
|
||||
| Бекап | бекапить `/data` требуется, а стратегия и ротация не описаны | `sqlite-backup` |
|
||||
| Наблюдаемость | healthcheck проверяет только сам сервис; метрик и алертинга нет, отказ виден по застрявшей задаче | `deep-healthcheck-dependencies` |
|
||||
| Идентичность раздачи | split v1/v2-хеши не связаны, паре `xt` из магнета доверяем | `infohash-identity-integrity` |
|
||||
| Расход внешних лимитов | кэша ответов метабаз нет, повтор распознавания бьёт провайдера заново | `metadata-cache` |
|
||||
| История переходов | хранится только текущее состояние, «как сюда попали» восстанавливается по логам | `download-transition-history` |
|
||||
| Предел ответа LLM | лимита на размер ответа нет — единственный недоверенный канал без предела; задачей пока не заведено | — |
|
||||
|
||||
@@ -6,6 +6,17 @@ Go-сервиса и что здесь уже проскакивало. Устр
|
||||
|
||||
## Как настроен конвейер
|
||||
|
||||
**Прежде чем задать вопрос, посмотри, не задан ли он уже машиной.** Перечень
|
||||
механизированного — [conventions/README.md](conventions/README.md) →
|
||||
«Механизировано»; чем безусловно краснеет гейт и чего в нём намеренно нет —
|
||||
[CLAUDE.md](../CLAUDE.md) → «Гейт». Вопрос про уже проверенное вытесняет вопрос
|
||||
про непроверенное — места в прогоне столько же.
|
||||
|
||||
**Severity не выводится проходом заново.** Она стоит рядом с формулировкой
|
||||
инварианта в [CLAUDE.md](../CLAUDE.md) → «Инварианты», обратимость — там же в
|
||||
«Работа» → «Необратимое». Шкала ущерба берётся оттуда, а порядок ценностей —
|
||||
из [security.md](security.md) → «Что чувствительнее чего».
|
||||
|
||||
### Типовые узлы
|
||||
|
||||
Рода узлов проекта и проверяемые свойства к каждому. Род, а не инвентарь
|
||||
@@ -54,6 +65,23 @@ Go-сервиса и что здесь уже проскакивало. Устр
|
||||
- невалидный вход даёт доменную ошибку, а не тихий дефолт;
|
||||
- результат нормализуется на границе (lowercase hex, trim, `ident.Parse`).
|
||||
|
||||
**Вызов LLM и разбор его ответа** (`recognize`, `naming.Derive`)
|
||||
|
||||
Самый специфичный род узла в проекте: единственный, чей выход недетерминирован,
|
||||
недоверен и стоит денег одновременно.
|
||||
|
||||
- решение узла **не является гейтом безопасности**: инъекция в промпт считается
|
||||
состоявшейся, защита стоит ниже — на валидации целевого пути
|
||||
([security.md](security.md));
|
||||
- самооценка модели не заменяет матч в метабазе — порог `confidence` стоит
|
||||
**поверх** матча дополнительным условием, а не вместо него;
|
||||
- разбор ответа устойчив к лишним и недостающим полям, обрезке и не-JSON;
|
||||
негодный ответ даёт доменную ошибку, а не тихий дефолт;
|
||||
- попытка стоит лимита и денег: число ретраев берётся из конфига, а фоновый цикл
|
||||
не запускает распознавание сам по себе повторно;
|
||||
- тест не ходит в живой эндпоинт — провайдер за интерфейсом, ответ фикстурой;
|
||||
живые прогоны только за env-гейтом.
|
||||
|
||||
**htmx-хендлер**
|
||||
|
||||
- один партиал обслуживает страницу и фрагмент, ветвление по `isHTMX`;
|
||||
@@ -121,6 +149,15 @@ Go-сервиса и что здесь уже проскакивало. Устр
|
||||
(задача про масштаб 100/1000, [database.md](database.md) → «Настройки»)
|
||||
- `operations`: что остаётся на диске и в базе, если процесс убит посреди
|
||||
раскладки батча? (состояние `linking` и его восстановление)
|
||||
- `autotests`: изменённые строки не просто исполнены тестом, а **проверены** —
|
||||
есть ли тест, который упал бы без этой правки? (diff-coverage в гейте меряет
|
||||
исполнение, отличить его от проверки машина не может)
|
||||
- `autotests`: конкурентная часть правки проверена тестом, а не рассуждением?
|
||||
(`-race` без gcc уходит в `SKIP`, и тогда гонки не проверял никто —
|
||||
[CLAUDE.md](../CLAUDE.md) → «Гейт»)
|
||||
- `autotests`: новый тест не ходит в живой qBittorrent, LLM, метабазу или
|
||||
Telegram — а если ходит, он за env-гейтом в `*_integration_test.go`?
|
||||
([CLAUDE.md](../CLAUDE.md) → «Запреты»)
|
||||
- `conventions`: логирующий чекпоинт один на операцию — или ошибка залогирована
|
||||
и возвращена вверх, где залогирована снова?
|
||||
([conventions/logging.md](conventions/logging.md))
|
||||
@@ -129,6 +166,15 @@ Go-сервиса и что здесь уже проскакивало. Устр
|
||||
([conventions/config.md](conventions/config.md))
|
||||
- `requirements`: не завелось ли поведение, которого спека не заказывала — тихий
|
||||
дефолт, проглоченная ошибка, ретрай «на всякий случай», отброшенное поле?
|
||||
- `security`: читается ли тело ответа внешнего сервиса целиком без предела —
|
||||
лимита на размер ответа LLM в проекте нет, и это единственный недоверенный
|
||||
канал, где предел не стоит ([security.md](security.md) → «Что вне модели»)
|
||||
- `operations`: не удваивает ли новая ветка расход лимита метабаз и платного
|
||||
LLM — повтор, ретрай, «распознать заново» на том же входе? (кэша ответов нет,
|
||||
задача `metadata-cache`)
|
||||
- `operations`: копится ли то, что заводит это изменение, без срока хранения —
|
||||
строки терминальных задач, сырые ответы, файлы? (авточистки в проекте нет,
|
||||
задача `db-retention-cleanup`)
|
||||
- `architecture`: не появился ли второй способ делать то, что уже делается —
|
||||
второе место, где генерится время или id, второй парсер источника, вторая
|
||||
логика целевых имён мимо `naming`?
|
||||
|
||||
+3
-1
@@ -100,7 +100,9 @@ REST API работают **без авторизации** осознанно;
|
||||
- **Отказ в обслуживании изнутри контура.** Огромная раздача, тысяча файлов,
|
||||
бесконечный ответ LLM — это вопросы устойчивости и ресурсов
|
||||
([architecture.md](architecture.md) → «Эксплуатация»), а не безопасности.
|
||||
Отсутствие лимита на размер ответа LLM — известный пробел, задача в беклоге.
|
||||
Отсутствие лимита на размер ответа LLM — известный пробел
|
||||
([architecture.md](architecture.md) → «Открытые вопросы»); задачей он пока не
|
||||
заведён.
|
||||
- **Целостность содержимого медиафайлов.** Что в контейнере mkv — не наша забота.
|
||||
- **Цепочка поставки** — модули Go, базовый образ distroless, плагины тулинга.
|
||||
- **Приватность запросов к внешним сервисам.** Названия раздач уезжают в LLM и
|
||||
|
||||
Reference in New Issue
Block a user