edit | blame | history | raw

CODE-DESIGN-PROJECT-INFO-BILI-DYNAMIC-REFRESH-COLLECTOR-V005

创建人员:dev.developer.project.secondary / infodev-2
事项:DEV-PROJECT-INFO-BILI-DYNAMIC-REFRESH-COLLECTOR-20260813-001
需求:REQ-BILI-DYNAMIC-COLLECTOR-20260804-001
性质:既有重型事项的受控 runtime 超时合同增量设计
前序组合方案:V001+V002+V003+V004
状态:PENDING_ORIGINAL_REVIEWER_RUNTIME_DELTA_REVIEW / IMPLEMENTATION_FROZEN

1. 变更来源与冻结基线

前序离线实现最终复审 PASS/0

  • result message=msg_20260814015709581_78422206
  • audit=DEV-AUDIT-PROJECT-INFO-BILI-DYNAMIC-REFRESH-COLLECTOR-HOLD1-F4-DURABLE-CREATE-REREVIEW-20260814-001
  • audit snapshot=495824/95ACC6236CB9F787137FC64F0DACBD796972258BB16E492B84928AD7565ED783
  • product=bili_dynamic_refresh.py|109597|5C813E3023319A4DEB38AC7213135D52F7DB3E137D9306F642A94941AF8011BD
  • tests=test_bili_dynamic_refresh.py|53314|5895C8409DF753C67A3E1429FF50048F7BE7850CABC63B13EBA42A55CBE85E10
  • 正式 manifest=51598/0E69AF2AF1C4B0014D2033A21F3986E283ECFD758EA652E7F2416006736C8D73/48 lines

生产运行槽 018/019/020 连续三小时均在 exact 目标页的一次受支持 reload 或 direct goto 后、可见 DOM/evaluate 读取完成前超时,正确形成 REFRESH_FAILED_PAGE_UNREADABLE,正式 manifest 不变。这三个 terminal slot 是不可变历史:不得改判、覆盖、重交旧 evidence 或把当前页面内容追溯写入旧 run。

本设计不重开 UID、五终态、coverage/no-new、mixed-history catalog、双 manifest 事务、slot/latest、formal lock 与崩溃恢复合同。

2. 只读诊断事实

诊断入口:dev/tmp/bili-dynamic-refresh-collector-20260813-001/runtime-read-timeout-diagnosis-20260814.json

本轮没有 reload、goto 或任何页面写动作。使用现有 Chrome 受支持控制面精确认领目标标签后:

受支持只读面 wall 结果
playwright.evaluate 最小 document 状态 21,343 ms PASS
dom_cua.get_visible_dom 21,355 ms PASS
viewport screenshot 21,389 ms PASS

页面返回 document.readyState=completevisibilityState=visible、正文可见文本长度 19,890,页面 console error/warn=0。三条独立读面都在约 21.3 秒后成功,并伴随控制运行时自身的有界遥测超时信号;未保存 endpoint、key、payload 或 raw error。

因此可复核根因是:**冻结的 page-ready=15s、DOM-read=8s 低于当前受支持 Chrome 控制路径的共同调用延迟**。业务 DOM/selector 不是三条读面共同失败的原因。内部遥测实现是否为唯一原因不作过度断言。

3. 最小受支持运行修复

3.1 单 action、单 observation

每一小时 run 只允许以下控制序列:

  1. refresh-begin 创建同一 run/pending/slot;
  2. 通过 Chrome openTabs() 精确选择 https://space.bilibili.com/1420210197/dynamic;现有 exact tab 只 reload() 一次,没有 exact tab 才 goto(exact_url) 一次;二者合计始终为 1;
  3. action 返回或达到其有界超时后,**不得再次 reload/goto**;
  4. 同一标签只调用一次 source-controlled playwright.evaluate observation;该调用在一个页面作用域内机械取得 ready/url/title/creator、可见 cards、unparsed nodes、终止标记和现有 extractor 所需字段;
  5. 不再串行调用 waitForLoadState + domSnapshot + evaluate,也不以 screenshot、visible DOM、坐标或 Raw CDP 作降级;
  6. controller 只按既有 CreateNew .partial→fsync→rename 写 exact evidence;CLI 仍是唯一验证与持久化入口。

这不是页面/API 绕过,不新增 Chrome 权限,不读取 Cookie、token、localStorage、profile、header、响应体或签名 URL。

3.2 固定预算

新增 source-controlled runtime contract,冻结:

contract_id=bili-supported-chrome-visible-runtime-v2
overall_deadline_seconds=120
refresh_action_timeout_seconds=35
observation_timeout_seconds=45
page_internal_settle_timeout_seconds=15
max_refresh_count=1
max_observation_count=1

refresh-begin 的 pending deadline 固定为 started+120s。35s action 与 45s observation 都受同一单调总 deadline 约束;内部 settle 仅发生在同一个 evaluate 内,不产生第二个浏览器控制调用。任一阶段不得无界等待、重试或在总 deadline 后写 evidence。

配置与 evidence 必须同时绑定 runtime contract id/bytes/SHA-256。V005 对未来 runtime-v2 run 精确替代 V001/V002 的 timeout_seconds=30page_ready_timeout_seconds=15dom_read_timeout_seconds=8 配置语义:

  • refresh 配置必须且只允许新增 overall_deadline_seconds=120refresh_action_timeout_seconds=35observation_timeout_seconds=45page_internal_settle_timeout_seconds=15;这些值是冻结常量,不是可调范围;
  • 新配置中出现旧三个 timeout 字段,或新字段缺失/非整数/不等于冻结值,均在 refresh-begin 任何 pending/lock/business 写前以 E_CONFIG 失败关闭;
  • refresh-begin 成功 stdout 必须回显 runtime contract id/SHA-256 与四个冻结预算,便于 controller 在浏览器动作前核对;
  • 新 begin 创建 pending schema 3 并绑定 runtime contract id/SHA-256、四预算、action/observation 上限和单调 deadline;已有 schema 2 pending 只允许按其原合同恢复/终结,不得升级、换绑或触发 runtime-v2 浏览器动作;
  • 新 run 的安全诊断 exact keys 替换为 {code,overall_deadline_seconds,refresh_action_timeout_seconds,observation_timeout_seconds};不保留语义已过期的 page-ready/DOM-read 字段,也不保存 raw browser error。

