# B 站博主动态采集辅助工具 MVP 开发工作记录 - 日期:2026-08-04 - AI:`infodev-2` - 角色:`dev.developer.project.secondary` - 事项:`DEV-PROJECT-INFO-BILI-DYNAMIC-COLLECTOR-MVP-20260804-001` - 上游:`REQ-BILI-DYNAMIC-COLLECTOR-20260804-001` - 请求方 Codex task:`019fcc5d-798f-7ea1-8325-3a4d1f2dc5a5` - 共享审核员:`dev.reviewer.project / inforev / 019fb7c5-e1fd-7df0-8ec9-c87edea4215d` ## 1. 接手与分类 已读取需求、项目规范、项目配置、common/本地编码与审计规范、project 开发工作区说明,并核对本角色写入范围。事项限定为一个 stdlib 本地 CLI、一个示例配置、一个测试文件、一份脱敏 fixture 和一页用法,不联网、不控制浏览器、不并发执行业务、不下载内容、不写正式采集目录,按“有需求文档的轻量实现”执行,不创建重型编码方案。 正式 `F:\video\<博主名>\` 与 `ana-data/news-<博主名>/` 的路径授权扩展仍由 project.admin 处理。本开发不等待该配置,只在测试临时目录和 `dev/tmp/bili-dynamic-collector-mvp/` 验证。 ## 2. 实现 - `dev/project-dev/bili_dynamic_collector.py` - `check`:最近时间窗、动态/opus/BV/URL 去重、Windows 安全 stem、待办 JSON、append-only manifest。 - `move-completed`:明确映射、下载完成度、下载目录边界、链接/reparse、后缀、重名和唯一性预检;partial + fsync + SHA-256 + hard-link no-overwrite 提交;失败追加 `MOVE_FAILED`,成功后再删除源。 - `handoff`:复核目标范围和 SHA-256,生成内容寻址且 `sent=false` 的 Codex 原生任务草稿,不自动发送。 - 全入口拒绝认证/会话字段;无网络或浏览器依赖。 - 示例:`dev/project-dev/bili_dynamic_collector.example.json`,只指向开发 tmp。 - 测试/fixture:`dev/project-dev/test/test_bili_dynamic_collector.py`;`dev/project-dev/test/fixtures/bili_dynamic_collector/dynamic_items.json`。 - 说明:`dev-doc/project-doc/B站博主动态采集辅助工具.md`;目录入口已补充。 ## 3. 验证 - py_compile:PASS。 - CLI help:PASS。 - 目标 unittest:`6/6 PASS / 0.610s`。 - project flat discover:`69/69 PASS / 49.873s`。 - 离线 CLI smoke:首次 check=`TODO_GENERATED/new=3`;55 字节非媒体 fixture move=`VIDEO_MOVED`;handoff=`HANDOFF_DRAFT_READY/sent=false`;相同输入复跑=`NO_NEW_ITEMS/new=0`。 - overlap safety:同 state 重叠调用一方按 `E_STATE_LOCKED` 停止,结束后无残留锁,串行重跑成功。 - `git diff --check`:PASS。 - `mbx validate --project project-info --governance`:`OK/projects=1/warnings=0`。 - 证据:`dev/tmp/bili-dynamic-collector-mvp/selfcheck.md`。 ## 4. 需求—代码自检 - 72 小时配置、稳定标识去重、manifest 字段与状态、Windows 时间命名:已实现并测试。 - 重跑跳过、失败可重试、重名停止、下载目录到目标目录安全移动:已实现并测试。 - 视频处理员交接摘要和定时检查入口:已实现;草稿不自动发送。 - 账号口令/cookie/token、访问控制绕过、浏览器扩展自动化、真实下载和正式采集写入:代码中不存在,smoke 动作为 0。 - 既有 `ana-data/news-青枫浦上Q/` 与其他正式采集内容:未读取、未修改。 ## 5. 当前状态与限制 当前状态:`PENDING_SHARED_REVIEWER_LIGHT_IMPLEMENTATION_REVIEW`。 限制:动态正文、原图和扩展任务仍由人工/浏览器扩展取得;目标文件系统不支持同目录 hard-link 时安全停止;正式路径授权完成前只使用开发 tmp/fixture 配置。未发送媒体处理交接,未创建定时任务。 ## 6. 独立安全审查终态 - 回执:`HANDOFF-INFOREV-INFODEV2-BILI-DYNAMIC-COLLECTOR-MVP-IMPLEMENTATION-REVIEW-RESULT-20260804-001`。 - 结论:`HOLD_5_TERMINAL_SNAPSHOT`;目标 `6/6`、project `69/69`、编码/治理/UTF-8 均通过,但 5 个实质阻断未关闭。 - 阻断:实现实际满足重型门禁但无已审设计;映射选择器不强制全一致且批量同源可先部分提交;源删除失败的 exit 4 在原映射重跑时降级;manifest 不经过秘密字段 gate;生成的原生 handoff 草稿缺少必填身份与 scope/evidence/expected_action。 - 可保留:源码、文档、fixture、自检和测试作为隔离开发快照;`check` 只允许在 dev/tmp/TemporaryDirectory 对完全可信、无秘密、人工确认的一实体一来源输入做演示。 - 禁止:不得把工具作为已验收采集器交付;不得对真实下载或正式目录运行 `move-completed`,不得调度/并发生产使用,不得发送当前 handoff Markdown,不得依赖 manifest 秘密保护或 retained-source 重试语义,不得写 `F:\video` 或正式 `ana-data`。 - 按请求方即时收尾约束,不开启后继设计、返修复审、授权或外部动作。最终状态:`TERMINAL_HOLD_DEVELOPMENT_SNAPSHOT_ONLY`。 ## 7. 请求方恢复 HOLD/5 最小修复 - 新授权:终态交付后,请求方明确“继续推进”,只修独立审核 F1—F5,不扩大产品范围。 - 分类已纠正为重型;已创建 `dev-doc/project-doc/开发方案/CODE-DESIGN-PROJECT-INFO-BILI-DYNAMIC-COLLECTOR-MVP-HOLD5-REPAIR-V001.md`。 - V001 只冻结 exact selector/同源批次零副作用、retained-source 告警粘性、manifest 统一 secret gate 和完整稳定 native handoff envelope;网络、浏览器、下载和正式路径继续排除。 - 当前代码、配置、测试和 fixture 未修改;状态=`V001_DESIGN_REVIEW_PENDING`。 ## 8. V001 设计复审 HOLD/1 与 V002 限定修订 - 原共享审核员返回 `HOLD/1`;重型分类、选择器一致性方向、manifest 秘密字段检查和规范原生 handoff 均已通过。 - 唯一冲突是终态重跑与 `source_file` 物理身份预检的先后关系。V002 固定为:全批选择器与实体唯一性先行;随后读取最新状态;仅 `ACTIVE_MOVE` 进入源/目标预检;已移动和 retained-source 终态均从 manifest 投影且不依赖当前源是否存在。 - 代码、配置、测试和 fixture 继续冻结,等待 V002 限定设计 PASS。 ## 9. V002 限定复审 HOLD/1 与 V003 最终收紧 - 原顺序冲突已经关闭;唯一剩余项是 V002 的“无移动终态”措辞可能扩大活动状态。 - V003 废止该措辞,`ACTIVE_MOVE` 只允许精确的 `TODO_QUEUED` 和 `MOVE_FAILED`;处理阶段、缺失/空白状态及未知状态全部在阶段 B 前以 `E_STATUS`、exit 3 零副作用停止。 - 追加一组参数化 CLI 入口反例合同;实现仍保持冻结,等待最后一次限定设计复审。 ## 10. V003 PASS 与五项实现 - V003 最终限定设计审核=`PASS/0`;V001+V002+V003 成为唯一实施合同,随后才修改代码/配置/测试。 - F2:所有 selector 单独命中且全一致;整批 entity 唯一后才分类;活动行做 source identity/target 预检,任何预检失败不写 manifest/目标/源。 - F3:retained-source 在源存在或后续人工删源的相同 mapping 重跑中均保持 exit 4、原目标/hash/失败原因和 manifest bytes。 - F4:manifest 每行在 schema/identity/status 前走递归 secret gate,三个命令共用。 - F5:配置化精确 route,生成完整 deterministic native handoff,`--now` 不影响相同证据的 handoff bytes,仍不自动发送。 - 验证:目标 `11/11 PASS / 1.393s`;新鲜闭环 `1/1 PASS / 0.226s`;project `74/74 PASS / 48.657s`;外部动作 0。 - 当前等待同一共享审核员一次限定实现复审。 ## 11. 限定实现复审 HOLD/2 - 独立正向复验目标 11/11、新鲜闭环 1/1、project 74/74 全 PASS,五项主要修复与无外部动作边界保留。 - 剩余两项 fail-closed 阻断:终态持久证据缺失仍可能成功投影;manifest 标量换行可注入原生 handoff。 - 按请求方“PASS/0 或明确剩余阻断返回”的单回合约束,本轮不再修改代码或自动开第二次实现复审;状态=`HOLD_2_ISOLATED_DEVELOPMENT_SNAPSHOT_ONLY`。 ## 12. HOLD/2 持续授权与 fail-closed 返修 - 请求方明确要求继续至 PASS/0;无需新设计,只修审核 F1/F2。 - 新增 terminal 状态证据校验与 handoff 全消费标量控制字符/格式校验;错误只返回安全字段路径。 - 新增 19 组参数化反例,逐组验证 exit 3、`E_MANIFEST`、业务树/manifest/目标不变、无残留且 stdout 不含污染值。 - 目标 13/13、新鲜闭环 1/1、project 76/76 PASS;外部动作和 fixture 修改均为 0。 - 当前等待原共享审核员限定复审;若仍有同边界问题按新授权继续最小闭环。 ## 13. HOLD/2 fail-closed 限定复审 PASS/0 - 回执=`HANDOFF-INFOREV-INFODEV2-BILI-DYNAMIC-COLLECTOR-MVP-HOLD2-FAIL-CLOSED-REREVIEW-RESULT-20260805-001`;结论=`PASS/0`、阻断=`0`。 - F1 terminal persisted evidence fail-closed 与 F2 handoff manifest 标量控制字符/格式注入均 CLOSED;原阻断反例 2/2、目标 13/13、project 76/76 均由审核员独立复跑通过。 - 审计=`DEV-AUDIT-PROJECT-INFO-BILI-DYNAMIC-COLLECTOR-MVP-HOLD2-FAIL-CLOSED-LIMITED-IMPLEMENTATION-REREVIEW-20260805-001`;回执时文件=`250254/43FD12548388E3760DCB52644273E54318591D44CE3D83E42013E1699F8D64B2`。 - 当前=`PASS_0_PROJECT_TOOL_DELIVERABLE`;开发与复审链关闭,不追加功能或真实运行。网络、浏览器、下载、自动 native send、调度、`F:\video` 和正式 `ana-data` 仍需另行明确授权。 ## 14. 请求方接收关闭 - 回执=`HANDOFF-VIDEO-DOWNLOADER-INFODEV2-BILI-DYNAMIC-COLLECTOR-PASS0-ACK-20260805-001 / ACCEPTED`;关联最终交付=`HANDOFF-INFODEV2-VIDEO-DOWNLOADER-BILI-DYNAMIC-COLLECTOR-MVP-PASS0-FINAL-20260805-001`。 - 请求方确认 PASS/0 工具与证据完整,本事项状态=`ACCEPTED_CLOSED`;不再修改代码、测试、配置或 fixture。 - 请求方声明当前博主真实浏览器/下载、`F:\video\青枫浦上Q`、正式 `ana-data`、原生转写交接和每小时调度已有既有授权;执行由视频下载员负责,开发员本轮动作仍为 0。 - 后续新缺陷另行回传,当前保持空闲。