Files
UHD_Media_Tool/CHANGELOG.md
T
2026-09-28 13:53:33 +08:00

211 lines
23 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Changelog
版本号遵循 [SemVer](https://semver.org/lang/zh-CN/)。所有成员包(`apps/*`、`packages/*`)与根 `deno.json` 使用同一个版本号;`/api/v1/health` 与备份清单里的版本取自 `apps/server/deno.json`。
## [0.2.0] - 2026-09-28
Agent 上游全覆盖与订阅登录、控制台信息架构重排、定时任务看板、全站文案第二轮审校。基线见 `docs/plan/08-v0.2-closeout.md`(W8-A)、`docs/design/{console-ia,pi-providers,agent-ui-reference}.md`、`docs/runbook/{schedules,agent}.md`。
### Agent
- 全局入口:侧栏顶部常驻 Agent 入口(展开与折叠态均带活跃会话数角标);右下角悬浮按钮(带活跃计数、最新状态摘要),在 Agent 会话页与迷你坞展开时隐藏;`Ctrl/Cmd+J` 切换抽屉、`Esc` 关闭,打开即聚焦输入框;抽屉首屏给出随页面变化的快捷目标。
- Agent 上游:新增 `pi_upstream` 表与 CRUD,一个上游 = 一个 pi provider(41 个内置之一,或 `openai-compatible` 自定义兼容端点,或 `fake`)+ 一份凭证;同一 provider 可建多个上游,各自独立凭证存储;`authKind` 分 `api_key` / `oauth` / `none`;默认上游可指定,`runAgent` 只从上游选模型。
- 订阅登录:8 种(Anthropic Claude Pro/Max、OpenAI Codex、GitHub Copilot、xAI、Kimi Code、Meta Muse、OpenRouter、Radius),browser 与 device 两种交互,登录会话 15 分钟;条款提示只陈述事实(借用官方客户端身份、可能违反条款、有限流或封号风险)。
- 设置页 Agent 分区:上游列表、新建向导(选 provider → 凭据与模型 → 登录 / 测试 / 设默认)、编辑抽屉(登录 / 重新登录 / 退出、测试、设默认、删除)。
- 子会话:`agent.spawn` 派生子会话(独立 agent_run,同一 runAgent 任务),`agent.await` 取子会话状态与脱敏汇报;能力白名单继承父会话并取交集;并发上限 `maxConcurrent`、派生层数上限 `maxDepth`、单会话最多 10 个子会话;预算从父会话划拨;中止父会话递归取消未结束子会话。
- `agent.await` 落定时挂起会话而不占 worker 槽:`drive` 返回 `suspended`,由 `waitForFact` 每 2 秒查一次子会话落定 / 超时 / 父会话取消,再以 `resumedAwaits` 重开会话续跑;单会话最多挂起 100 次。
- 没有候选的待识别资源(无法解析,或候选为 0,或查询失败且自动复查已停)开 `identity_unresolved` 待处理事项:可手动指定 TMDB ID、选本地作品或忽略。
- 旧 `settings.pi.provider / baseUrl / model / thinkingLevel / apiKeySecretRef` 弃用:schema 保留兼容旧数据,`PATCH /settings` 丢弃,设置分区不再展示;`runAgent` 没有上游直接失败并提示「未配置 Agent 上游」。
- Agent 汇报里的下载链接改指向 `/console/downloads/:id`,不再经 `/console/tasks/:id` 404 探测再跳转。
### 控制台信息架构
- 侧栏改为 7 组 19 项(概览、资源、订阅、下载、整理、Agent、系统),按业务流程排列;新增"定时任务"入口。
- 站点工作台合并快照与账号:详情页 4 个页签(整理视图 / 原站视图 / 快照与 Feed / 账号)。
- 原"下载与任务"拆分为下载队列、下载计划、业务任务三页;订阅页"收录策略"页签独立为收录规则页。
- 身份判定收口到待处理中心:身份页"待识别"改为只读,已进待处理的行标注跳转,判定动作只在待处理执行。
- 设置页改为 9 个左侧分区(自动化、站点与账号、下载器、媒体库与目录、媒体服务器、元数据、Agent、API Key、账户与安全),用 URL hash 定位到分区与节;旧 `?tab=` 全部重定向到新分区 hash,`settingsPath()` 直接生成 `#分区[/节]`。
### 定时任务看板
- `scheduled_job` / `scheduled_job_run` 表驱动全部周期任务,worker(io 组)内唯一调度器按表调度(`pg_try_advisory_lock` 选出执行者);控制台"定时任务"页(`/console/schedules`)查看与调整。
- 已登记 16 个任务,分 5 组(采集、下载、整理、维护、Agent);Agent 组含 3 个默认关闭的巡检(待处理巡检、下载诊断、订阅与站点周报)。
- 模块自建计时器全部并入注册表:`pi.token_refresh`(上游登录刷新,维护组,10 分钟)与 `auth.cleanup`(登录会话清理,维护组,1 小时)改为 `registerScheduledJob`,模块里不再有 `setInterval`。
- 支持立即执行、跳过本次、开关与周期自定义(`customized` 标记,改过之后再登记不覆盖,`PATCH {reset:true}` 恢复默认);自定义巡检可增删,内置任务只能停用。
- 调度器中断恢复:新执行者拿到锁时,把上一个执行者留下的 `running` 状态改为 `failed`。
### 文案与术语
- 全站第二轮文案审校:控制台、设置、Agent、服务端消息统一术语表用词(待处理 / 待识别 / 整理记录 / 运行记录 / 凭证 / 子会话 / Agent 上游),精简说明文字、空态、确认按钮与 toast。
- 内置 Agent 巡检的目标模板改短、改具体。
- 实例(下载器 / 媒体服务器)CRUD 报错改用可读名词,不再显示表名。
- 审计日志补 `pi_upstream` / 定时任务 / 持续授权相关动作的显示名。
- 术语表新增:上游、订阅登录、凭证、定时任务、巡检、运行记录、子会话、停止、持续授权。
### 修复
- 设置页深链改用分区 hash 定位,不再依赖 `?tab=` 查询参数(旧链接仍可打开,经重定向落到新分区)。
- Agent 汇报的下载任务链接直接指向下载详情页,不再先探测业务任务详情再判断是否为下载任务。
- 生产容器静态 ffprobe 升级到 9.0.2;`.gitignore` 忽略 compose override 文件。
### 已知限制
完整清单见 `docs/plan/08-v0.2-closeout.md`"仍遗留"节。
- 41 个 provider 里只有 fake 与 OpenAI 兼容本地端点有自动化覆盖;8 种订阅登录只测了 fake 的 OAuth 状态机;Codex `_randomBytes` 在 Deno 下的行为待 spike(`docs/design/pi-providers.md`)。
- `agent.spawn {await:true}` 仍在进程内轮询等待,占 worker 槽到超时;要挂起需要和 `agent.await` 相同的关闭会话 + 重放机制,但 spawn 是 replay=never,重放会得到"结果未知",需另行设计。
- 子会话挂起期间父会话状态保持 `running`(避免被祖先会话的 `agent.await` 当成已落定);运行时长预算按每段 drive 计,不含挂起等待。
- 查询失败但仍在自动复查期内的资源不开待识别事项,避免 TMDB 抖动刷屏,复查耗尽后才开。
- 身份页"待识别"详情抽屉的提示句仍写"选择候选或忽略",未识别类(无候选)读起来不准确,留给下一轮文案。
- 旧 `settings.pi` 字段只是弃用未删除,真正删除需要一次迁移清理里面的旧键。
- 原站视图仍是占位(IA-1 遗留)。
- 控制台账户弹层的二次验证(TOTP)开启时只显示密钥与 otpauth 链接,不渲染二维码。
## [0.1.0] - 2026-09-28
第一个可用版本:REQ v0.7 的 M0 + M1 纵切。全链路在没有真实 PT 账号的情况下用 mock(RSS / 站点 / TMDB / qBittorrent / Emby)验证。范围与验收依据见 `docs/plan/00-first-version-plan.md` §3.1 和 `docs/plan/04-v0.1-acceptance.md`。
### W0 底座
- Deno workspace 单仓(`apps/server`、`apps/web`、`packages/{adapters,agent,contracts,db,domain,mapping,tasks,testkit}`),迁入 uhd_web 设计系统。
- OpenWorkflow 与 Pi SDK 兼容性 spike,结论写入 ADR-002 / ADR-003;Deno 2.9.7 + TypeScript 7 spike 写入 ADR-004。
- MoviePilot / MovieClaw 迁移对照账本(识别、刮削、转移入库、站点框架)。
### W1 领域与适配
- `@umt/domain`:发布标题解析、身份判定、Slot 状态机与完成条件、收录模式判定、路径模板与路径绑定、整理计划、下载状态机,全部是纯函数。
- `@umt/adapters`:qBittorrent(多实例、管理标签、带数据删除前的安全检查)、文件系统(Copy/Move、跨卷 Copy→核验→删源、EXDEV 不静默降级、全量 sha256)、TMDB、Emby、RSS、PT 站点(NexusPHP 观众、馒头 API,移植 MoviePilot 开放站点框架)。`@umt/testkit` 提供对应 mock。
- `@umt/db`:36 张表的全量迁移;`@umt/contracts`:共享 zod 契约与 API 注册表;`@umt/mapping`:domain 与 contracts 之间的映射集中在一处。
- `@umt/tasks`:基于 OpenWorkflow 的持久任务引擎、任务注册表、outbox 中继、操作账本 fencing(旧 attempt 的提交会被拒绝)。
- `@umt/agent`:能力注册中心、Pi AgentRuntimePort、fake 模型、输出脱敏。
### W2 服务编排
- 认证与设置:管理员登录门禁(argon2id、会话 cookie、CSRF 双提交、登录限速、可选 TOTP)、API Key scope(read / organize.read / organize.execute / admin)、密钥加密存储、实例与路径映射、审计、PG 通知驱动的 SSE(带序号,可补读)、自动化总开关与只读对账模式、工作流引擎面板 API。
- 来源与身份:站点与 Feed 管理、多 RSS 抓取与多层去重、站点快照与实时补查、TMDB 识别与本地实体优先、待识别池、人工纠错映射。
- 规则、下载与入库:订阅、Slot、策略版本(发布即生成持续授权)、确定性 evaluateAcquisition、每日预算与并发、qB 同步与标签接管、缓存卷硬阈值与恢复水位、verifyAndImport(Copy/Move)、路径绑定固定、整理记录与公开增量 API、媒体库与首页聚合。
- Agent:14 个能力接到服务,服务端授权(持续授权 / 一次性审批),会话 API + SSE 增量,后台事件触发有界调查任务。
### W3 控制台
- 20 个路由:首页、媒体库、订阅与规则、偏好标签、待处理中心、身份与元数据、PT 站点工作台、来源 / Feed / 快照、下载与任务、整理记录、Agent 会话、系统设置、工作流引擎面板、审计。
### W4 集成验收与修复
- 单容器打包(API + worker + 静态前端,compose 只有 app 和 pg),`DATA_DIR`,备份与恢复脚本,runbook。
- 控制台接入真实端点;Playwright 全路由冒烟(`deno task test:web:smoke`)。
- BrowserProvider 接口与 camofox-browser 适配骨架(只落接口)。
- 主循环解耦:后台循环只做编排,清理 / 对账 / 入库一律入队到任务引擎;io / agent worker 分组;外部 IO 能力调用限流;事件循环延迟探针。
- 安全修复:审批只能由管理员会话决定,共享一份脱敏表,TMDB 错误信息不带 api_key,生产构建不能打开 Agent mock。
- 授权内异常调查与恢复:有持续授权时,调查结论可在授权范围内自动重试并继续。
- 手动整理守卫(`POST /organization-records`):`sourcePaths` 必须在已登记的媒体库根或下载器路径映射之下(realpath 后按目录前缀匹配,拒绝 `..` 与符号链接逃逸,dryRun 同样受限);Move 需要管理员会话,或 API Key 同时有覆盖目标作品的持续授权 / 与本次请求一致的一次性审批;来源是纳管下载任务且做种义务未满足时返回 409 并建待处理,不改成 Copy。
- 剧集完成判定:总集数未知(集单元都是临时单元)时 Slot 不判满足,订阅继续追踪;覆盖按实际文件登记,整季包不因包名覆盖整季;已在库的相同文件算作核验到的内容。
- 工作流引擎面板支持重跑:`POST /engine/runs/{id}/retry`(仅 admin,新幂等键 `retry:<id>:<序号>`,写审计),run 详情页有"重跑"按钮。
- 新增 e2e:E7 常规剧集纵切、E8 管理标签移除与 qB 任务消失(AT24)。
### 文件管理(`/console/files`,00 §6 追加范围)
- 后端 `/files` 模块共 18 个端点:根 / 列表 / stat(行内带资产、Slot、下载任务状态)、mkdir、rename、move、copy、organize、delete、回收站(列表 / 还原 / 还原到… / 清理)、identify、probe、scrape、records、download。
- 路径守卫:realpath 必须落在已登记根内,拒绝 `..`、URL 编码、符号链接逃逸与对根本身的写操作;执行前再做一次 realpath(TOCTOU);根离线返回 503,不返回空列表;fs 竞态错误映射为 503/404/403/400。
- 两阶段写操作:move / copy / organize / delete 先 dryRun 产出 `planId` 与源事实指纹,执行时只认 planId,源变化返回 `plan_stale`;全部写操作带幂等键并写审计。
- move / copy 经 `planImport` 的 `transfer` 变体生成整理记录,由 `verifyAndImport` 执行:逐文件账本可续跑、经 fsproxy、跨卷目录 Move 为逐文件 Copy→核验→删源;资产位置逐文件跟随,整目录搬走时修订路径绑定。请求最多等待 `FILES_TRANSFER_WAIT_SEC`,超出返回 `executed.pending`。
- organize 支持逐项覆盖季 / 集 / 内容单元 / 目标目录 / 操作 / Slot;delete / 回收站 / 还原写整理记录(迁移 0026)。
- 回收站:`<root>/.umt-trash/<day>/<uuid>/`,`trash_item` 表(迁移 0024),删除前核对引用,做种中的文件不能改名、删除或 Move;过期清理由 `purgeTrash` 任务执行。永久删除默认关闭(`FILES_ALLOW_PERMANENT_DELETE`)且只接受管理员会话;API Key 删除每次都要一次性审批。
- download:仅管理员会话,nfo / 字幕 / 图片白名单,`FILES_DOWNLOAD_MAX_BYTES` 上限,`nosniff` + `CSP sandbox`,写审计。
- 前端:目录树、虚拟滚动网格、面包屑、排序与 glob 搜索、多选 / 右键菜单 / 拖拽后 dryRun 预览、键盘操作(F2 / Del / Shift 区间 / Ctrl+A)、离线与空态、移动端布局;改名 / 移动 / 复制 / 删除对话框,4 步整理向导(未决项挡住下一步),回收站页;SSE `files.changed` 触发刷新。`?mock=1` 内存后端只在 DEV 构建生效。
- 运行手册 `docs/runbook/files.md`。
### 订阅增强(对照 MoviePilot,`docs/plan/05-subscription-gap.md`)
- 总集数账本:季单元记录 `episode_total` 及来源 / 锁定 / 时间(迁移 0025);`resolveEpisodeTotal` 只增不减,TMDB 回退时以已覆盖的最大集号为下限,手动值可锁定。
- 完成判定按账本:总集数未知时不结束并记疑似缺集;`pending`(元数据未就绪)的订阅可搜可评估但不会完成;once 与持续订阅的当季完成都写 `subscription_history`。
- Slot × 单元预留:缺口 = 发布单元 ∩ 集范围 − 已覆盖 − 在途;剧集 Slot 可同时有多个互不重叠的在途计划,重叠或忙时延后(`slot_deferral`),计划结束或周期重评时再评估。
- 硬条件与优先级:排除来源、HDR / 编码集合、每集体积、include/exclude 正则(白名单校验)、站点范围、最少做种、仅免费;MoviePilot 规则组分级映射为 0–100 优先级并带逐级 trace;分集洗版(`slot_unit` 账本)。
- 季包选文件:提交后读取 qB 文件列表,把已覆盖或在途的集设为不下载;无法判定时整包下载并记录原因。
- 主动搜索:建订阅时、每 `searchIntervalHours`(默认 24h)和 `POST /subscriptions/{id}/search` 入队 `searchSubscription`;元数据每 6h 刷新并写季总集数。
- 前端订阅抽屉:立即搜索、追更进度(每季总集数与来源、每集状态、在途 / 延后计数)、设置并锁定季总集数。
- 新增 e2e E9 持续追更剧集。
### 转移语义与文件系统隔离(`docs/porting/moviepilot-rust-transfer.md`)
- FsProxy + fsworker:文件操作在可杀子进程里执行;复制 / 哈希按进度停滞看门狗(`FS_HANG_TIMEOUT_MS`),快操作按总超时;超时后 SIGTERM → SIGKILL → `FsError('TIMEOUT')`,stat / 根探测超时不会被当作"不存在"。
- 生产二进制内置 `--role fsworker`(`/app/umt-server` 自身 spawn,容器演练见 `docs/runbook/deploy.md`)。
- `copyWithVerify` 支持 conflict / skip / replace:replace 先硬链接留底再原子 rename,旧文件进 `.umt-trash` 并登记 `trash_item`;写前清理超过 24h 的 `.uhd-partial`。
- 核验读失败抛错,不再当作"不匹配";对账错误不再误报 EEXIST;TIMEOUT / IO 有限重试(`FS_TRANSFER_MAX_ATTEMPTS`)后建待处理,不删记录。
- 复制流 1 MiB 块;强制全量 sha256 走 `sha256sum` 子进程;手动整理遍历有上限(`ORGANIZE_WALK_MAX_FILES`)。
- 字幕 `.default` 标记、同集其他版本作为洗版处置候选。
### Agent 会话页
- 移植 agentui(MIT,`LICENSE-agentui.md`)组件并换成本项目语义 token:流式光标、可展开的思考块、带类别 / scope / 风险 / 幂等徽章的工具卡、服务端拒绝的醒目态、压缩标记、预算条、审批卡(仅管理员会话可操作)、"模型声明 vs 系统核实"双栏最终汇报、跟随滚动与回到底部。
- 输入框(Enter 发送、中止需确认、追加、执行 / 只要方案切换、从方案一键执行)、会话列表与状态筛选、断线重连横幅;侧栏抽屉按路由带入上下文,可最小化为迷你坞。
- 设置页新增 `autoInvestigateMode`(调查 / 授权内恢复)与最大恢复次数、`agent.sessionDir`。
### 识别与站点解析补迁(MoviePilot 差分)
- 标题识别:动漫前缀标签、多种集号写法、首括号作标题或组名、原盘判定、`{[tmdbid=…]}` 显式块与 bangumi/anilist id、流媒体平台表等;繁简表补字。标题识别剔除登记项后 100% 对齐,missing / our_bug 清零。
- 站点:18 个站点定义的行选择器收紧、字幕搜索分支(只到解析层)、体积解析的银行家舍入。差分快照与样本来源登记在迁移账本。
### 稳定性与部署
- 容器内三个受监管进程(api + worker(io)+ worker:agent),静态 ffprobe。
- qB 同步在事务内 `for update` 重读下载任务后再合并,修复与入库并发时把 `imported` 写回 `importing` 的丢失更新。
- 授权内恢复的核实结论与 run 终态同一次写入,观察者不会读到中间态。
- 完成判定只保留 `applySlotEvent(verify_passed)` 一条路径,整理流程不再自行把订阅置为完成。
- server 测试分为并行的 unit 组和文件级串行的 pg 组,`packages/tasks` 同样串行;`deno task ci` 连续 3 次全绿(约 340–370 秒)。
### 发布前安全修复(W6-B,`docs/plan/07-v0.1-final-review.md` §1.2)
- 多源 Move 授权:`/files/move` 与 `/files/organize`(action=move)按**每个源**所属作品(声明作品 ∪ 源下已登记资产的作品)逐一核对持续授权,任一不覆盖整体 403 并列出未授权项;无法归属作品的源只接受一次性审批;organize 先整体预检,不会只执行一部分组。
- `GET /files/download`、`POST /files/trash/purge` 在注册表标 `auth:"session"`,由中间件统一只放行管理员会话(DEV key 与 admin scope 的 API Key 一律 403);永久删除同口径;`api-registry.test` 新增反向断言,未标 session 的端点不得对 admin scope 返回 403。
- 脱敏键表只剩一份:rss 与 browser 的参数判定改用 `@umt/contracts` 的 `SENSITIVE_QUERY_PARAMS` / `isSensitiveQueryParam`,补齐 `pass_key`、`c_secure_pass`、`refresh_token`、`password`、`uid_key`、`auth` 等写法,加三处一致性测试。
- 回收站"还原到…"只允许可写的 managed 库根;原位还原逐级重建父目录且不跟随符号链接;跨卷还原受 `FILES_TRASH_CROSS_MAX_BYTES` 上限,回收站进出的跨卷复制经 fsproxy。
- `/files/identify` 的远端查询经进程共享的 TMDB 限流器,单次请求最多 20 个远端查询;`POST /files/probe` 改为需要 `organize.execute`(会写 `media_info`)。
- fsworker 阶段完成的进度一律立即上报,不再被节流吞掉最后一跳(全量 ci 下偶发的 fsproxy 用例失败)。
- fsproxy 挂死验收开关 `UMT_FS_TEST_HANG_AFTER_BYTES` 必须同时设置 `UMT_FS_TEST_HOOKS=1` 才生效,preflight 发现已设置会告警。
- 控制台账户弹层新增"二次验证"入口(生成密钥 → 验证码确认开启;凭密码 + 验证码关闭),不显示二维码,手动输入密钥或 otpauth 链接。
### 已知限制
完整清单与出处见 `docs/plan/07-v0.1-final-review.md` §8;范围外内容以 `docs/plan/00-first-version-plan.md` §3.2 与 §6 为准。
**范围外(00 §3.2 / 02 后置)**
1. 国产综艺分段、`require_distinct_asset` 组合校验、浏览器 / camofox 与原站视图、HHClub / CHD、旧库分范围接管、Agent 主观选片与规则学习、多用户。
2. Passkey、主密钥轮换、子代理、Transmission、TTG 自定义适配、馒头 adult 模式。
**订阅(05 §4 遗留)**
3. 完成判定前不会强制刷新元数据;titleQuery 订阅不会自动建档回填;季范围语义(`current_season` 在没有季单元时固定)未做;偏好标签不参与评估。
4. 同作品同季重复订阅没有查重;`prefer_pack`、回退等待期、Agent 选片理由与独立预算、队列按优先级出队、实体级识别词都未做;没有"清账重置"(只能把状态改回 active 重新订阅)。
5. (已解决)完成判定的双路径已在 W6-A 合并为一条,编号保留以便与 07 §8 对照。
**文件管理**
6. NFO / 图片投影(scrape 的 `writeNfo/images` 返回 `not_implemented`)、硬链接、蓝光原盘整目录操作未做;路径守卫没有下沉到 adapters。
7. 从回收站还原不会恢复资产状态,需要重新整理登记;永久删除开关是环境变量,不是设置项。
8. 跨卷进回收站与跨卷还原(都受 `FILES_TRASH_CROSS_MAX_BYTES` 上限、复制经 fsproxy)、永久删除、identify(已经走 TMDB 限流器,单次最多 20 个远端查询)、probe(串行,每次 30 秒超时)仍在 HTTP 请求内执行;浏览、根探测、readdir 与永久删除的 `rm` 不经 fsproxy。计划 v0.1.1 改为入队(07 S-7)。多项永久删除没有服务端的逐项确认(单项要求 `confirmName`)。
9. 前端没有整理向导 e2e 和移动端快照,页面行为靠 model 单测和冒烟覆盖。
**转移与文件系统**
10. `planImport` 规划期的 stat / 哈希、资产对账和文件管理不经 fsproxy;没有根级熔断;失效软链一律按冲突处理;hardlink、organize 源侧空目录上溯清理、蓝光原盘未做。
11. 二进制必须位于 `/app/umt-server`,否则 fsproxy 回退为进程内看门狗(能按时报 TIMEOUT,但卡住的线程无法回收)。基准 B1(50 GB)、B2(并发)、B3(真实 FUSE 冻结)没有跑。
**Agent 与安全**
12. (已解决,W6-B)控制台 TOTP 入口已补;开启时只显示密钥与 otpauth 链接,不渲染二维码。
13. (已解决,W6-B)rss 和 browser 已改用 contracts 的共享键表;全仓凭证泄漏的故障注入测试留到 M2。
14. `GET /inventory/media-servers` 在请求内串行查 Emby;能力调用超时后,底层调用仍会跑完。
15. Agent 页的幂等键来自审计(最多 3 页),审批卡片的 planId 靠解析工具摘要得到,较早的运行可能取不到。
16. 自动恢复只核实到下载恢复,入库由后续流程负责;恢复白名单只有 `task.retry`、`download.recheck`、`identity.resolve`。
**识别与站点**
17. 字幕搜索只到解析层;RSS 不带时区的时间与 HTML 命名实体未处理;过滤器的 tmdb 放行、SPECSUB 等属于 Slot 能力扩展。
**质量与运维**
18. 恢复流程只有人工演练;流程版本升级没有产品侧测试;下载状态机 `ALLOWED` 未收紧;`scanIncremental` 出错时仍返回 complete;AT18 恶意标题 e2e、AT42 未纳管占用没有测试;`vertical.test` 的用例依赖执行顺序;web 单测少(账户弹层的 TOTP 对话框只有类型检查,没有组件测试);E6 自动恢复只核实到 recheck 后回到下载中,engine-retry 用的是 mock enqueue。
19. `deno task ci` 约 6 分钟(W6-B 两次全绿 357 s / 341 s),server 测试(pg 组文件级串行)是主要耗时。