RSS/list releases that match no subscription or local work no longer hit
TMDB or open a pending item; they go to the identity pool as `unmatched`.
TMDB is queried only on a local alias hit, a published new-title rule whose
prefilter passes, manual/Agent retry, search results, or when the new
setting identity.eagerTmdbLookup (default off) is on. Mirrors MoviePilot:
torrents are recognised only when matched to a subscription or searched,
and recognition failures are logged, not alerted.
- Pending items only for related releases (ambiguous after lookup, or
related to a local work but unresolved); same source + normalized title
merge into one decision ("来源「X」的 N 条资源待识别"), resolve/dismiss
applies to the whole group, members detach as they get resolved.
- Pool governance: unmatched reviews capped (daily, 3x), title_alias
insert trigger wakes similar entries, stale unmatched entries archived
after identity.poolArchiveDays (30); review idempotency keys include the
due time.
- Migration 0047_identity_pool: reason/outcome `unmatched`,
identity_candidate.normalized_title (+trgm index), wake trigger, and
cleanup of open identity_unresolved items with no related work
(dismissed, resolution=moved_to_pool).
- Inbox: group by type + work/source with collapse, hide info-only items
by default (minSeverity=warning), badge counts warning+ only; pool sheet
gets manual TMDB/local-work assign and dismiss; settings card for the
new identity settings.
- Runbook docs/runbook/identity.md.
Requires rebuild/restart (migration runs on start).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
6.0 KiB
资源识别与待识别池运行手册(DEC-1)
新观察到的资源(RSS、站点列表快照、搜索结果)先进待识别池,只在有理由时才查 TMDB。只有和订阅或本地作品相关、
又需要你决定的资源才进待处理。对照 MoviePilot:RSS / 站点资源只在匹配订阅或用户搜索时才识别,识别失败只写日志、不告警
(app/chain/subscribe/match.py _prepare_match_torrents:未识别的种子最多重试 3 次,之后跳过)。
需求依据:REQ §4.2–4.3(观察不等于事实)、§6.3(新作品收录 / 追更补缺 / 升级都由规则触发)、§7.5(待识别池可检索、 不污染正式库、有界复查、不留死数据)、§13(待处理按作品与问题类型合并)。
识别流程(resolveObservation)
-
解析标题(release-parser),本地召回:显式外部 ID、
title_alias精确 / pg_trgm ≥ 0.45(本地作品 = 订阅、追踪、已登记的作品)。 -
判断是否查 TMDB(
lookup,记在source_release.resolution_evidence.lookup和池条目query.lookup):lookup 条件 manual任务输入 trigger: "manual":池里点「重新识别」、Agent / 能力identity.resolvesearch任务输入 trigger: "search":搜索结果tracked_alias本地召回有候选(标题命中订阅 / 本地作品的别名) previously_looked_up周期复查,且这条池条目以前查过 TMDB(旧数据、手动、规则触发) eager设置 identity.eagerTmdbLookup = truenew_title_rule有已发布、开启 newTitle且有有效持续授权的获取策略,资源类型在规则的mediaKinds内,标题年份(若有)不早于窗口能覆盖的年份都不满足:只进池,
reason = unmatched,不查 TMDB,不开待处理。 -
查了 TMDB 的,走原来的
domain.resolveIdentity:auto 建档 / 关联并发release.resolved;否则进池。
任务输入 trigger 缺省:force 为 true 视为 review(池复查),否则 observed。
搜索模块想让搜索结果直接识别,入队 resolveObservation 时传 trigger: "search"(目前搜索结果经 release.observed 进来,
按 observed 处理;命中订阅别名的照样会查)。
待处理只收相关的
| 结果 | 开事项? |
|---|---|
unmatched |
否 |
ambiguous / proposed(查过 TMDB,有候选) |
是,identity_ambiguous,级别 warning |
no_match / 复查已停的 lookup_failed |
只有本地召回有候选(与本地作品相关)时开 identity_unresolved,级别 warning |
合并:dedupeKey identity-group:<siteId>:<归一化标题>,同来源同标题的资源并成一条。成员 = identity_candidate.decision_id
指向该事项且仍 pending 的条目。标题 1 条时写资源原标题,多条时写「来源「X」的 N 条资源待识别 / 待确认身份:<标题>」,
evidence.releases 列前 50 条,evidence.count 为总数。
- 处理(选候选 / 手动 TMDB ID / 选本地作品):先处理代表资源(subject),再把确定的作品套到组内其它资源(都加人工锁)。
- 忽略:组内每条池条目都
dismissed。 - 组内某条被单独识别 / 指定 / 忽略:从组里摘除,代表资源和候选选项换成剩下的最近一条;组空了才关事项。
- 旧式单条事项(
identity:<releaseId>)在该资源下次复查时并入合并事项并关闭。
收件箱:顶栏角标和待处理页缺省只算 warning 及以上(minSeverity=warning),"仅信息"类在待处理页「级别 → 含仅信息」里看。
待处理页按问题类型 + 作品 / 来源分组,前 3 组展开,其余折叠;合并事项卡片可展开组内资源。
池的治理
- 复查有上限:
unmatched每天一次本地召回,最多 3 次;查过 TMDB 的按原退避(无结果 1h 起、查询失败 15min 起,翻倍到 7 天,最多 8 次)。 - 新证据即重试:
title_alias插入触发器title_alias_wake_identity_pool,把归一化标题相同或相似度 ≥ 0.45 的unmatched/no_match池条目的next_review_at设为现在。建档、手动加别名、合并作品都会触发。 - 过期归档:
identity.poolArchiveDays(缺省 30)天没有新尝试的unmatched条目改为archived,在池复查定时任务里做, 每进程每小时最多一次。归档不删资源,仍可按状态筛出、手动指定。 - 检索:媒体概览 → 待识别,按原始标题 / 解析标题检索,原因筛「未命中订阅」即 unmatched。条目详情里可「重新识别」
(手动触发,会查 TMDB)、手动指定 TMDB ID / 本地作品(复用
/identity-pool/{id}/assign,加人工锁)或忽略。
设置
设置 → 元数据 → 资源识别:
identity.eagerTmdbLookup(缺省关):打开即旧行为,每条新资源都查 TMDB。每条约 1–2 次搜索 + 命中时 1 次详情 (识别缓存命中为 0);每小时 100 条的 RSS 约每天 2400–7200 次请求,站点独有的短剧 / 综艺多半查不到。 打开后无结果的资源仍只进池,不开事项。identity.poolArchiveDays(缺省 30)。
存量清理(迁移 0047_identity_pool)
未关闭的 identity_unresolved 事项中,资源未关联作品、池里没有候选、归一化标题也不命中任何本地别名的:
事项改 dismissed,resolution = {"resolution":"moved_to_pool","by":"migration:0047_identity_pool"};
池条目改 reason = unmatched、清 decision_id、停自动复查。相关的保留原样,下次复查时并入合并事项。
需要重建镜像 / 重启 api + worker 才生效(迁移随启动执行)。
排查
-- 池分布
select reason, status, count(*) from identity_candidate group by 1, 2 order by 3 desc;
-- 某条资源为什么没查 TMDB
select resolution_status, resolution_evidence->>'lookup' as lookup, resolution_evidence->>'detail' as detail
from source_release where id = '<id>';
-- 某个合并事项的成员
select p.source_release_id, r.title, p.reason from identity_candidate p join source_release r on r.id = p.source_release_id
where p.decision_id = '<decisionId>' and p.status = 'pending';
-- 迁移搬走的事项
select count(*) from decision where resolution->>'resolution' = 'moved_to_pool';