生产 v0.3.8~v0.3.13 均由 8013196 加工作区修改构建部署,此前未提交;本提交补齐源码,
并含未部署的 v0.3.14 原地入库。中间各版本源码状态未保存,无法逐版拆分,详见
docs/plan/17-full-upgrade.md 与 docs/plan/18-organize-release.md。
- v0.3.8 全面升级:Deno workspace 依赖、Router 8 / Vite 8、camofox 1.18.0 / Node 24、
PostgreSQL 18.6、备份客户端 18.6、演示 qB 5.2.4
- v0.3.9 媒体整理:分类规则、整理来源与目录快照(0059)、文件管理整理入口
- v0.3.10 手动下载与入库:独立手动下载、详情页资源下载、TMDB / Local 元数据兜底
(metadata.resolve_organize)、正常多版本 / 一次性洗版(0060)
- v0.3.11 搜索详情与桌面黑边修复
- v0.3.12 列表分页、搜索历史、首页概况
- v0.3.13 统一整理弹窗与队列
- v0.3.14 原地入库(0061,未部署)
同批审计修复:
- 刮削入队:确认原记录存在后才删重放产生的新记录;写回 run 关联失败时保持 queued,
由处理器补关联(对齐 MP 先登记、只在入队失败时记失败)
- 识别升级链只在结果更确定时采用,不再用 no_match 顶替原有歧义候选
- bluray_dir 资产以原盘目录本身为刮削根(MP 同做法)
- metadata.resolve_organize 登记到入库排障 Skill 与能力地图
- db/src/types.ts 按迁移重新生成;contracts 整理动作枚举顺序与数据库对齐
- 测试:原地入库用例改为直接查记录表;domain 测试模板补 version
- 前端:通知铃铛弹层与用户菜单统一样式;站点卡片共用卡头、底栏贴底、分页间距
依赖升级证据只提交摘要文件,registry-snapshot.json 移至 .local/(SHA-256 记于文档)。
Co-Authored-By: Claude Opus 5.5 <[email protected]>
14 KiB
工程检查与调整建议
本报告回答「继续开发之前是否需要先处理工程问题」。当前版本完整 CI 通过,主流程实现和部署均存在;检查仍发现任务升级、入队与业务记录一致性、故障状态判定以及验收口径需要先厘清。建议先做一轮范围明确的恢复与验收补强,再确定后续功能范围。
日期:2026-10-01。升级前业务代码基线:main,8013196,v0.3.7。开发情况与 R01 至 R32 覆盖见 当前开发情况基线。本轮采用两个中等思考强度的独立代码/验证检查、一个低思考强度的文档检查,由主代理复核和汇总。该检查阶段没有修改业务实现、提交、部署或执行数据修复。后续用户授权的依赖与容器升级执行状态见 完整升级记录。
后续核查按用户确认先逐项参考 MoviePilot v3 的业务逻辑,再讨论调整。进度见 MoviePilot v3 逐项业务对照:已固定 v3.0.10-1 源码,第一项任务恢复与升级兼容完成源码对照;后续已实施局部恢复修正并做故障注入,见下方当前落实情况。
并行完成的版本检查见 依赖与程序版本报告:记录 58 个直接依赖、主锁文件和浏览器独立审计、运行程序版本,以及 PG 18/Pi 原生 MCP 的迁移边界;该版本检查阶段没有执行依赖更新或部署。
当前落实情况(2026-10-01)
用户讨论后授权的恢复修正已落到源码:引擎接受任务后回填关联失败保留 queued 并记日志;worker 执行时补关联;巡检优先查最新 run 并修复关联,查询失败跳过当前轮次,不误判成不存在补投。刮削去重复用原业务记录,不让回填失败把已接受的任务标成失败。
enqueue-recovery.test.ts 在隔离 PostgreSQL schema 中完成 9 个故障测试,包括关联写失败、原 run 修复、已有活跃 run 的查询异常。连同接管、刮削和手动季集覆盖回归,5 个测试文件共 34 个测试通过。发布前旧任务检查补到 部署手册。没有引入新恢复器、任务状态机或永久旧 handler。
后续媒体整理范围经过用户逐项讨论后实现:可编辑 TMDB 分类 YAML、单来源配置、复制/移动、qB 标签接管、首次基线+增量快照、一次性存量向导。运行说明见 整理手册。这轮功能已发布为 v0.3.9,见 发布记录;下文检查表保留检查阶段的事实和其他仍需讨论的项目。
1 结论如何使用
「代码已确认」说明能从当前控制流或配置看到该边界;「影响待复现」说明尚未做故障注入,也未证明用户已经受影响;「验收证据不足」说明已有实现不能用当前证据验收完整要求。下文建议是供讨论的工作范围,不是已执行的修复或已批准的排期。
完整 CI 的 3264 个通过测试能证明现有固定回归通过;不能证明未结束的旧版本任务、线上故障下的双写恢复、真实模型行为或真实媒体挂载已经验收。应为这些具体边界补证据,而不是只扩大通过测试的总数。
1.1 用户确认的工程取舍
用户认可任务恢复的调整方向,同时明确本产品面向团队内部,避免过度设计和过度防御。后续优先修复已确认、会影响正常使用的局部问题,复用现有任务引擎、幂等键、巡检和记录页面。MoviePilot 用于参考同一场景的业务处理,不照搬其全部基础设施。
临时查询异常保留日志并等待下一轮,不新增人工审核流程;普通可重试失败使用已有重试,最终失败说明原因并支持现有入口重试。只有删除、覆盖、替换文件等操作出现实际状态不明或冲突时,才停止自动执行并提示处理。没有复现需要之前,不增加通用恢复框架、第二套任务状态机或新的补偿服务。
旧任务兼容先用发布前检查和处置清单解决;没有在途旧任务时,不为假设场景长期维护旧处理器。验证围绕本次改动的失败分支和文件保护展开,T01 至 T06 是场景清单,不作为继续所有开发的统一前置门槛。当前版备份恢复和部署验收已在升级阶段完成,见 升级记录,后续针对实际变更补充验证。
2 建议优先核对的恢复边界
2.1 刮削任务升级后的旧任务承接
代码已确认,当前部署未发现未结束的旧刮削任务。 handlers.ts 第 193 行起只注册 scrapeMedia v2,输入是 recordId。旧版本 v1 使用作品 ID 和触发方式等输入。worker 在 openworkflow-engine.ts 第 221 行起按已注册的任务名和版本过滤认领,当前清单没有 v1。
因此升级前未结束的 v1 run 如果存在,当前 worker 没有对应处理器。0058 迁移还将原 media_scrape 表替换为 scrape_record,不能简单恢复旧处理器而不核对数据结构。需要明确旧任务应完成、迁移、取消还是以说明终止。
本轮对部署数据库只读聚合:scrapeMedia|v1|completed|1,没有其它刮削任务状态;scrape_record 没有记录。这次没有发现受影响的活动旧任务,也没有据此做任何取消或补投。 这个结论只对应本次检查时点。
最小下一步:把「升级前未结束的任务版本清单及处置」加入发布记录。在隔离环境用上一版本入队、当前版本恢复验证兼容方案,避免只验证同版本崩溃恢复。
2.2 入队成功和业务记录关联回填不是一个原子操作
控制流已确认,故障影响待复现。 scrape.ts 第 152 行起先插入 queued 记录,第 192 行入队,第 207 行回填 engine_run_id。入队成功而回填失败,也进入同一个 catch,将记录标为 failed/task_enqueue_failed。第 476 行的执行器对 failed 记录直接返回。
可能出现两种不一致:插入后、入队前进程退出,留下没有 run 的 queued 记录;入队已成功、回填失败后记录先被标为 failed,worker 再读取时跳过。实际结果取决于失败时点,本轮没有通过故障注入证明发生概率,也没有把它写成已发生的线上故障。
common.ts 第 134 行的 enqueueTracked 也依次执行业务行、引擎入队和回填,应一起定义恢复口径。稳定幂等键可以帮助找到已有 run,但本身不等于已完成关联恢复。
最小下一步:在隔离测试中分别注入这三个时点的失败,确认最终状态。再选择恢复回填与补投方案,或复用现有事务 outbox;保持改动集中在这些入口。
2.3 引擎查询失败被当成查无任务
异常处理行为已确认,重复补投的实际影响待复现。 common.ts 第 171 行在巡检中使用 engine.get(...).catch(() => null),查询异常和明确不存在共用 null。下一时间槽可能补投新 run,而旧 run 仍在运行,共享同一业务任务行。
下载与文件操作已有底层幂等账本,不能直接推断会重复下载或覆盖文件。但两条 run 竞争业务行、回填关联和状态的风险,需要单独验证。
最小下一步:故障注入中模拟一次引擎查询异常;讨论让查询异常记录并跳过本轮,仅在明确查无 run 或终态时补投。这个边界适合与 2.2 一起检查。
2.4 默认空壳可以掩盖正式任务注册遗漏
维护风险已确认,当前核心任务都有正式处理器。 context.ts 第 96 行为缺失的核心任务注册 stub;modules.test.ts 第 86 行主要检查任务名存在。未来如果漏注册真实 handler,名字检查仍可能通过,stub 回显 todo 后可以成功结束。
本轮装配核对确认最初 9 个核心任务均已由业务模块覆盖,不应把当前主流程描述成「还是空壳」。
最小下一步:下一次触及模块或任务注册时,增加完整生产模块装配的处理器来源断言;讨论是否只允许局部测试装配使用 stub。无需因此重写任务系统。
3 应先明确的验收口径
| 检查项 | 当前事实 | 需要补的最小证据 |
|---|---|---|
| PG 测试必执行 | 部分 server/tasks harness 在 PG 探测失败时跳过;默认 db 包连接失败会报错,所以不能称默认整条 CI 会在无 PG 时全绿 | 在 CI 汇总中保留跳过清单,讨论严格 PG 模式;区分允许跳过的真实模型和真实 qB |
| 前端冒烟 | 独立于普通 CI;smoke.mjs 第 188 行详情页数据获取失败或为空会 skip,最终主要按失败数退出 | 固定演示数据、必须执行的详情页,以及接口错误和合法空数据的不同判定;本轮没有跑页面冒烟 |
| 模型行为 | E13 有恶意网页清洗、URL 与不可信标注回归,但用固定 FakeScript;AG-5 真实前后评测默认关闭且历史记录明确未跑 | AT18 的真实模型行为单独评测,不用 fake 模型脚本替代;模型调用须在明确范围内进行 |
| 部分入库后的清理 | downloads.ts 第 1043 行检查最近整理成功并拒绝失败/排队/运行/取消文件,已有保护 | AT29 构造部分成功仍有源文件的反例,核对不会整种清理;不能写成「没有删除保护」 |
| 未纳管占用 | 域层有 managed:false 和增长风险断言;服务层现有阈值测试主要使用假磁盘 |
AT42 用固定同卷场景核对汇总占用和暂停范围 |
| 多实例同 hash | 多下载器选择有测试,未找到两个实例同 hash 后分别同步、暂停、删除的完整专项断言 | AT73 在 mock qB 的两个实例中核对任务与清理隔离 |
| 备份一致性和恢复 | backup.sh 依次 pg_dump、导出映射、归档在线会话,产物不是同一时点;早期临时恢复演练曾通过 | 当前版隔离恢复演练,明确在线变更如何影响映射和会话比对,再决定是否需要一致性改造 |
| 镜像运行与来源 | 编译自检在空环境验证模块图可加载,不能替代最终镜像的进程、工具、静态文件、权限和挂载检查 | 下一次发布记录源码提交和镜像摘要,并做隔离镜像启动验收 |
本轮完整 CI 中 PG 集成实际运行;上述 PG 问题属于后续执行环境变化时的验收可靠性,不是本轮大量跳过集成测试。没有新增或改写测试来掩盖缺口。
4 已解决的工程问题与文档调整
已有 cleanup/reconcile 入队、后台任务编排、IO 与 Agent worker 隔离、文件/网络/维护分道、请求限制器、整理 walk 上限、sha256 子进程和操作账本。GET /inventory/media-servers 已多实例并行、限制实例内并发并设总超时,旧串行遗留不能继续作为待开发项。
本轮文档调整集中在影响当前判断和操作的内容:建立需求基线与工程检查报告;将早期覆盖表和解耦审计标为历史;校正 README 的能力数、刮削、验证和部署形态;统一当前部署示例的 .env.deploy;修正默认桌面镜像构建前提、浏览器内存配置、MCP 工具数、站点详情补请求和识别异步说明。
基线中的所有本地文件链接均另行检查。历史演练表和对应日期、测试数继续保留,避免把新结论改写进旧验收记录。源码中的旧注释与较早手册可能仍有残留,遇到冲突以当前代码和这两份基线报告为准。
5 供讨论的下一阶段范围
建议下一阶段先以「任务升级和异常恢复可核验」为范围,交付 2.1 至 2.3 的故障与升级证据、当前恢复演练、明确的测试跳过清单和发布来源记录。2.4 可在同一轮触及装配时补强。这里是建议,尚未修改对应实现或开始功能开发。
然后再确定功能阶段:综艺完整性、独立双版本、旧库接管、智能体选片与规则优化都仍有需求缺口,但应按具体场景分别验收。每阶段要明确触发入口、最终结果、失败和等待处理、固定样本与真实环境需求。
讨论时需要决定的是下一阶段的目标和边界,以及哪些验收证据必须先补。已有授权、稳定路径和清理保护不需要重新设计;尚未复现的问题应先做有针对性的核查,再确定最小实现调整。
6 升级核验新增的待讨论证据
2026-10-01 的 1.18 浏览器升级核验已覆盖正常重启、空闲回收、旧元素引用拒绝、登录保持与 SIGKILL 后未落盘登录丢失识别。现有核验脚本原先会捕获错误后返回成功,且仍期待自动重连之前的行为,本次已修正并收紧下载关联和脱敏断言。
精确恢复页面地址仍有证据缺口:核验 a 阶段末尾曾导航回列表,b/idle 恢复观测地址为详情页,缺少 a 末尾的数据库 URL 与最终快照对照,目前不能判定为已复现业务故障。后续应在重启前记录 BrowserService.view(sid).currentUrl、snapshot.url、browser_session.current_url 与当前 browser_tab.url,重启后逐一比较;恢复入口见 apps/server/src/modules/browser/service.ts 的 restoreUrl(row.current_url) 及适配器 reopenSession。十项能力核验不等同于精确 URL 恢复已经验收,下一轮业务对照应补这个场景。