创建人员: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
前序离线实现最终复审 PASS/0:
msg_20260814015709581_78422206;DEV-AUDIT-PROJECT-INFO-BILI-DYNAMIC-REFRESH-COLLECTOR-HOLD1-F4-DURABLE-CREATE-REREVIEW-20260814-001;495824/95ACC6236CB9F787137FC64F0DACBD796972258BB16E492B84928AD7565ED783;bili_dynamic_refresh.py|109597|5C813E3023319A4DEB38AC7213135D52F7DB3E137D9306F642A94941AF8011BD;test_bili_dynamic_refresh.py|53314|5895C8409DF753C67A3E1429FF50048F7BE7850CABC63B13EBA42A55CBE85E10;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 与崩溃恢复合同。
诊断入口: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=complete、visibilityState=visible、正文可见文本长度 19,890,页面 console error/warn=0。三条独立读面都在约 21.3 秒后成功,并伴随控制运行时自身的有界遥测超时信号;未保存 endpoint、key、payload 或 raw error。
因此可复核根因是:**冻结的 page-ready=15s、DOM-read=8s 低于当前受支持 Chrome 控制路径的共同调用延迟**。业务 DOM/selector 不是三条读面共同失败的原因。内部遥测实现是否为唯一原因不作过度断言。
每一小时 run 只允许以下控制序列:
refresh-begin 创建同一 run/pending/slot;openTabs() 精确选择 https://space.bilibili.com/1420210197/dynamic;现有 exact tab 只 reload() 一次,没有 exact tab 才 goto(exact_url) 一次;二者合计始终为 1;playwright.evaluate observation;该调用在一个页面作用域内机械取得 ready/url/title/creator、可见 cards、unparsed nodes、终止标记和现有 extractor 所需字段;waitForLoadState + domSnapshot + evaluate,也不以 screenshot、visible DOM、坐标或 Raw CDP 作降级;.partial→fsync→rename 写 exact evidence;CLI 仍是唯一验证与持久化入口。这不是页面/API 绕过,不新增 Chrome 权限,不读取 Cookie、token、localStorage、profile、header、响应体或签名 URL。
新增 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=30、page_ready_timeout_seconds=15、dom_read_timeout_seconds=8 配置语义:
refresh 配置必须且只允许新增 overall_deadline_seconds=120、refresh_action_timeout_seconds=35、observation_timeout_seconds=45、page_internal_settle_timeout_seconds=15;这些值是冻结常量,不是可调范围;refresh-begin 任何 pending/lock/business 写前以 E_CONFIG 失败关闭;refresh-begin 成功 stdout 必须回显 runtime contract id/SHA-256 与四个冻结预算,便于 controller 在浏览器动作前核对;{code,overall_deadline_seconds,refresh_action_timeout_seconds,observation_timeout_seconds};不保留语义已过期的 page-ready/DOM-read 字段,也不保存 raw browser error。实现只扩展现有 RefreshConfig 和安全诊断 schema,不创建服务、浏览器 daemon 或新调度器。
受支持 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。
未来 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
}
refresh_count 与 observation_count 都只能为 1,且必须与 pending schema 3 中的动作预算一致;E_EVIDENCE_SCHEMA,两份 manifests 不变。设计 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;不得修改正式 manifest,不得新增浏览器扩展权限、Raw CDP、坐标控制、Cookie/session、本地 profile、网络 API、下载、媒体、F:\video、formal ana-data 或转写能力。
cookies 标识符不误杀,Cookie/session 值读取仍为0;不要求设计/实现复审进行真实 reload、goto、网络或正式写入。若后续实现 PASS,首次新 runtime smoke 必须由 requester/admin 单独调度,仅作用于新小时槽,且最多一次 action、零重试。
51598/0E69AF2AF1C4B0014D2033A21F3986E283ECFD758EA652E7F2416006736C8D73/48;dev.reviewer.project/inforev 对 V005 聚焦设计复审。