edit | blame | history | raw

B 站动态主动刷新采集器实现与验证证据

事项:DEV-PROJECT-INFO-BILI-DYNAMIC-REFRESH-COLLECTOR-20260813-001

需求:REQ-BILI-DYNAMIC-COLLECTOR-20260804-001

实施者:dev.developer.project.secondary / infodev-2

审核员:dev.reviewer.project / inforev

1. 使用入口

python -B dev/project-dev/bili_dynamic_collector.py `
  --config dev/project-dev/bili_dynamic_collector.example.json `
  refresh-begin

python -B dev/project-dev/bili_dynamic_collector.py `
  --config dev/project-dev/bili_dynamic_collector.example.json `
  refresh-commit `
  --input <refresh-begin 返回的 evidence_path>

refresh-beginrefresh-commit 是离线协调入口,不控制 Chrome、不联网,也不读取 Cookie、token、localStorage 或页面源代码。页面操作者必须把一次受支持刷新产生的有限、无秘密 JSON evidence 写到 refresh-begin 返回的精确路径,再由 refresh-commit 校验和落账。

刷新身份固定为 青枫浦上Q / 1420210197 / https://space.bilibili.com/1420210197/dynamic,每个 run 最多刷新一次。页面 evidence 由 bili_dynamic_page_observation_contract.jsonbili_dynamic_page_extract.js 的精确哈希绑定;cards 与 unparsed nodes 按 DOM 位置互斥。只有页面身份、正文、时间窗与终止标记共同证明覆盖完整时,空结果才可成为 REFRESH_CONFIRMED_NO_NEW。公开搜索或 API 只能作非权威补充发现,空结果、-412、验证码、访问限制和不可读页面永远不能证明 no-new。

五个正式终态为:

  • NEW_ITEMS_SAVED:有通过合同的新正文、原图或视频 metadata,内容与 state/formal 两份 manifest 一致提交;
  • REFRESH_CONFIRMED_NO_NEW:页面观察完整且所有已解析实体均被历史 catalog 去重;
  • REFRESH_FAILED_PAGE_UNREADABLE:刷新后页面就绪或只读提取超时/失败;
  • REFRESH_BLOCKED_AUTH_OR_ACCESS:页面明确登录、验证码、访问控制或等价阻断;
  • PARTIAL_DISCOVERY_UNCONFIRMED:页面覆盖不完整或只有非权威公开发现,不能确认无新增。

2. 审核基线与实现入口

  • 组合方案:V001 + V002 + V003 + V004;V004 最终锁协议复审为 PASS/0
  • 主 CLI:dev/project-dev/bili_dynamic_collector.py
  • refresh 协调层:dev/project-dev/bili_dynamic_refresh.py
  • 页面 observation 合同:dev/project-dev/bili_dynamic_page_observation_contract.json
  • 只读提取脚本:dev/project-dev/bili_dynamic_page_extract.js
  • 示例配置:dev/project-dev/bili_dynamic_collector.example.json
  • 原功能回归:dev/project-dev/test/test_bili_dynamic_collector.py
  • refresh 测试:dev/project-dev/test/test_bili_dynamic_refresh.py
  • fixture 说明:dev/project-dev/test/fixtures/bili_dynamic_refresh/README.md

原采集器的 check、move-completed、handoff 与终态证据合同保留;只新增 refresh 配置、两个 CLI 子命令和独立 refresh 模块。

正式前像 ana-data/news-青枫浦上Q/manifest.jsonl 为 48 行事件账。离线 catalog 验收复算为 22 个 identity component、16 个已保存实体、5 个视频跟踪实体和 1 个可重试实体。

3. 已实现合同

  1. refresh-begin 创建 schema 2 pending 和一小时一个的 durable slot,绑定 run/config/contract/extractor/evidence path 与进程 identity;同一 UTC 小时不重复启动。
  2. refresh-commit 严格校验 duplicate-key、UTF-8、路径、run、时钟、页面身份、观察计数、cards/unparsed 位置互斥、终止标记和安全发现状态。
  3. 页面不可读和无凭据公开 endpoint -412 分别重放为 REFRESH_FAILED_PAGE_UNREADABLE 与非权威 partial/access evidence;两者都不能进入 no-new。
  4. mixed-history loader在不改正式账的前提下复算事件身份、状态与保存文件 hash;新正文、图片和视频 metadata 使用同一 catalog 去重。
  5. state lock 使用稳定一字节 kernel-backed 文件和短生命周期 owner metadata;正式 manifest lock 使用进程创建 identity、同目录同卷 quarantine、generation 与 claim attempt,恢复歧义一律停止。
  6. 新内容提交同时构造 state/formal manifest 候选并记录事务 phase;正式锁、artifact、双 manifest 和 terminal slot 的 crash-reopen 由 pending 驱动恢复,失败不会冒充成功或 no-new。
  7. 最近运行只保留 168 个 slot;terminal evidence 与 latest 投影由 run/status/hash 绑定,重复 commit 返回同一终态而不重复正式事件。

4. 离线验证

python -B -m py_compile `
  dev/project-dev/bili_dynamic_collector.py `
  dev/project-dev/bili_dynamic_refresh.py

python -B -m unittest `
  dev/project-dev/test/test_bili_dynamic_collector.py `
  dev/project-dev/test/test_bili_dynamic_refresh.py

python -B dev/project-dev/bili_dynamic_collector.py --help

结果:22/22 PASSpy_compile=PASS;CLI help 显示 check / move-completed / handoff / refresh-begin / refresh-commit 五个入口。

refresh 九项非真空测试覆盖:真实 timeout/-412 状态、no-new 终止标记硬门、cards/unparsed 互斥与位置冲突、正文双 manifest 提交、168 小时 slot 与 pending 恢复、kernel-backed state lock、正式 48/22/16/5/1 catalog、dead formal lock 同卷接管。原 13 项继续覆盖既有采集器安全合同。

项目回归按文件拆分后,本任务两份测试均通过。发现的项目级异常不属于本任务:

  • bili_authenticated_extension/test_protocol.py 1 项和 test_native_host.py 6 项被独立产品源码树中的四个 __pycache__/*.pyc 触发 exact-source-set fail closed;本事项未删除或修改该独立产品缓存/源码。
  • bili_authenticated_extension_managed_load/test_managed_load.py 在有界单文件运行中长期未终止;仅停止已确认属于该测试命令的子进程,未杀其他 Python/MCP 进程,也未修改该独立产品。
  • 其余已完成的逐文件回归未发现本任务回退;长耗时的股票估值 V2 59 项也通过。

项目回归结论是 本任务通过;整库受两个独立环境/长时问题阻断,已精确归因,不宣称整库全绿。

5. 正式数据与真实动作边界

  • 正式 manifest 开发前像为 51598 bytes / 0E69AF2AF1C4B0014D2033A21F3986E283ECFD758EA652E7F2416006736C8D73 / 48 lines;最终检查必须仍完全一致。
  • 本实现只在 TemporaryDirectory 和示例 tmp/ 路径运行。正式 ana-data 写入为 0。
  • 2026-08-13 的既有一次真实样本只用于脱敏离线重放:目标标签 reload 恰好一次,15 秒页面边界和 8 秒只读 evaluate 均超时,结果固定为 REFRESH_FAILED_PAGE_UNREADABLE;无凭据公开 endpoint 返回 code=-412,只支持 partial/access 附证。
  • 本轮新 Chrome reload、DOM/evaluate、公开 API、network retry、Cookie/session 读取、下载、媒体写入、F:\video、扩展/policy/HKCU、转写均为 0。
  • 实现 PASS 只表示离线协调器可交付,不自动授权真实刷新或正式内容写入;运营动作仍由请求方/管理员按独立边界调度。

6. 实现审核状态

当前状态:IMPLEMENTATION_COMPLETE_PENDING_ORIGINAL_REVIEWER。本文件记录开发者冻结证据;最终可用结论以同一 task、同一 dev.reviewer.project / inforev 实现复审终态为准。

7. HOLD/4 聚焦修复与复验(覆盖第 6 节状态)

  • 首次实现复审正式终态为 HOLD/4,MB-X 结果消息为 msg_20260813173933589_7efe75d8。本节仅闭环该结果列出的 F1—F4,不重开 V001+V002+V003+V004 已通过设计,不扩大产品或真实动作范围。
  • F1:page_observation.cardsitems 现在按规范化 dynamic_id/opus_id/bvid/dedupe_keys/content_type/published_at/source_url 精确双向绑定;重复绑定漂移、跨卡 token 重叠、缺项、额外项和内容属性不一致均以 E_EVIDENCE_ITEM_BINDING 失败关闭,不能投影为无新增。
  • F2:mixed-history catalog 现在跨全部 JSONL 行构造 identity union,并验证 schema 1/2 状态、身份、URL/BVID/opus 一致性与 schema 2 artifact path/bytes/SHA-256;状态优先级固定为 saved、video tracking、retry-only,冲突组件失败关闭。
  • F3:每小时终态 slot 与 latest.json 冻结为精确八键索引;无正式变化显式记录 NO_FORMAL_CHANGE receipt;slot/latest 均写后读回。EVIDENCE_BOUNDTERMINAL_RECORDED 重开可复算终态、重建缺失/较旧 latest 并清理自身 pending,冲突 latest 不覆盖。
  • F4:V004 CREATE_PLANNED 在持有进程死亡或 PID reuse 时按同 generation、attempt+1 换绑;已存在失败 claim 先移动到同卷 quarantine,并写入/验证 owner marker,成功恢复后只清理本次所有权范围。
  • 新增 reviewer 非真空反例覆盖观察/条目缺失与重叠、跨行 catalog 冲突与 schema 2 artifact 漂移、无变化与正式提交 receipt、slot/latest 写入故障及重开、CREATE_PLANNED absent/existing claim 两类恢复。
  • 最终目标测试为 collector 13 项 + refresh 17 项,共 30/30 PASSpy_compile=PASS、CLI help exit 0。整库 discover 未作为本事项通过证据:已确认的 authenticated-extension __pycache__ exact-set 失败与 managed-load 长时项属于独立产品,本修复未修改或清理它们。
  • 正式 manifest 终检仍为 51598 bytes / 0E69AF2AF1C4B0014D2033A21F3986E283ECFD758EA652E7F2416006736C8D73 / 48 lines。Chrome、网络、下载、正式采集、F:\video、Cookie/session、扩展/HKCU 与转写动作均为 0。
  • 当前状态更新为 HOLD4_FOCUSED_REPAIR_COMPLETE_PENDING_LIMITED_REREVIEW;最终结论仍以原 task、原 dev.reviewer.project / inforev 限定复审为准。

8. HOLD/3 F2—F4 聚焦修复(覆盖第 7 节状态)

  • 第二次限定复审正式终态为 HOLD/3,MB-X 结果消息为 msg_20260813204949399_274b6660;F1 observation/items 已关闭,本节只修 F2—F4。
  • F2:schema 2 creator_uid 必须是与配置精确相等的 string;schema 1 数字 stable_id 仅接受 1—32 位 ASCII digits,33 位和全角数字均失败关闭。schema 1 冻结历史 UID 兼容口径保持不变。
  • F3:pending CreateNew 后、STARTED 前崩溃会从 durable pending 机械重建同一 run 的 exact STARTED slot,并返回同 run_id;既有 slot 只有 exact STARTED 或 exact planned TERMINAL 可接受,第三内容永不 replace。TERMINAL_RECORDED 重开会复算 planned schema、receipt、当前双 manifest identity 和 exact terminal slot bytes,再补 latest/cleanup。
  • F4:失败 claim 先把 exact quarantine intent、规范相对路径、archive/quarantine 目录 identity、bytes/hash/attempt 写入 pending,再执行 no-overwrite rename。Windows 使用 MoveFileExW(MOVEFILE_WRITE_THROUGH) 且不带 replace;rename 后 flush/readback 目录项。主 lock 已删除时 terminal cleanup 仍继续删除 exact quarantine/failed claims/owner marker,空目录崩溃点可重开完成并 flush 父目录。
  • 新增非真空反例覆盖 schema2 integer UID、schema1 超长/非 ASCII stable ID、pending→STARTED 崩溃同 run、STARTED/TERMINAL 第三 slot、tampered planned receipt、failed-claim intent 后 rename 前崩溃、no-overwrite target、目录 flush 与主锁先删后的 cleanup reopen。
  • 最终目标测试为 collector 13 项 + refresh 21 项,共 34/34 PASSpy_compile=PASS。正式 48 行 catalog 仍只读通过 48 events / 22 components / 16 saved / 5 video / 1 retryable
  • 正式 manifest 仍为 51598 bytes / 0E69AF2AF1C4B0014D2033A21F3986E283ECFD758EA652E7F2416006736C8D73 / 48 lines。Chrome、网络、下载、正式采集、F:\video、Cookie/session、扩展/HKCU 与转写动作均为 0。
  • 当前状态=HOLD3_F2_F4_REPAIR_COMPLETE_PENDING_LIMITED_REREVIEW

9. HOLD/1 F4 formal-lock durable-create 聚焦修复(覆盖第 8 节状态)

  • 原 reviewer 正式回执 msg_20260814002856995_85f04dcaHOLD/1;F2/F3 保持关闭,本轮只关闭 F4_NEW_FORMAL_CLAIM_CREATE_NOT_READBACK_OR_DIRECTORY_DURABLE
  • 新增单一 _durable_formal_lock_claim 门:所有 formal-lock CreateNew 均先完成文件 flush/fsync,再做 lexical lstat、精确 bytes/length/SHA-256 回读、父目录 fsync,并在持久化后再次精确回读;只有全部成功后才允许写入 HELD/NEW_LOCK_HELD
  • post-create 第三内容漂移、读取失败或父目录 fsync 失败均保留 PLANNED/CREATE_PLANNED;第三内容不覆盖。精确 lock 已创建但目录 fsync 失败时,同一 pending 可在重开后重新验证/持久化并晋升。
  • 新增公开反例覆盖 drift/readback/fsync 三类故障,并用真实子 Python 进程在 CreateNew 后父目录 fsync 前、以及 NEW_LOCK_HELD 后两个断点 kill;重开均沿 durable pending 恢复,正式 manifest 和第三内容保持不变。
  • 限定反例 2/2 PASS;目标全量 collector 13 + refresh 23=36/36 PASS;refresh 单文件 23/23 PASSpy_compile=PASS、CLI help exit 0、governance=OK/projects1/warnings0
  • 正式 manifest 冻结前像仍为 51598 bytes / 0E69AF2AF1C4B0014D2033A21F3986E283ECFD758EA652E7F2416006736C8D73 / 48 lines;Chrome/network/download/formal write/F:\video/Cookie/session/extension/HKCU/media/transcription 均为 0。
  • 当前状态:F4_DURABLE_CREATE_REPAIR_COMPLETE_PENDING_LIMITED_REREVIEW;最终结论以原 task、原 dev.reviewer.project/inforev 限定复审为准。

10. V005+V006 supported Chrome runtime 超时合同实现

  • F4 离线实现复审已于 msg_20260814015709581_78422206PASS/0。随后生产槽 018/019/020 连续投影为 REFRESH_FAILED_PAGE_UNREADABLE;这些槽与 evidence 保持不可变,未改判、覆盖或重交。
  • 只读诊断显示同一 complete/visible/content-bearing 页面上,supported evaluate/visible-DOM/screenshot 分别约 21343/21355/21389ms 后成功,故可复核问题是旧 15s/8s 合同低于共同控制路径延迟,不把业务 selector 或单个内部组件过度断言为唯一根因。
  • V005 设计首次复审 HOLD/1,消息=msg_20260814050003153_4b3b36b1;V006 精确拆分 PRE/POST dispatch error 后组合设计于 msg_20260814051716904_5ebc133fPASS/0
  • 新 runtime-v2 固定 120/35/45/15s 总体/action/observation/internal-settle 预算,只允许一次 supported reload/goto 和一次 source-controlled evaluate,retry=0;runtime contract bytes/SHA、pending/evidence schema3、实际 action/observation count 与 elapsed 墙钟机械绑定。
  • PRE_DISPATCH_ERROR 固定 0/0、零保存、unreadable;POST_DISPATCH_ERROR 固定 action count1,若可读新完整条目可保守保存但不得 coverage/no-new,可读空为 partial,读取失败为 unreadable。TIMEOUT 同样永不确认 no-new;CONFIRMED 才能结合旧 coverage 硬门产生 no-new。
  • 原 schema2 pending 仅保留历史恢复/终结能力,不可升级或触发 runtime-v2 动作。旧 timeout 配置字段在 begin 前 E_CONFIG,example 已改为四个 exact runtime-v2 常量。
  • 新增 runtime contract JSON、单 evaluate bounded-settle extractor 以及 8 项入口/矩阵测试;collector13+refresh31=44/44 PASSpy_compile=PASS、CLI help exit0。
  • 正式 manifest 仍为 51598 bytes / 0E69AF2AF1C4B0014D2033A21F3986E283ECFD758EA652E7F2416006736C8D73 / 48 lines。实现与测试期间 Chrome/reload/goto/network/download/formal write/Raw CDP/Cookie/session/F:\video/media/transcription=0
  • 当前状态=V005_V006_RUNTIME_REPAIR_COMPLETE_PENDING_LIMITED_IMPLEMENTATION_REVIEW;首次新 runtime smoke 必须在本实现复审 PASS 后由 requester/admin 另行调度。

11. runtime HOLD/5 权威纠偏与完整修复(覆盖第 10 节状态)

  • 当前唯一权威 runtime 实现审核终态是 msg_20260814065631653_4be06bb5 / HOLD/5,对应 DEV-AUDIT-PROJECT-INFO-BILI-DYNAMIC-REFRESH-COLLECTOR-V005-V006-RUNTIME-LIMITED-IMPLEMENTATION-REVIEW-20260814-001。旧消息 msg_20260814015709581_78422206 仅关闭 V004 formal-lock durability;误发撤回 msg_20260814080254352_57428c14 不撤销、不覆盖 runtime HOLD/5。
  • F1:新增 source-controlled bili_dynamic_refresh_controller.py。controller 独占 tab 选择、dispatch 前后状态、单调计数、HMAC capability attestation、CreateNew partial→file fsync→no-overwrite rename→parent fsync→readback;begin 不回显 capability,调用者手写/篡改 outcome 无法绑定成功终态。
  • F2:controller 向唯一 supported evaluate 传入 source-controlled extractor 与固定 15 秒调用表达式;deterministic adapter 生成 creator、cards、unparsed fingerprints、terminal marker、items 和 observation。真实 Node fixture 驱动 readable-new、empty、unparsed、identity 四态;受控 adapter 另覆盖 access blocked,均进入产品 evidence→CLI 链而非 Python 手写观察。
  • F3:总 deadline 同时约束 action、observation、evidence durable completion 与 binding。evidence 写后立即复算同一 monotonic deadline;跨线时只删除本次 exact owned payload、fsync 父目录并保持 pending=AWAITING_EVIDENCEbind_controller_evidence 另以 pending wall deadline 拒绝迟到绑定;CLI deadline+ε 不保存、不推进 manifest。
  • F4:schema2 pending 在 begin、commit、controller 三入口均是 recovery-only;AWAITING_EVIDENCE × slot present/missing × deadline before/after 矩阵不会返回 BROWSER_REFRESH_REQUIRED,controller 在任何 browser adapter 调用前拒绝。
  • F5:final URL、UID、name、profile 任一不匹配,在 CONFIRMED、TIMEOUT、POST_DISPATCH_ERROR 三种已派发结果下均持久化为 REFRESH_BLOCKED_AUTH_OR_ACCESS/E_CREATOR_MISMATCH/exit3;terminal slot/latest 完成、pending 清理、no-new=false、正式 manifest 不变。
  • reviewer 聚焦反例=6/6 PASS / 7.427s,其中包含 F2 五态链、F4 12 组合和 F5 4×3 矩阵;refresh 全量=37/37 PASS / 15.384s;collector+refresh=50/50 PASS / 20.114spy_compile=PASS、CLI help exit0、strict UTF-8/no BOM/trailing whitespace=PASS、secret literal scan=0、governance=OK/projects1/warnings0
  • project discover 完整执行=Ran 191 tests in 172.129s / failures=46 / skipped=6。本任务 collector+refresh 零失败;7 个 failure records 位于独立 authenticated-extension(既有 __pycache__ exact-source 漂移),39 个位于独立 managed-load(fixture 在 E_BUILD_CONTRACT 审计/批准门失败)。本事项不删除缓存、不改这些产品,也不把整库宣称为全绿。
  • 正式 manifest 测试前后严格保持 51598 bytes / 48 lines / 0E69AF2AF1C4B0014D2033A21F3986E283ECFD758EA652E7F2416006736C8D73。本轮 Chrome、network、refresh-begin 正式调用、formal write、Cookie/session、Raw CDP、download、media、F:\video、transcription 均为 0。
  • 当前状态=RUNTIME_HOLD5_F1_F5_REPAIR_COMPLETE_PENDING_ORIGINAL_REVIEWER;只接受原 task、原 dev.reviewer.project/inforev 的新实现复审终态。