# Bilibili 已登录会话扩展零手工标准加载设计 V003 ## 1. 事项、角色与门禁 - 项目:`project-info` - 上游需求:`REQ-BILI-DYNAMIC-COLLECTOR-20260804-001` - 原开发事项:`DEV-PROJECT-INFO-BILI-AUTHENTICATED-SESSION-DOWNLOAD-20260805-001` - 本次续派消息:`msg_20260810005439384_edc9a9f1` - 管理授权:`HANDOFF-INFOADMIN-INFODEV2-BILI-AUTHENTICATED-EXTENSION-ZERO-MANUAL-STANDARD-LOAD-ASSIGN-20260810-001` - 唯一 owner:`dev.developer.project.secondary / infodev-2` - 唯一审核员:`dev.reviewer.project / inforev`,沿原事项审核链 - 精确扩展 ID:`oidmclckpdmpabbfedplkbdplmfcenbb` - 冻结 Native Host:build-005,已安装且静态健康检查通过 本增量涉及扩展发布、Chrome 管理策略、当前用户注册表写入和卸载恢复,属于重型高失败成本变更。按照编码规范,V003 必须先取得独立方案审核 `PASS/0`,才允许创建部署代码、测试或离线候选包。 方案和实现审核前的真实动作固定为:扩展发布 `0`、安装策略写入 `0`、Chrome 启动/控制 `0`、Cookie/session 读取 `0`、网络 `0`、下载 `0`、真实媒体与 `F:\video` 写入 `0`、正式 `ana-data` 写入 `0`、转写 `0`。 ## 2. 问题与最小目标 当前 build-005 Native Host 已按 exact bytes 安装,但 Chrome 控制策略禁止 Codex 访问 `chrome://extensions`,也不能检查工具栏扩展列表。继续依赖开发者模式“加载已解压的扩展”既需要手工操作,也无法形成标准签名、策略状态和自动卸载证据。 本增量只解决一个问题: 1. 把冻结的五个浏览器扩展文件形成一个可提交 Chrome Web Store 的确定性 ZIP 和离线 receipt; 2. 外部受权发布完成后,只接受 Web Store 返回的精确同 ID 版本和 reviewer-owned release approval; 3. 通过 Chrome 支持的当前用户 `ExtensionInstallForcelist` 策略,强制安装 Web Store 签名扩展; 4. 以一次受控脚本写入实现后续零重复手工加载,并提供精确、可回滚、可审计的策略移除; 5. 不读取 Chrome profile,不访问受限 Chrome URL,不执行浏览器自动化。 “零手工”指最终用户不进入 `chrome://extensions`、不点击开发者模式或“加载已解压的扩展”。Web Store 发布和一次受控策略安装是独立的治理动作,不属于用户重复手工加载。 ## 3. 支持机制选择 ### 3.1 唯一支持路径 本版本只支持: ```text 冻结扩展源码 -> 确定性 Web Store 上传 ZIP + schema 1 build receipt -> 受权发布者提交 Chrome Web Store -> reviewer 核对 Web Store 返回的 exact extension ID/version,创建树外 release approval -> 受控 installer 写 HKCU ExtensionInstallForcelist 单一值 -> Chrome 在后续获授权的正常启动/策略刷新中从 Web Store 官方更新 URL 安装 ``` 固定官方更新 URL: `https://clients2.google.com/service/update2/crx` 策略位置: `HKCU\Software\Policies\Google\Chrome\ExtensionInstallForcelist` 策略值正文: `oidmclckpdmpabbfedplkbdplmfcenbb;https://clients2.google.com/service/update2/crx` 策略值名称不是在代码中猜测。受控安装前由管理员冻结一个当前未使用的十进制值名,写入 install approval;installer 只消费该 exact 值名,绝不覆盖或重排其他扩展策略。 ### 3.2 明确排除 - 不访问或绕过 `chrome://extensions`、`chrome://policy` 或其他受限 URL。 - 不使用坐标点击、Raw CDP、remote debugging、Chrome profile/Preferences/Secure Preferences 注入。 - 不使用 `--load-extension`、开发者模式、unpacked 自动加载、快捷方式参数或计划任务启动浏览器。 - 不自托管 CRX/update.xml,不新增 localhost/HTTP/HTTPS 服务、证书、端口或后台守护进程。 - 不使用非 Web Store CRX、第三方扩展商店、第三方 VideoTextHost 或未文档化 policy workaround。 - 不生成、读取、保存扩展私钥;项目仓库、日志和 handoff 中不得出现 `.pem`、私钥或 Web Store 账号凭据。 - 不修改冻结的 Native Host build-005、已安装 Host、原扩展运行时协议、Cookie 内存边界或下载链路。 ### 3.3 外部事实门禁 离线实现不能证明 Web Store 已接受发布,也不能证明 Chrome 已加载扩展。因此: 1. 源码/实现 PASS 只证明“发布包和策略工具符合合同”,不等于扩展已发布或已加载。 2. Web Store 发布必须是后续单独授权的外部动作;返回 ID 不是 exact ID 时立即停止,禁止修改 Native Host allowed origin 迁就新 ID。 3. 发布后必须由原 reviewer 创建位于源码、构建和安装树之外的 release approval。 4. 实际策略安装必须再由管理员调度;本次实现回合不得消费该动作。 5. 默认 profile 是否启用只能在策略安装后、由获授权运行方在正常 Chrome 运行阶段验证;离线测试不得伪造 enabled 结论。 ## 4. 文件与模块边界 方案 PASS 后仅新增独立目录,不修改冻结的 `bili_authenticated_extension/` 17 文件树: ```text dev/project-dev/bili_authenticated_extension_managed_load/ managed-load-contract.json build_webstore_upload.ps1 install_managed_extension_policy.ps1 README.md dev/project-dev/test/bili_authenticated_extension_managed_load/ test_managed_load.py ``` 开发文档: - 本 V003; - `dev-doc/project-doc/B站已登录会话完整视频扩展入口.md` 追加标准加载章节; - 一份离线实现与验证证据页; - 根级开发总纲、计划、执行日志和 private worklog 只做 append-only 回写。 禁止修改或重新构建: - `dev/project-dev/bili_authenticated_extension/` 全部17个批准文件; - build-005 EXE、schema 2 receipt、source/install approvals 和已安装三文件; - `dev/project-dev/bili_video_download_bridge.py` 及其测试; - Chrome profile、扩展目录、Native Host HKCU 和正式媒体目录。 ## 5. 单一机器合同 `managed-load-contract.json` 是 builder 与 installer 共同读取的唯一 source-controlled 合同,schema 固定为1,至少冻结: - `task_id`、`target`、`extension_id`、`extension_version`、`extension_version_name`; - `webstore_update_url`; - `policy_key` 与策略正文; - 冻结源 manifest 的 bytes/SHA-256; - 五个扩展 payload 相对路径、bytes/SHA-256; - manifest public key DER SHA-256 与由其派生的 exact Chrome extension ID; - Native Host name、allowed origin、build-005 EXE bytes/SHA-256、安装 manifest bytes/SHA-256; - package receipt、release approval、install receipt 和 rollback receipt 的 exact schema/key set; - 安装策略值名的格式 `[1-9][0-9]{0,3}`,但不预占具体值。 五个 payload 固定为: 1. `manifest.json` 2. `background.js` 3. `sidepanel.html` 4. `sidepanel.css` 5. `sidepanel.js` builder 在任何输出前必须递归验证原冻结源码树(excluding source manifest)仍是 `17/17 exact`、无额外/缺失/哈希漂移/reparse;然后只投影上述五文件进入 ZIP。Python、PowerShell、wheel、配置、receipt、缓存和其他文件不得进入扩展包。 ## 6. Web Store 上传包 `build_webstore_upload.ps1` 只有两种公开模式: - 默认/`-ValidateOnly`:只验证源码、合同和外部 source approval,输出 `VALIDATION_PASS_ONLY`; - `-Build`:向一个不存在的输出目录写唯一 ZIP 与 schema 1 build receipt。 ZIP 规则: - 根目录正好五个文件,使用 POSIX basename,不含目录、绝对路径、`..` 或重复项; - 条目按路径 ASCII 排序; - 固定 ZIP 时间戳和文件属性; - 禁止 NTFS reparse、ADS、隐藏附加文件或密码; - ZIP 创建后重新打开,复算 entry set、uncompressed bytes、逐项 SHA-256 和 manifest ID; - receipt 最后写入,绑定 contract、原 source manifest/source approval、ZIP bytes/SHA-256、五项 entry 摘要和 build start/finish; - 输出目录只允许 `project-info-bili-auth-ingress-webstore.zip` 与 `webstore-upload-build-receipt.json`。 builder 不调用 Chrome、不签名、不上传、不联网,也不接受 Web Store 凭据。开发测试只在 `TemporaryDirectory` 或 `dev/tmp` 生成候选。 ## 7. 发布回执和树外信任锚 实际策略安装必须同时取得两份树外、不可由 developer 自批的文件: ### 7.1 Web Store release approval 由原 reviewer 在发布证据核对后创建,schema 1 exact keys: - `schema=1` - `scope=install-exact-webstore-extension` - `approved_by_role=dev.reviewer.project` - `extension_id`、`extension_version`、`webstore_update_url` - source contract bytes/SHA-256 - upload build receipt bytes/SHA-256 - Web Store 返回的非秘密 release evidence bytes/SHA-256 - `approved_at` release evidence 不得含账号、邮箱、Cookie、token、授权 header 或后台页面正文;只允许 item ID、版本、公开状态、时间和不可变哈希。 ### 7.2 install approval 由 project.admin 在只读环境 preflight 后创建,schema 1 exact keys: - `scope=install-exact-managed-extension-policy` - release approval bytes/SHA-256 - 当前用户 policy key、选定的空闲 policy value name、策略正文 - 安装 receipt 根的绝对本地路径 - 已安装 Native Host manifest 路径及 exact bytes/SHA-256 - 安装前像摘要:目标值 absent;是否新建 policy key;其他 value names 的排序哈希 - `approved_at` installer 必须在读取 Web Store build payload、创建目录或触碰 HKCU 前验证两份树外 approval;任一 bytes/hash/path/schema/role/scope 漂移即 fail closed。 ## 8. 策略安装状态机 `install_managed_extension_policy.ps1` 公开模式: 1. 默认/`-ValidateOnly` 2. `-Install` 3. `-HealthCheck` 4. `-Rollback` 测试专用 file-registry seam 必须是隐藏参数;生产参数不能选择任意 policy root、host name、extension ID、update URL 或禁用 gate。 ### 8.1 共同 lexical/preflight - 所有文件先按 lexical parent chain `lstat`/reparse 检查,再解析最终绝对路径;网络路径、相对路径、ADS、设备路径和软链接/junction 均拒绝。 - source contract、release/install approvals、Native Host manifest/EXE、receipt 根必须位于各自批准边界;禁止源码树内自签 approval。 - Native Host manifest 必须 exact name=`com.project_info.bili_auth_ingress`、type=`stdio`、单 origin=`chrome-extension://oidmclckpdmpabbfedplkbdplmfcenbb/`、path 指向 exact build-005 EXE。 - policy key 可含其他数字值,但选定 value name 必须 absent;现有其他值名和数据排序哈希必须与 install approval 前像一致。 - 不读取 Chrome profile、进程、页面、Cookie 或 extension runtime state。 ### 8.2 ValidateOnly 执行全部共同门禁后输出单行 canonical JSON: `{"result":"VALIDATION_PASS_ONLY",...}` receipt root、HKCU、Chrome 和任何正式路径副作用必须为0。 ### 8.3 Install 逐步 ownership: ```text preflight -> CreateNew receipt root -> CreateNew install-receipt.pending.json(含前像与 exact bindings) -> 写入选定 HKCU value(禁止覆盖) -> 回读 value name/type/data 与所有其他值前像 -> 原子 rename pending -> managed-extension-install-receipt.json -> SUCCESS ``` 从 receipt root 创建到最终 receipt rename 的整个边界捕获 `BaseException`。任一步失败:只删除本次创建的 policy value;仅当 policy key 由本次创建且仍为空时删除该 key;删除本次 receipt root。原有其他 values 不得修改。rollback 二次异常保存在外部失败证据,不覆盖原异常。 ### 8.4 HealthCheck 只读复算 contract、approvals、Native Host、install receipt、policy exact value 和其他 values 前像;返回 `HEALTH_PASS` 或固定错误码。它不启动 Chrome,也不声称扩展 enabled。 ### 8.5 Rollback Rollback 只允许在 install receipt 与当前 policy exact 匹配时执行: ```text preflight exact active state -> CreateNew rollback-receipt.pending.json -> 删除本次 policy value(不删其他 values) -> 回读确认目标 absent、其他 values 原样 -> rename pending -> managed-extension-rollback-receipt.json -> ROLLBACK_COMPLETE_POLICY_REMOVED ``` 若删除后 receipt 持久化失败,优先恢复 exact policy value,再清理 pending,并保留双错误证据。成功 rollback 保留 install/rollback 两份 receipt 作为审计历史;不删除 Chrome profile 文件。Chrome 实际卸载/禁用只在后续获授权的正常策略刷新中验证,不在离线脚本中虚报。 ## 9. CLI 终态和错误码 stdout 只输出单行 canonical JSON,stderr 只允许固定无秘密错误码。主要终态: - `VALIDATION_PASS_ONLY / exit 0` - `INSTALL_COMPLETE / exit 0` - `HEALTH_PASS / exit 0` - `ROLLBACK_COMPLETE_POLICY_REMOVED / exit 0` - `SAFETY_STOP / exit 3` - `FAILED_ROLLED_BACK / exit 4` - 非普通 `KeyboardInterrupt/SystemExit` 保留原类型,但必须先完成同一回滚和外部失败证据。 主要错误码:`E_SOURCE_DRIFT`、`E_APPROVAL`、`E_RELEASE_ID`、`E_PATH`、`E_REPARSE`、`E_NATIVE_HOST_IDENTITY`、`E_POLICY_PREIMAGE`、`E_POLICY_CONFLICT`、`E_RECEIPT`、`E_ROLLBACK`。错误响应不得回显注册表其他 value 数据、个人路径之外的环境信息、账号或第三方正文。 ## 10. 秘密与浏览器边界 - 源码、合同、ZIP、receipt、stdout/stderr、测试和证据递归拒绝 `cookie/token/password/authorization/signed_url/client_secret/private_key` 等字段名。 - 不读取或枚举 Chrome profile、扩展存储、Local State、Preferences、Cookies、History、登录账号或浏览器进程命令行。 - 不启动/终止 Chrome,不调用 WebDriver/CDP,不访问 `chrome://`,不点击 toolbar。 - Web Store 发布凭据只由外部获授权发布者持有,不传给 developer 或工具。 - 策略安装只声明 extension ID + 官方 update URL;Cookie 和下载链继续由冻结运行时在未来用户可见动作中按 V001+V002 处理。 ## 11. 离线验收矩阵 ### 11.1 builder - 正确 17 文件 source + 五文件 payload -> `ValidateOnly` PASS;build 后 ZIP exact 5、receipt exact。 - 运行两次到不同临时目录,ZIP bytes/SHA 一致。 - manifest public key 独立派生 exact ID;key、ID、version 任一漂移失败。 - 源码缺失/额外/哈希漂移/reparse,payload path escape/重复/未知文件,source approval 位于源码树内或哈希漂移,均在输出创建前失败。 - ZIP 不含 Python、PowerShell、wheel、receipt、配置、缓存、秘密字段或绝对路径。 ### 11.2 installer ValidateOnly/Install/Health - exact release/install approvals、Native Host、空目标 value -> ValidateOnly PASS,file registry/receipt root 字节不变。 - Install 只新增一个 exact value 和一份 exact receipt;其他 values 的 names/types/data 逐字不变。 - HealthCheck 对 exact state PASS;target value、value type、update URL、receipt、host origin/EXE/hash 任一漂移失败。 - 错 ID/version/update URL、旧/自签/树内 approval、缺 release evidence、相对/网络/reparse 路径、policy preimage 漂移、目标已占用均在业务写前失败。 ### 11.3 BaseException 与 rollback - receipt root、pending write/flush/fsync、policy key/value、回读、final rename 每点注入 ordinary exception、`KeyboardInterrupt`、`SystemExit`;失败后目标 value absent、其他 values 与 receipt root 恢复前像。 - Rollback 的 pending、policy delete、回读、final rename 各点注入;失败时 active policy 恢复 exact,其他 values 不变。 - 成功 rollback 只移除本值,保留其他 values 和双 receipt;重复 rollback 返回 `SAFETY_STOP/E_POLICY_PREIMAGE`,不删除额外对象。 ### 11.4 静态禁区和回归 - 产品代码不得出现 `chrome://extensions`、`--load-extension`、remote-debugging/CDP、profile Preferences 写入、自托管 server、第三方 Host 依赖或 Cookie/token 字段。 - 测试只用 `TemporaryDirectory`、file-registry seam、合成 hashes 和非秘密 JSON;真实 HKCU/Chrome/network/media=0。 - 冻结原扩展测试、bridge 测试和 project regression 均通过;原17文件和 build-005 installed hashes保持不变。 ## 12. 性能与可重跑 本工具只处理五个小文件和一个注册表值,无专项性能风险。离线 builder/installer 每次目标 `<5s`(不含完整 project regression)。 - builder 输出目录必须不存在;不覆盖,不在失败后复用。 - Install 只允许 absent target value;成功后重跑 `-Install` 安全停止,使用 `-HealthCheck`。 - Rollback 只允许 exact active state;成功后不得再次删除。 - 任何 source/approval/release/native-host/policy preimage 漂移都要求重新 review/approval,不自动重试或 fallback。 ## 13. 审核与后续阶段 本 V003 先提交原 `dev.reviewer.project / inforev` 做方案审核。只有 `PASS/0` 后才能实现第4节文件、运行纯离线测试和形成一次实现证据包。 实现审核 PASS 仍不授权 Web Store 发布、policy 安装、Chrome 启动或真实下载。后续最少四个独立事实门: 1. 受控 Web Store 发布授权与 exact ID/version 事实; 2. reviewer-owned release approval; 3. project.admin 的 exact policy install approval; 4. 安装后获授权的 Chrome 正常运行检查,证明 default profile exact ID enabled、Native Host origin一致。 第4门通过前,既有 `BV1HA3o6oEJJ` runtime 授权继续冻结。任何门失败都不得回退到开发者模式、命令行加载、profile 注入或第三方扩展。