DEV-PROJECT-INFO-BILI-DYNAMIC-COLLECTOR-MVP-20260804-001REQ-BILI-DYNAMIC-COLLECTOR-20260804-001CODE-DESIGN-PROJECT-INFO-BILI-DYNAMIC-COLLECTOR-MVP-HOLD5-REPAIR-V001.md1191716C14FB2751A0EAB63F76371E75D0569FF8EF5B47FDD8724BE861314B6062733HOLD/1,唯一未闭环项为 F1_DESIGN_RERUN_PREFLIGHT_ORDER_CONFLICT本修订 PASS 前,代码、示例配置、测试和 fixture 继续保持冻结;不运行网络、浏览器、下载,不接触 F:\video 或正式 ana-data。
move-completed 对整个 mapping 批次采用下列固定顺序。任何阶段失败都在复制、目标创建、源删除和 manifest 追加之前结束。
dynamic_id、opus_id、bvid、source_url;每个选择器都必须存在、唯一命中,且同一行的全部选择器必须命中同一实体。source_url 继续执行 V001 的 registered-host 规范化。E_ENTITY_DUPLICATE。该检查不依赖 source_file 是否仍存在。TERMINAL_MOVED:最新状态是 VIDEO_MOVED 或 COMPLETE;TERMINAL_RETAINED:最新状态是 VIDEO_MOVED_SOURCE_RETAINED;ACTIVE_MOVE:最新状态是 TODO_QUEUED、MOVE_FAILED,或没有移动终态。TERMINAL_MOVED 返回 ALREADY_MOVED、exit 0,并复用已记录的 local_file 与 sha256;TERMINAL_RETAINED 返回 VIDEO_MOVED_SOURCE_RETAINED、exit 4,并复用已记录的 local_file、sha256 与 failure_reason;即使保留源后来被人工删除,告警也保持粘性;source_file,不参与物理源重复检查,不创建、删除或改写文件,不追加 manifest 事件。只有 ACTIVE_MOVE 行进入以下预检:
source_file 必须存在且为允许下载根目录中的普通文件;逐级拒绝链接、junction/reparse,检查稳定年龄与扩展名。(st_dev, st_ino);inode 为 0 时使用 normcase(resolve(strict=True))。ACTIVE_MOVE 行检查 source identity 唯一性;重复即 E_SOURCE_DUPLICATE。MOVE_FAILED;只有完整两阶段预检通过后发生的真实运行时事务失败才可按 V001 记录失败事件。终态行可以与活动行共存于同一批次。终态行仍参与 entity 唯一性检查,但不参与 source identity/目标写入集合;活动行全部通过阶段 B 后才允许逐项进入 V001 已冻结的 copy/fsync/hash/atomic link/manifest/delete 事务。
| manifest 最新状态 | 当前源文件 | 分类 | 输出状态 | exit | manifest 变化 |
|---|---|---|---|---|---|
VIDEO_MOVED / COMPLETE |
不存在或存在 | TERMINAL_MOVED |
ALREADY_MOVED |
0 | 无 |
VIDEO_MOVED_SOURCE_RETAINED |
存在 | TERMINAL_RETAINED |
VIDEO_MOVED_SOURCE_RETAINED |
4 | 无 |
VIDEO_MOVED_SOURCE_RETAINED |
后来被人工删除 | TERMINAL_RETAINED |
VIDEO_MOVED_SOURCE_RETAINED |
4 | 无 |
TODO_QUEUED / MOVE_FAILED / 无终态 |
存在且通过预检 | ACTIVE_MOVE |
按事务结果 | 0/4/3 | 仅运行时事务可追加 |
TODO_QUEUED / MOVE_FAILED / 无终态 |
不存在或不安全 | ACTIVE_MOVE |
输入/安全错误 | 2/3 | 无 |
批次汇总规则保持不变:只要投影或新事务结果中包含一个 retained-source,整体为 COMPLETE_WITH_RETAINED_SOURCE、exit 4;否则按既有成功/失败规则汇总。
在 V001 第 8 节基础上必须新增以下实际 CLI 入口回归,全部使用 TemporaryDirectory、小型非媒体字节文件和秘密无关的净化 JSON:
ALREADY_MOVED,目标/hash/manifest bytes 完全不变,目录无新增临时文件。VIDEO_MOVED_SOURCE_RETAINED,复用原 local_file/sha256/failure_reason,源、目标和 manifest bytes 不变。测试必须从 CLI/main() 入口进入,不得只调用内部分类函数。三种重跑均须比较调用前后 manifest 原始 bytes,而非只比较事件数量。
V001 与 V002 组合为唯一实施合同。V002 限定设计 PASS 后,开发员才可一次性实现五项 HOLD 修复,并运行目标测试与 project 回归;全程不得联网、打开浏览器、触发下载、写 F:\video 或正式 ana-data。实现完成后只向原 dev.reviewer.project 提交一次限定实现复审。