docs(changelog): B1 complete [0.1.0] with file manager, subscriptions, transfer, agent UI and known limits

Covers W4-E4/F, W5-A..E and W6-A grouped by feature; known limitations
replaced with the 19 items from docs/plan/07 §8 (stale series-completion
item removed).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-28 00:34:36 +08:00
1 parent 1c7af8b7e5
commit b48d8592d5
1 file changed
+93 -5
+93 -5
View File
@@ -2,7 +2,7 @@
版本号遵循 [SemVer](https://semver.org/lang/zh-CN/)。所有成员包(`apps/*`、`packages/*`)与根 `deno.json` 使用同一个版本号;`/api/v1/health` 与备份清单里的版本取自 `apps/server/deno.json`。
## [0.1.0] - 2026-09-27
## [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`。
@@ -44,9 +44,97 @@
- 工作流引擎面板支持重跑:`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 秒)。
### 已知限制
- v0.1 明确不做的内容见 `docs/plan/00-first-version-plan.md` §3.2:国产综艺分段、双版本 require_distinct_asset 组合校验、浏览器接入与原站视图、HHClub / CHD、旧库接管、Agent 主观选片与规则学习、媒体级主动整理 UI、多用户。
- 验收报告 `docs/plan/04-v0.1-acceptance.md` §1.2 的应修项和 §1.3 的建议项里,未标"已修"的条目留在 v0.1.x 处理。
- 剧集总集数目前没有来源会把集单元确认为 `confirmed`,所以持续追踪的剧集 Slot 在 v0.1 不会进入 satisfied。
- 恢复流程只有人工演练记录,没有自动化测试。
完整清单与出处见 `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 合并为一条(见"稳定性与部署")。
**文件管理**
6. NFO / 图片投影(scrape 的 `writeNfo/images` 返回 `not_implemented`)、硬链接、蓝光原盘整目录操作未做;路径守卫没有下沉到 adapters。
7. 从回收站还原不会恢复资产状态,需要重新整理登记;永久删除开关是环境变量,不是设置项。
8. 跨卷进回收站(≤2 GiB)、跨卷还原、永久删除、identify(每项超时 15 秒,不经 TMDB 限流器)、probe 都在 HTTP 请求内执行,也都不经 fsproxy。
9. 前端没有整理向导 e2e 和移动端快照,页面行为靠 model 单测和冒烟覆盖。
**转移与文件系统**
10. `planImport` 规划期的 stat / 哈希、资产对账和文件管理不经 fsproxy;没有根级熔断;失效软链一律按冲突处理;hardlink、organize 源侧空目录上溯清理、蓝光原盘未做。
11. 二进制必须位于 `/app/umt-server`,否则 fsproxy 回退为进程内看门狗(能按时报 TIMEOUT,但卡住的线程无法回收)。基准 B1(50 GB)、B2(并发)、B3(真实 FUSE 冻结)没有跑。
**Agent 与安全**
12. 控制台没有 TOTP 开关入口(后端 `GET/POST /auth/totp` 已有)。
13. rss 和 browser 的脱敏键表没有与 contracts 统一。
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 单测少。
19. `deno task ci` 约 6 分钟,server 测试(pg 组文件级串行)是主要耗时。