DEV-PROJECT-INFO-BILI-AUTHENTICATED-SESSION-DOWNLOAD-20260805-001REQ-BILI-DYNAMIC-COLLECTOR-20260804-001dev.developer.project.secondary / infodev-2dev.reviewer.project / inforevCODE-DESIGN-PROJECT-INFO-BILI-AUTHENTICATED-EXTENSION-MANAGED-LOAD-V003.md=17715/1EC7F6D8D6CD6AA9BEE5F5696D1CB578514CA3C61ADA838777093C8EFEF2C2F1HOLD/6,审计 ID=DEV-AUDIT-PROJECT-INFO-BILI-AUTHENTICATED-EXTENSION-MANAGED-LOAD-V003-DESIGN-20260810-001本文件只闭合 F1—F6。V003 未被本文件替换的合同继续有效;发生文字冲突时,本 V004 优先。总体路径继续唯一为 Chrome Web Store 签名发布物加 Windows ExtensionInstallForcelist,不回退到 chrome://extensions、unpacked、命令行加载、CDP、profile 注入、自托管更新服务或第三方 Host。
本修订仍是设计阶段。bili_authenticated_extension_managed_load/ 代码、测试、图标文件和候选 ZIP 均不得在 V004 PASS/0 前创建。Web Store 发布、policy/HKCU、Chrome、Cookie/session、网络、下载、真实媒体、F:\video、formal ana-data 和转写保持为0。
原扩展源码树继续固定为 17/17 exact,source manifest 固定为:
dev/project-dev/bili_authenticated_extension/source-artifact-manifest.json|3681|333BA59512C5F68B35C00B8C9738C8B26FB78285F05851F9F35BA3FC44819535
原 manifest.json 与四个运行时文件不得改写。Web Store 包中的 manifest.json 由 source-controlled managed-load-contract.json 内的 packaging overlay 精确投影;其余四个运行时文件仍逐字取自冻结源码。manifest overlay 只允许相对原对象追加以下字段,其他 key、value、顺序和语义全部逐项相等:
"icons": {
"16": "icons/icon16.png",
"32": "icons/icon32.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
}
overlay manifest 固定为 UTF-8、无 BOM、LF、末尾一个 LF、2-space indent,精确实物为:
115092F2E950BA5CA5ECDA5A0F167DD90FB19449D4CC3AE1C6AB7AB404A337BA7A43ewogICJtYW5pZmVzdF92ZXJzaW9uIjogMywKICAibmFtZSI6ICJwcm9qZWN0LWluZm8gQmlsaWJpbGkg5a6M5pW06KeG6aKR5YWl5Y+jIiwKICAidmVyc2lvbiI6ICIxLjAuMCIsCiAgInZlcnNpb25fbmFtZSI6ICIxLjAuMCsyMDI2MDgwNS52MDAyIiwKICAiZGVzY3JpcHRpb24iOiAi5LuF5aSE55CG5bey5o6I5p2D55qEIEJWMUhBM282b0VKSiDlrozmlbTop4bpopHku7vliqHjgIIiLAogICJrZXkiOiAiTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF0MmRUMUhHWWFJMERYTTd6WndPVE5CV1hUS2xNQkpNcHlEVmpSVWMrdjZiVW90bUx5b3JhQytheTJzY3k5VVFsdVNaVllxMHRTOHF2UU5OdnVaT2xjNXcyYk9FeG00VEgySUlLdmFWTzhuVnRoSEJuTnoya1hkaU04SXROMHZQWkVtUys4Z3BUQ0kxKzZ3UFR1VWdsTW9YcHFZQlloaWk4Zko1UmtFTlJGM1BSSkJCaWdHdDhzb3FkQkZSWTFRWlVtcFF2OWRZdzRkUnE0TDJDNFF0QmdDbFVnNGJRcHVDcHBpVlo5TEhiZVBpOUlBamM5cjlSOTNLTHpwYUJ1WGRKcGZWUkU1dy82WUhueFA4b3ZYeEJkbDdYa3RtcmRIM3hqN21XVDdRN1pCeGtETnduMlJrcnVENDVYZ0REM3l1TnhPWVNrTEZNa3NlTitVYTY5Z1NTNHdJREFRQUIiLAogICJwZXJtaXNzaW9ucyI6IFsKICAgICJhY3RpdmVUYWIiLAogICAgImNvb2tpZXMiLAogICAgIm5hdGl2ZU1lc3NhZ2luZyIsCiAgICAic2NyaXB0aW5nIiwKICAgICJzaWRlUGFuZWwiCiAgXSwKICAiaG9zdF9wZXJtaXNzaW9ucyI6IFsKICAgICJodHRwczovL3d3dy5iaWxpYmlsaS5jb20vKiIKICBdLAogICJiYWNrZ3JvdW5kIjogewogICAgInNlcnZpY2Vfd29ya2VyIjogImJhY2tncm91bmQuanMiLAogICAgInR5cGUiOiAibW9kdWxlIgogIH0sCiAgInNpZGVfcGFuZWwiOiB7CiAgICAiZGVmYXVsdF9wYXRoIjogInNpZGVwYW5lbC5odG1sIgogIH0sCiAgImFjdGlvbiI6IHsKICAgICJkZWZhdWx0X3RpdGxlIjogIuaJk+W8gOWujOaVtOinhumikeS7u+WKoSIKICB9LAogICJpY29ucyI6IHsKICAgICIxNiI6ICJpY29ucy9pY29uMTYucG5nIiwKICAgICIzMiI6ICJpY29ucy9pY29uMzIucG5nIiwKICAgICI0OCI6ICJpY29ucy9pY29uNDgucG5nIiwKICAgICIxMjgiOiAiaWNvbnMvaWNvbjEyOC5wbmciCiAgfQp9Cg==
builder 必须 base64 严格解码、复算 bytes/SHA、严格 JSON 解析并证明相对原 manifest 只有上述 icons 差异;不得由 PowerShell JSON serializer 重新生成或容忍额外差异。
四个 icon 以 canonical base64 存在 managed-load-contract.json,方案 PASS 后才由 builder 解码为 ZIP entry,不在原17文件树内新建资产:
| entry | bytes | SHA-256 | canonical base64 |
|---|---|---|---|
icons/icon16.png |
109 | FC9FC7B26C322BD264CF991FE92D5929446F1536201A9B8F4CDD4294ACB17EB3 |
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAANElEQVR42mMQMQn7TwlmGJwGgADFBhBrCF4DiDGEoAGEDCLaAFyG0M+AgQnEgUtIQyszAQCnXe2u8NCwkgAAAABJRU5ErkJggg== |
icons/icon32.png |
151 | B18E2B064885BF2E682F6F4CF403554538AFBCED15E13DB90B0FD699A4508828 |
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAXklEQVR42u3WwQ0AIAgDQIZwFGdx/000biBQQmJLwo/HPQjUxly7s00AAQR4HbzVDqhAuAFoSBiAQqQACAgEkEHAAFEIHOBFlAA8kD8BnEvIeYg4nxFvIFEmFECAqj7bk5WwHfB3ywAAAABJRU5ErkJggg== |
icons/icon48.png |
187 | 66BB68173A0DC211E4F1A6A5ABCB97AA466F83D42909817E3D197FCD3F7DDA97 |
iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAgklEQVR42u3YgQnAQAhD0Ruio3SW7r9JSzconEkqfsEBHhynZh3ndXfuBQAAAAAAAADoDHirPSCJKAOkIOUAN0ICcEKkAAdCDlBDbAAVwgpQQCKASkQMUAWJA3YRvwDsQACMf0J8owyyKasE6zQHzZSTkliFYItsFAAAAAAAAADwuR8pbeAzuPoqrAAAAABJRU5ErkJggg== |
icons/icon128.png |
405 | FF72913CB2486830A8503E7B7E71FFCD2F51D7E13A9881ED3D1A4ECA09582210 |
iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAABXElEQVR42u3cUQ3EIAAFQUQgpVrw7wRSEfywc8ka6Jvk7lrSMb+11W24CAC4EAAIAAEgAASAABAAAkAACAABIAAEgAAQAAJAAAgAASAABIAAEAACQAAIAAEgAK70f4wWBwABACAAAAEAIAAAAQAgAAABACAAAAEAIAAAAQAgAAABACAAAAEAIAAAAQAgAAABACAAAAEAIAAAAgAQAAACABAAAAIAcQQAxCEAEEcAQBwCAHEEAMQhAAAAAL4CAPAjEAB/AwFwIwgAt4IB8DAIAI+DAXAgBABHwgBwKBQAx8IBeHB4AIwPQHl4AIwPQHl4AIwPQHl4AIwPgBdFelUsADUARg8DMHgUgKHDAIwcBWDcMADDRgEYNAzAmFEARgwDMGAUgOHCAIwWBiAABIAAEAACQAAIAAEgAASAABAAAkAACAABIAAEgAAQAAJAAAgAASAABIAAEAAAuAjpDuyucugIpcc7AAAAAElFTkSuQmCC |
PNG 还必须由独立 parser 验证 signature、IHDR 尺寸、RGBA 8-bit、CRC、IDAT 可解压、scanline 长度和 IEND;只核对 hash 不足以接受损坏图像。
ZIP entry 集合由5项修订为恰好9项:overlay manifest.json、原 background.js/sidepanel.html/sidepanel.css/sidepanel.js 四文件及上表四个 icon。manifest public key、版本、权限和 Native Host identity 不变,独立派生 extension ID 仍必须等于 oidmclckpdmpabbfedplkbdplmfcenbb。旧 exact-five 正例废止,改为负例;ZIP 缺 icon、尺寸错误、CRC 错误、额外图标或 manifest 任意其他差异均在输出接受前阻断。
正式 source approval 只能在 V004 实现审核 PASS/0 后由原 reviewer 创建,位于源码树、测试树、候选输出树和正式安装树之外。建议路径为 reviewer 私有 worklog;developer 不得创建、覆盖、自签或把临时 fixture 当正式批准。
schema 固定为1,顶层 exact keys 为:
schema
scope
status
task_id
approved_by_role
managed_load_contract
original_source_manifest
managed_load_source_tree
webstore_payload
implementation_review
approved_at
固定值和子合同:
scope=controlled-webstore-upload-sourcestatus=APPROVEDtask_id 为本事项 exact 值approved_by_role=dev.reviewer.projectmanaged_load_contract={path,bytes,sha256}original_source_manifest={path,bytes,sha256},必须是 3681/333BA5...19535managed_load_source_tree={file_count,tree_sha256},tree hash 对实现目录 excluding approval/output 按 path UTF-8 + NUL + bytes ASCII + NUL + lowercase sha256 + LF 排序计算webstore_payload={entry_count,payload_tree_sha256,entries};entries 为9项 exact {path,bytes,sha256}implementation_review={audit_id,audit_path,audit_bytes,audit_sha256,verdict},verdict 必须为 PASSapproved_at 为带时区 RFC3339正式 builder 的 -ValidateOnly/-Build 都必须由管理调度同时传入 approval 的 exact path、bytes 和 SHA-256,并在任何输出前复算。approval 只要任一绑定实物、实现审核或 exact set 漂移即失效;没有“按时间自动延长”或旧 approval fallback。
实现审核前的离线单元测试只允许在 TemporaryDirectory 构造 scope=test-only-controlled-webstore-upload-source 的 synthetic fixture,通过不可从生产 CLI 选择的内部 adapter 注入;生产参数和环境不能开启 test scope。测试必须证明 developer 自签、同树 approval、旧实现审核、错误角色/scope/status 和额外 key 均失败。
V003 第10节“按字段名单词递归拒绝”废止。cookies permission、chrome.cookies API、cookie_store_id 和冻结内存协议字段是合法公开标识符,不因名称出现而阻断。
新的门禁由三层组成:
E_SOURCE_DRIFT。测试使用唯一合成值:
MBX_TEST_SECRET_SENTINEL_7E21A9B9C9DD4E33B72BDCB7D43168B4
把该 sentinel 分别注入 unexpected JSON value、release evidence、审批路径名、合成 registry data、环境变量和错误对象;均须在业务写前失败或被固定错误码替代,且 sentinel 不得进入 ZIP、receipt、stdout/stderr、日志、argv 快照或证据。额外静态负例拒绝 credential literal、Authorization/Cookie header、signed media URL、.pem/private-key、Chrome profile/Cookies 数据复制和任何 secret output sink。文档中用于描述边界的单词及冻结运行时公开 API 不算 secret evidence。
产品实现保持 PowerShell,不再使用 Python BaseException/KeyboardInterrupt/SystemExit 术语。唯一口径为:
Set-StrictMode -Version Latest、$ErrorActionPreference='Stop'。SAFETY_STOP/exit 3,stdout 为单行 canonical JSON,stderr 只含固定 E_*。FAILED_ROLLED_BACK/exit 4;原 ErrorRecord 仅以固定 error code/hash 写外部失败证据,不回显 message/stack 中的路径或值。[System.Management.Automation.PipelineStoppedException]/合作式取消执行同一恢复,恢复后 exit 130 且不得输出成功终态。Stop-Process -Force、进程崩溃和掉电均视为不可捕获中断;不得声称 catch/finally 已覆盖。测试分别用 terminating .NET exception、显式 PipelineStoppedException、实际子进程 Ctrl+C(若测试宿主支持)和 Stop-Process -Force。不再测试或声称“原类型重抛”。非普通终止的核心断言是无成功终态、无伪 final receipt、下次启动按唯一恢复矩阵收口。
install approval 必须冻结一个已存在、普通、非 reparse、位于当前用户 LocalAppData 项目边界内的 receipt parent;installer 不创建或替换 parent。四个目标文件在审批时必须 absent:
managed-extension-install-pending.jsonmanaged-extension-install-receipt.jsonmanaged-extension-install-recovery-receipt.jsonmanaged-extension-rollback-pending.jsonrollback final/recovery 文件路径也由 install receipt 冻结并在 rollback 前证明 absent。每个操作使用 CreateNew -> FileStream.Flush(true) -> same-volume atomic rename 写文件;不覆盖。
任何公开模式先取得 current-user named mutex:Local\project-info-bili-managed-load-{SHA256(user SID + policy key)前24位},再执行 recovery-before-normal-mode。mutex 防止本工具并发;完整 policy preimage 的最后复算负责识别外部漂移。
安装 pending 是在 policy 写入前持久化的 immutable intent,exact fields 至少包含:
schema=1、operation=install、phase=PREPAREDrun_id、task、created_at、owner SID hashString、expected data hash/lengthFINAL_RECEIPT_ATOMIC_RENAMEpending 成功落盘后才允许最后一次 preimage 复算和 target-absent 检查,再写 exact policy value。写后必须复算完整 postimage;其他 values 与 preimage 一致,target 是唯一新增项。final install receipt 先写临时文件并 Flush(true),其 atomic rename 到 absent final path 是唯一 commit point。pending 在成功后保留且由 final receipt 绑定,不清理、不改写。
每次启动在普通门禁前检查 pending/final:
| 持久化状态 | 当前 policy | 动作 |
|---|---|---|
| final exact 存在 | exact committed postimage | 视为已提交;Install 安全停止,HealthCheck 可继续 |
| pending exact、final absent | exact preimage | 写 CreateNew recovery receipt=NO_POLICY_MUTATION;不改 registry |
| pending exact、final absent | exact preimage + 本 target exact | 仅删除本 target,复算恢复 exact preimage,写 recovery receipt=INSTALL_PREIMAGE_RESTORED |
| pending exact、final absent | target/其他 value/key 任意漂移 | SAFETY_STOP/E_RECOVERY_AMBIGUOUS;不覆盖、不删除 |
| final/pending/temp 任一 schema/hash/binding 不明 | 任意 | SAFETY_STOP/E_RECEIPT;保留现场 |
install recovery 完成后不自动重试。原 approval/receipt 文件名已消费;下一次安装必须由管理员形成新 approval 和全新 absent receipt paths。
Rollback 在 exact committed install state 下先写 immutable rollback pending,绑定 install receipt、active postimage、目标 value 和 rollback final path;删除目标后验证 policy 恢复 exact install preimage。rollback final receipt atomic rename 是唯一 rollback commit point,pending 同样保留。
| 持久化状态 | 当前 policy | 动作 |
|---|---|---|
| rollback final exact | exact install preimage(target absent) | 视为 rollback 已提交 |
| rollback pending、final absent | exact active postimage | 写 recovery receipt=NO_POLICY_MUTATION;保持 active |
| rollback pending、final absent | exact install preimage(target absent) | 只恢复 exact target,验证 active postimage,写 recovery receipt=ROLLBACK_ACTIVE_PREIMAGE_RESTORED |
| rollback pending、final absent | 任意其他状态 | SAFETY_STOP/E_RECOVERY_AMBIGUOUS;不写 registry |
外部 drift、target 被改成非 exact data、其他 values 漂移或所有权记录不明时,恢复不得猜测。失败证据只能写入管理员批准的独立 failure root,不能改写 manifest-bound 或正式 receipt。
Python 测试以 TemporaryDirectory 的 file-registry adapter 启动真实子 PowerShell;在 pending flush、最后 preimage check、value write/delete、postimage verify、final temp flush、final rename 前后各以 marker 同步,然后 Stop-Process -Force。每点重新启动实际入口,断言唯一矩阵、无伪成功 receipt、无自动重试、其他 values bytes 不变。还要覆盖 unknown temp、pending 篡改、target exact/非 exact、其他 value drift 与 recovery receipt 写失败;歧义态必须零 registry mutation。
install approval、install pending/final、rollback pending/final 和 HealthCheck 共同使用一个 source-controlled canonical 算法。preimage exact keys:
key_exists
target_value_name
target_absent
values
canonical_sha256
values 按 value name 的 ordinal UTF-16 code unit 顺序排列,每项 exact keys 为 {name,kind,data_bytes,data_sha256}。允许 kind 及规范 bytes:
String、ExpandString:.NET GetValue(..., DoNotExpandEnvironmentNames) 的字符串编码为 UTF-16LE 加一个终止 NUL;MultiString:每项 UTF-16LE+NUL,末尾再加一个 NUL;DWord:4-byte little endian;QWord:8-byte little endian;Binary:原 bytes;Unknown/None 或无法无损规范化的值:E_POLICY_PREIMAGE,不写入。canonical stream 为:
key_exists ASCII + LF
对每个 value:name UTF-8 + NUL + kind ASCII + NUL + data_bytes decimal ASCII + NUL + lowercase data_sha256 ASCII + LF
最终 SHA-256 用大写十六进制。approval/receipt 不保存其他 value 的 raw data,只保存 name/kind/length/hash;错误输出不得回显 name 之外的数据。
V003 第7.2节的“其他 value names 排序哈希”废止。install approval 顶层 exact keys 固定为:
schema
scope
status
task_id
approved_by_role
release_approval
source_approval
policy
policy_preimage
native_host
receipt_paths
approved_at
固定 schema=1、scope=install-exact-managed-extension-policy、status=APPROVED、approved_by_role=project.admin。policy 精确冻结 key、空闲十进制 target name、kind=String、exact extension ID+official update URL data 的 length/hash;policy_preimage 使用上节完整结构且 target absent;receipt_paths 冻结全部 existing parent 与 absent target paths;native_host 精确绑定已安装 build-005 三文件与 allowed origin。
测试至少覆盖 key absent/existing、零/多个其他 values、所有允许 registry kinds、排序、空字符串/MultiString、data hash/length 漂移、同名 target race、两个进程并发、其他 value 在各持久化点改变、rollback 后完整 preimage。所有非目标 values 的规范摘要必须逐项不变。
V003 第4节文件集合保持不变;icon 与 overlay bytes 存入 managed-load-contract.json,不新增原扩展资产文件。实现后 builder ZIP 为9项,source approval 是实现审核后的 reviewer-owned 树外文件,不属于产品源码或 ZIP。
V003 第11节按以下修订:
性能目标继续是每次纯离线 builder/installer <5s,真实子进程 kill 矩阵和 project regression 不计入单次 CLI 目标。
V003+V004 是唯一组合实施合同。V004 先沿原 reviewer 链做 F1—F6 聚焦设计复审;PASS 前不得创建 managed-load 代码、测试、图标实物或候选 ZIP。
设计 PASS 只授权离线实现与测试。实现审核 PASS 后,reviewer 才能创建第3节 source approval。后续仍依次需要:受权 Web Store upload/publish、exact release evidence/reviewer release approval、project.admin install approval、受控 policy install、正常 Chrome 状态核验和 runtime 单独调度。任何门失败都不得回退非标准加载方式。