实现只扩展现有 RefreshConfig 和安全诊断 schema,不创建服务、浏览器 daemon 或新调度器。

3.3 action timeout 后的保守投影

受支持 action 调用超时可能已经触发页面刷新,因此绝不重试。之后仍允许唯一一次 observation,用于区分“页面实物可读”与“控制面完全不可读”,但不得伪称 action 已确认完成:

action observation 允许终态
confirmed exact READABLE + 新完整条目 NEW_ITEMS_SAVED
confirmed exact READABLE + coverage complete + 无新增 REFRESH_CONFIRMED_NO_NEW
timeout exact READABLE + 新完整条目 可保存新条目,但 coverage/no-new token 必为 false;状态仍按已有新条目合同
timeout exact READABLE + 无新增/coverage PARTIAL_DISCOVERY_UNCONFIRMED;绝不 no-new
任意 observation timeout/error REFRESH_FAILED_PAGE_UNREADABLE
任意 exact login/captcha/access/identity mismatch REFRESH_BLOCKED_AUTH_OR_ACCESS

新增 refresh_action_outcome=CONFIRMED|TIMEOUT|ERROR,以及 bounded elapsed buckets;不得写 raw browser error。REFRESH_CONFIRMED_NO_NEW 新增硬门 refresh_action_outcome=CONFIRMED

4. 证据 schema 增量

未来 runtime-v2 的 browser evidence schema 固定升级为 3;schema 2 仅可用于与旧 pending/terminal identity 精确一致的历史恢复,不可提交到 schema 3 pending。在既有 evidence 根增加 exact runtime object:

runtime_contract={contract_id,contract_bytes,contract_sha256}
runtime_observation={
  refresh_action_outcome,
  refresh_action_elapsed_ms,
  observation_outcome,
  observation_elapsed_ms,
  refresh_count,
  observation_count
}
  • elapsed 必须为 0..对应预算的整数;timeout 可等于预算上界;
  • refresh_countobservation_count 都只能为 1,且必须与 pending schema 3 中的动作预算一致;
  • source-controlled observation 输出不接受由调用者直接声称的 coverage totals;CLI 继续从 observations/cards/unparsed/marker 重算;
  • 旧 V1 evidence 仅作为已经落定 slot 的历史证据,不允许提交给新 run;新 run 只接受 runtime-v2;
  • 任何 contract/hash/elapsed/action count/timeout drift 均 E_EVIDENCE_SCHEMA,两份 manifests 不变。

5. 实现边界

设计 PASS 后才允许修改:

  • dev/project-dev/bili_dynamic_collector.py:runtime contract config/上限;
  • dev/project-dev/bili_dynamic_refresh.py:runtime-v2 evidence/schema/no-new action-confirmed 硬门;
  • dev/project-dev/bili_dynamic_page_extract.js:单次 evaluate 的 bounded ready+visible extraction 包装,不做网络或存储访问;
  • 新增 dev/project-dev/bili_dynamic_browser_runtime_contract.json
  • 对应 example、fixtures、tests、工具说明、实现证据和必要 append-only 执行账。

不得修改正式 manifest,不得新增浏览器扩展权限、Raw CDP、坐标控制、Cookie/session、本地 profile、网络 API、下载、媒体、F:\video、formal ana-data 或转写能力。

6. 离线验收合同

  1. 21.5s action + 21.5s observation 在 35/45/120 合同内成功,控制调用数 exact 1+1;
  2. action=35s timeout 后 observation exact 一次,refresh count 仍为1;无新增必须 partial,no-new token=0;
  3. observation=45s timeout 为 unreadable,formal/state business manifests 不变;
  4. overall 120s 截止后无调用、无 evidence 写入;
  5. action timeout + 可见新完整 item 可保存,但不得产生 no-new/coverage complete;
  6. confirmed action + exact complete no-new 仍必须通过原 V002 observation/coverage 全硬门;
  7. runtime contract/hash/elapsed/count/action-outcome 任一漂移 fail closed;
  8. 018/019/020 旧 slot 原 bytes 不变且不能作为新 run evidence;
  9. synthetic unique secret sentinel 不进入 evidence/log/stdout;合法 cookies 标识符不误杀,Cookie/session 值读取仍为0;
  10. 原 36 项目标测试、formal 48/22/16/5/1 只读验收和 F2/F3/F4 合同不回退。

不要求设计/实现复审进行真实 reload、goto、网络或正式写入。若后续实现 PASS,首次新 runtime smoke 必须由 requester/admin 单独调度,仅作用于新小时槽,且最多一次 action、零重试。

7. 当前冻结状态

  • product code/test/fixture modification=0(相对于 F4 PASS snapshot);
  • 本轮 Chrome reload/goto=0;只读页面诊断已完成并释放标签;
  • network/download/formal write/Cookie/session/Raw CDP/F:\video/media/transcription=0;
  • 正式 manifest 仍为 51598/0E69AF2AF1C4B0014D2033A21F3986E283ECFD758EA652E7F2416006736C8D73/48
  • 实现保持冻结,等待原 dev.reviewer.project/inforev 对 V005 聚焦设计复审。