Files
jellybit/openspec/changes/archive/2026-07-10-refresh-display-name/proposal.md
T
avandClaude Opus 4.8 0c9421f4c1 Имя: восстановление display_name после распознавания + гард пустого входа
Голый magnet без dn/контекста заставлял namer звать LLM на пустом входе,
и модель галлюцинировала мусорное имя («Unknown»), которое писалось и в
display_name, и в rename qBittorrent, а заодно ломало UI-фолбэк на
распознанное название. Верное каноническое имя, вычисляемое позже при
распознавании, никуда не переливалось.

- naming: гард пустого входа в DeriveName (нет контекста и подсказки → ""
  без вызова LLM) + детерминированный форматтер FormatTitleYear.
- qbt: операция RenameTorrent (переименование существующей раздачи).
- store: SetDisplayName — обновление имени постфактум без гарда состояния.
- worker: refreshDisplayNameLocked/RefreshDisplayName — перелив канонического
  имени (эффективный план) в display_name + best-effort rename раздачи по
  реальному t.Hash; авто-триггер при подтверждении матча (choose/manual add).
- web-ui: кнопка «Обновить имя» на странице загрузки (htmx-своп заголовка,
  деградация без JS), видимая при наличии распознавания (вкл. done/orphaned).

Спека: дельты ingest/review/web-ui влиты в openspec/specs; change
refresh-display-name заархивирован.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 16:51:04 +03:00

5.4 KiB
Raw Blame History

Why

При бедном первичном приёме (голый magnet без dn и без контекста) вывод имени на шаге добавления зовёт LLM на пустом входе, и модель галлюцинирует мусорное имя (наблюдалось «Unknown»). Это имя пишется и в download.display_name, и в rename qBittorrent, и вдобавок ломает UI-фолбэк на распознанное название (downloadTitle отдаёт непустой display_name). Позже распознавание по дереву файлов даёт верное имя (в наблюдавшемся случае — «Harold and the Purple Crayon», 2024), но это имя никуда не переливается: и карточка загрузки, и раздача в qBittorrent остаются с «Unknown».

What Changes

  • Гард пустого входа при выводе имени. Если и контекст, и подсказка (dn magnet / имя .torrent) пусты, система не зовёт LLM и считает имя не выведенным (display_name остаётся пустым, rename не задаётся). Убирает корень «Unknown» — приём не присваивает имя из пустоты.
  • Обновление имени по подтверждённому распознаванию. Появляется поведение «перелить» уже вычисленное каноническое имя (из распознавания / выбранного кандидата метабазы) в download.display_name и в имя раздачи qBittorrent. Детерминированный формат Title (Year) (для сериала — по аналогии с текущим выводом имени), без нового вызова LLM — источник уже сохранён (recognition.title/year, metadata_candidate.title/year).
    • Авто: при подтверждении матча в ревью (выбор кандидата) — согласуется с инвариантом «авто-действие только при подтверждённом матче».
    • Ручной: кнопка «Обновить имя» на карточке загрузки.
  • Переименование существующей раздачи в qBittorrent. Новая операция клиента qBittorrent rename для уже добавленной раздачи (сейчас rename действует только при add). Адресация — по infohash своей раздачи.

Capabilities

New Capabilities

Нет.

Modified Capabilities

  • ingest: требование «Вывод имени через LLM» ужесточается гардом пустого входа (нет ни контекста, ни подсказки → LLM не вызывается, имя считается не выведенным). Добавляется требование «Обновление отображаемого имени по подтверждённому распознаванию» (источник имени, детерминированный формат, запись display_name, переименование раздачи qBittorrent; точки входа — авто и ручная; политика перезаписи).
  • review: подтверждение матча (команда выбора/применения кандидата) SHALL запускать обновление отображаемого имени по подтверждённому распознаванию.
  • web-ui: на карточке/странице загрузки появляется htmx-действие «Обновить имя», обновляющее заголовок на месте.

Impact

  • Код:
    • internal/naming/naming.go — гард пустого входа в DeriveName.
    • internal/qbt — новая операция RenameTorrent(ctx, hash, name) (POST /api/v2/torrents/rename).
    • internal/store — метод обновления download.display_name пост-фактум.
    • internal/worker — перелив имени при подтверждении кандидата в ревью.
    • internal/httpapi — эндпоинт ручного обновления имени + htmx-партиал заголовка; кнопка в шаблоне карточки/страницы загрузки.
  • Инварианты безопасности данных: изменение чисто косметическое (display_name + ярлык раздачи в qBittorrent). Пути на диске (paths.movies/series), распознавание и раскладка НЕ затрагиваются; rename адресуется по infohash своей раздачи.
  • БД: структура не меняется (используется существующий столбец download.display_name); миграция не требуется.
  • Внешние вызовы: дополнительный вызов qBittorrent rename при обновлении имени (логируется как ext.service=qbittorrent). Новых LLM-вызовов нет.