Files
workinf_Blender_Wasm/docs/CURRENT_EXECUTION_PLAN.md
mes123456 7c16b279ae
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled
Advance M7 workflows and release operations
2026-08-15 17:43:53 -04:00

866 lines
55 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Web Blender V1 当前执行计划
更新时间2026-08-15
## 1. 交付目标
当前交付物是 `Web Blender Modeler V1`,不是 Blender 5.2 的完整浏览器移植。
V1 产品承诺、明确排除项和发布门以 `WEB_BLENDER_MODELER_V1_SCOPE.md` 为准。
浏览器基线仅为 Chromium。产品架构保持为
```text
React 工作区和编辑器
-> versioned TypeScript protocols
-> Web Workers
-> Blender Main / Depsgraph WASM 子集
-> binary SceneIR / Three.js WebGL 或 OffscreenCanvas viewport
-> OPFS 大文件 + IndexedDB 元数据
```
本计划是当前唯一的短周期领取队列。长期 Blender 功能对标仍记录在
`BLENDER_5_2_WEB_FEATURE_PARITY.md``status/parity-ledger.json`,但不以长期全域差距
阻断已明确限定范围的 V1。
## 2. 文档与事实源
| 文件 | 唯一职责 |
| --- | --- |
| `WEB_BLENDER_MODELER_V1_SCOPE.md` | V1 产品契约、支持矩阵、非目标、发布标准 |
| `CURRENT_EXECUTION_PLAN.md` | 当前任务顺序、最小任务、依赖和退出条件 |
| `PROJECT_STATUS_AND_NEXT_WORK.md` | 已实现能力、风险、验证命令总览 |
| `BLENDER_5_2_WEB_FEATURE_PARITY.md` | Blender 5.2 全域长期差距 |
| `status/parity-ledger.json` | 功能域和 V1 slice 的机器事实 |
| `status/release-evidence.json` | 最近一次可审计发布证据快照 |
文档冲突时按上表职责解释;机器状态冲突时以校验脚本能够同时验证的 ledger 和 evidence
为准,不靠描述性文字覆盖失败结果。
## 3. 完成规则
### 3.1 最小任务规则
每个任务只产生一个主要行为变化或一个证据变化。任务状态只允许:
- `[ ]` 未开始;
- `[~]` 正在执行;
- `[x]` 已实现且验收通过;
- `[!]` 有可复现阻断,必须附命令、错误和解除条件。
不能仅凭协议存在、fixture 存在、UI 可显示或测试代码已写入,就把任务标为完成。
### 3.2 功能任务完成定义
适用项必须同时具备:
1. 正例使用生产代码路径,不在测试中复制另一套实现。
2. 非法输入、预算超限或未声明能力返回稳定结构化错误码。
3. Worker 可取消;取消后不得发布迟到结果。
4. 资源释放可观测;释放后 CPU/WASM/GPU/OPFS 临时占用回到预算内。
5. Main 或持久化状态修改必须经过 revision验证 undo/redo、原子保存和重开。
6. 浏览器行为至少在 Chromium 生产配置验证;视口相关能力覆盖主线程和
OffscreenCanvas Worker除非 V1 范围明确只承诺其中一个。
7. 独立验收命令退出码为 0并产生至少一个与实现或测试绑定的 SHA-256。
8. 状态文档、ledger、evidence 和代码描述一致。
### 3.3 发布证据规则
`release-evidence.json` 中任何 `true` 字段必须:
- 由成功 evidence record 绑定;
- 记录实际命令、耗时、输出摘要和非空构件 SHA-256
- 失败时不能保留过期成功状态;
- 不得用 mock、跳过、仅 schema 单测或只有 hash 格式校验替代真实运行。
## 4. 重新盘点后的事实基线
### 4.1 已完成工程基础
- React/Three.js 工作区、主线程 WebGL 与 OffscreenCanvas Worker 视口已存在。
- Blender 5.2 Main 子集已编译为 WASMWorker/C ABI、结构化错误和内存统计已存在。
- `.blend` 导入、已声明编辑命令、undo/redo、保存、OPFS/IndexedDB、重启重开已形成闭环。
- 二进制 Mesh/非 Mesh SceneIR、range patch、LOD cache、GLB 和有限 USD 路径已存在。
- VDB desktop/server converter、HTTP range/OPFS、Float32 NanoVDB WebGPU、有限多 grid
材质、显式 resident LRU 和故障恢复已存在。
- 12 个 N-015 至 N-026 功能域的 Blender 全域 `parityStatus` 均为 `BLOCKED`;其 V1
required slice 的 `releaseStatus` 均为 `READY`。这两个状态轴不得再次合并。
### 4.2 2026-08-14 本轮复核结果
| 检查 | 结果 |
| --- | --- |
| `npm --prefix web run typecheck` | 通过 |
| `npm --prefix web run lint` | 通过 |
| `npm --prefix web test` | 9/9 通过 |
| `npm --prefix web run test:status-consistency` | 通过12 parity blocked、0 release blocked |
| `npm --prefix web run test:release-evidence` | 通过17 records、0 missing、`READY` |
### 4.3 2026-08-15 重新盘点结论
这次盘点把“V1 发布切片”和“完整 Blender Web 对标”分开统计,禁止用一个百分比混合两种
完成定义:
| 观察轴 | 已完成 | 未完成/阻断 | 当前判断 |
| --- | --- | --- | --- |
| V1 family release | 12/12 `releaseStatus=READY` | 0 family release blocked | V1 功能切片已实现 |
| Blender 5.2 全域 parity | 0/12 `parityStatus=COMPLETE` | 12/12 `BLOCKED` | 不是完整 Web Blender |
| 发布证据字段 | 17 条成功 record、0 missing49/49 唯一 acceptance 通过 | 无 V1 证据缺口 | release gate 与 acceptance 审计链已闭环 |
| 浏览器 | Chromium 主线程/Offscreen 两条路径 | Firefox、WebKit 未纳入 | Chromium-only |
| Blender runtime | Main/Depsgraph/WebEngine 有界 WASM 子集 | 完整窗口系统、GPU 后端、Python/add-on、全量 operator 未移植 | 子集架构,不是桌面二进制直编 |
| 交付 | 离线 binary/source archive、SBOM、SHA-256 可复现 | 正式部署模板、持续发布流水线、跨机器复验待做 | 本地 V1 RC 已收口 |
2026-08-15 重新执行 `typecheck``lint`、14 个 Node tests、status consistency、release
evidence checker 和 `git diff --check`,均退出 0。M6-03 后 acceptance runner 再次解析 12 个
family 的 50 条声明,去重为 49 条命令并全部通过,命令总耗时 480,169 ms清单 SHA-256 为
`d5fb0a7b2df92b076f8b05ccd68903d60e3352b9423b0c1404065f6cbcbdd45c`。官方 Blender 5.2.0
Linux archive SHA-256 为 `96f6c181a30f4950607839dc84d42a354b250d8a0231b098b59b7bc69c351c48`
运行时 `USD=True`desktop USD roundtrip 已通过。
第一次重跑误用了本地 `USD=False` Blender结果为 48/49该失败证据未标 READY。修正为上述
官方 runtime 后完整重跑 49 条,而不是手改失败记录。当前 release evidence 生成时间为
`2026-08-15T05:37:25.215Z`17 条 record 均为 exit code 0、非空输出和非空构件 hash
总命令耗时 553,577 ms。`v1-user-loop` record 已绑定上述 acceptance
清单 hash。
### 4.4 当前阻断与决策顺序
1. `P0`V1 可部署 RC 已完成 M6 71/71M7 已完成 7/18下一领取点为 `M7-08` Worker 崩溃恢复。
2. `P1`binary/source archive 已在独立目录复验quick/Chromium/release 三条
CI lane 与 RC manifest 已联合校验;发布/限制/恢复和运维合同均已进入离线包。
3. `P1`pthread/single-thread、真实 HTTP、缓存升级、归档离线、OPFS 断网和空目录
deploy/upgrade/rollback 均已有可复验证据M7 开始核心项目体验硬化。
4. `P2`:完整 Blender 功能域继续受 VDB demand paging、PBVH、Geometry Nodes evaluator、
通用 Shader、完整编辑器/渲染/媒体和安全脚本边界阻断。
### 4.5 真实发布缺口
当前 V1 release gate 已无 evidence 或 acceptance 缺口,`faults.oom` 由独立 Chromium 四场景
命令和构件 hash 绑定。`geometry1M`、4K/8K texture、600 帧 simulation cache、断网、device
loss、恶意 blend、zip bomb、离线包和 V1 用户闭环均已在最终 M5 全矩阵回归。后续代码变化
必须使 source/tool/package hash 过期并重跑对应证据。Blender 全域 `parityStatus=BLOCKED`
长期差距不因 V1 gate `READY` 而关闭。
## 5. 里程碑总览
| 里程碑 | 交付物 | 状态 | 退出条件 |
| --- | --- | --- | --- |
| M0 范围与状态模型 | V1 契约、双轴 ledger、P0 用户闭环 | 已完成,持续回归 | 状态一致性与 V1 闭环通过 |
| M1 当前工作区收口 | VDB/WebGPU 与现有证据可复验 | 已完成,持续回归 | 静态门、VDB 全矩阵、V1 闭环全部通过 |
| M2 10M geometry | 大几何浏览器性能与恢复证据 | 已完成,持续回归 | `performance.geometry10M=true` |
| M3 long media | 长时间线索引、seek、取消与重启证据 | 已完成,持续回归 | `performance.longMedia=true` |
| M4 OOM | 四类确定性内存故障与恢复证据 | 已完成,持续回归 | `faults.oom=true` |
| M5 V1 RC | 可复现离线候选包、SBOM、校验和 | 已完成,持续回归 | release gate `READY`、49/49 acceptance |
| M6 可部署 RC | 双 WASM 运行时选择、真实 HTTP、离线包、CI、运维合同 | 已完成71/71 | single/pthread 可解释,真实部署与归档 P0 通过 |
| M7 核心体验硬化 | 项目状态机、恢复、存储、输入和可访问性 | 进行中7/18 | 30 分钟编辑/保存/重开 soak 通过 |
| M8 VDB 自动分页 | GPU 缺页反馈、range/OPFS、LRU、双视口恢复 | 未开始 | 64 MiB sparse bundle 与三视角 golden 通过 |
| M9 非 Mesh/GP/Paint | 字体、Curve、Grease Pencil、Paint 增量闭环 | 未开始 | 每个新增 writer 独立通过 Main/undo/save/golden |
| M10 GN/Shader/NLA/Simulation | 白名单求值、cache、编译与阻断 | 未开始 | 四域分别通过 desktop/WASM/fault 门 |
| M11 Render/Compositor/Media | 灯光、渲染、合成、媒体执行边界 | 未开始 | 本地白名单与 server 边界均可审计 |
| M12 Asset/IO/Editors | 资产、格式、编辑器和上下文工作流 | 未开始 | 每个格式/editor 有独立 round-trip 或稳定阻断 |
| M13 Scripting/Security | 脚本默认拒绝、服务端隔离、CSP、供应链 | 未开始 | 恶意输入矩阵和 release 安全门通过 |
| M14 跨浏览器/设备 | Firefox、WebKit、触控、笔、HiDPI、IME | 未开始 | 新浏览器进入 quick/P0/full CI 后才声明支持 |
| M15 全域审计 | Blender 5.2 全域差距和下一发布 | 未开始 | 逐 family 审计,不由聚合 release gate 反推完成 |
M0 至 M5 已完成并转入持续回归;当前严格领取 M6。里程碑内部允许先写纯校验任务但不得在
前一小里程碑失败时把后一小里程碑标为完成M7 至 M15 不得绕过 M6 发布合同扩功能。
## 6. M0 范围、状态和 P0 闭环
### M0.1 V1 范围收敛
- [x] `M0-SCOPE-01` 定义 V1 用户和核心使用场景。
- [x] `M0-SCOPE-02` 定义 `LOCAL_EXACT/LOCAL_BOUNDED/SERVER/EXCLUDED`
- [x] `M0-SCOPE-03` 明确 Chromium-only 和不承诺完整 Blender UI/渲染/模拟。
- [x] `M0-SCOPE-04` 将 PBVH、完整 Geometry Nodes、任意 Shader、完整 NLA、完整 VDB
demand paging 等移出 V1 required slice。
### M0.2 双轴状态模型
- [x] `M0-STATE-01` ledger schema 分离 `parityStatus``releaseStatus`
- [x] `M0-STATE-02` 每个 family 声明 V1 required/excluded slices。
- [x] `M0-STATE-03` 校验 required/excluded 不重叠且都引用已声明 slice。
- [x] `M0-STATE-04` 校验 `READY` 的 required slices 全部完成。
- [x] `M0-STATE-05` 校验依赖不存在缺失和环。
- [x] `M0-STATE-06` N-026 只聚合 V1 `releaseStatus` 和真实 evidence 缺口。
- [x] `M0-STATE-07` 旧 schema、非法状态、依赖环、无构件 evidence 均有负例。
### M0.3 单一 P0 用户闭环
固定流程:
```text
import .blend
-> object/mesh/material edit
-> undo -> redo
-> atomic save
-> terminate StorageWorker + WebEngineWorker
-> reopen and compare stable IDs/geometry/material
-> main-thread + Offscreen viewport non-empty pixels
-> GLB export and semantic round-trip
-> unsupported shader stable block
```
- [x] `M0-LOOP-01` 创建独立 `test:v1-user-loop` 命令。
- [x] `M0-LOOP-02` 覆盖对象、Mesh 和 Principled 材质编辑。
- [x] `M0-LOOP-03` 覆盖 Main revision 的 undo/redo。
- [x] `M0-LOOP-04` 覆盖 StorageWorker 与 WebEngineWorker 双终止重开。
- [x] `M0-LOOP-05` 比较稳定 object/mesh/material ID 和 geometry SHA-256。
- [x] `M0-LOOP-06` 覆盖双生产视口非空像素。
- [x] `M0-LOOP-07` 覆盖 GLB PBR 语义回读。
- [x] `M0-LOOP-08` 覆盖未支持 Shader 的稳定阻断。
- [x] `M0-LOOP-09` 将成功命令和两个构件 SHA-256 写入 evidence。
## 7. M1 当前工作区收口
目标:确认现有 VDB/WebGPU、状态模型和 P0 闭环不是只在局部测试成立。
### M1.1 快速静态门
- [x] `M1-STATIC-01` TypeScript typecheck。
- [x] `M1-STATIC-02` ESLint。
- [x] `M1-STATIC-03` Node unit tests。
- [x] `M1-STATIC-04` status consistency。
- [x] `M1-STATIC-05` release evidence parser/evaluator。
### M1.2 VDB/WebGPU 专项矩阵
- [x] `M1-VDB-01` 校验 VDB availability 和 native resource catalog。
- [x] `M1-VDB-02` 校验 desktop OpenVDB -> NanoVDB converter 与畸形输入。
- [x] `M1-VDB-03` 校验 server job 隔离、取消、超时和 hash 等价。
- [x] `M1-VDB-04` 校验 conversion boundary 结构化阻断。
- [x] `M1-VDB-05` 校验 NanoVDB OPFS hash binding 和 Worker 重启。
- [x] `M1-VDB-06` 校验 Float32/Vec3 CPU 与 WGSL sampling。
- [x] `M1-VDB-07` 校验主线程与 Offscreen 生产视口。
- [x] `M1-VDB-08` 校验多 grid/X 视角固定 golden不仅检查 hash 格式。
- [x] `M1-VDB-09` 校验全局 resident budget、LRU 次序和唯一释放。
- [x] `M1-VDB-10` 校验网络、Worker、device-loss 故障恢复。
- [x] `M1-VDB-11` 确认文档仍明确阻断自动缺页重绘、联合重开、大 bundle 联合故障和发布
三视角 golden。
### M1.3 P0 和工作区一致性
- [x] `M1-REG-01` 重新运行 `test:v1-user-loop`
- [x] `M1-REG-02` 重新运行包含 release gate 的 Chromium 专项。
- [x] `M1-REG-03` 执行 `git diff --check`
- [x] `M1-REG-04` 核对所有未提交文件都有明确来源,不删除或回退既有用户改动。
- [x] `M1-REG-05` 更新本节状态和 evidence 时间戳时不伪造未运行命令。
M1 退出命令:
```bash
npm --prefix web run typecheck
npm --prefix web run lint
npm --prefix web test
npm --prefix web run test:status-consistency
npm --prefix web run test:release-evidence
npm --prefix web run test:vdb-availability
npm --prefix web run test:vdb-native
npm --prefix web run test:vdb-server
npm --prefix web run test:vdb
npm --prefix web run test:vdb-opfs
npm --prefix web run test:vdb-webgpu
npm --prefix web run test:vdb-viewport
npm --prefix web run test:vdb-faults
npm --prefix web run test:v1-user-loop
git diff --check
```
## 8. M2 10M Geometry 发布门
目标:证明 10,000,000 triangles 项目能通过二进制/分块路径在 Chromium 内先显示可交互
LOD并能取消、释放和恢复。禁止构造 10M 元素 JSON禁止同时保留多份完整源数组。
### M2.1 契约和预算
- [x] `M2-GEO-01` 定义 10M reporttriangle/vertex/chunk 数、源字节、传输字节、
first-interactive-frame、JS/WASM/GPU 峰值、取消延迟、释放后占用和最终状态。
- [x] `M2-GEO-02` 固定 10M 精确计数、chunk 上限、LOD triangle budget 和测试超时。
- [x] `M2-GEO-03` 发布命令没有可把默认 fixture 降到小规模的环境开关。
- [x] `M2-GEO-04` 为非法计数、chunk 越界、重复/缺失 range 定义稳定错误。
### M2.2 分块二进制输入
- [x] `M2-GEO-05` 以固定大小生成 positions/indices chunk任一时刻只保留有界工作集。
- [x] `M2-GEO-06` 每个 chunk 使用 transferable ArrayBuffer发送后验证发送端 detached。
- [x] `M2-GEO-07` range 表连续覆盖 10M triangles无重叠、空洞或整数溢出。
- [x] `M2-GEO-08` 对输入流和 range manifest 生成确定性 SHA-256。
- [x] `M2-GEO-09` 在中途取消,验证 Worker 停止、迟到 chunk 被丢弃且下一会话可启动。
### M2.3 LOD 与首个可交互帧
- [x] `M2-GEO-10` 复用现有 LOD cache key/manifest不创建测试专用缓存格式。
- [x] `M2-GEO-11` 在完整源仍流入时先发布有界 LOD记录首个非空像素时间。
- [x] `M2-GEO-12` 主线程视口渲染 LOD 并完成一次相机/选择交互。
- [x] `M2-GEO-13` OffscreenCanvas Worker 渲染同一 LOD 并报告非空像素。
- [x] `M2-GEO-14` 验证近/远 LOD 切换不重建完整 10M geometry。
### M2.4 内存、释放和证据
- [x] `M2-GEO-15` 采集 `performance.memory`可用时、WASM allocated bytes 和估算 GPU buffer
bytes报告峰值而不是只有最终值。
- [x] `M2-GEO-16` 明确 JS/WASM/GPU 上限并对超限给出稳定失败。
- [x] `M2-GEO-17` dispose renderer/geometry/material、终止 Worker、删除临时 OPFS 数据。
- [x] `M2-GEO-18` 释放后运行一个小场景,证明浏览器会话可恢复。
- [x] `M2-GEO-19` 创建独立 `test:geometry-10m-performance` 命令。
- [x] `M2-GEO-20` 将成功 record 绑定 `performance.geometry10M`,至少 hash 测试、生产实现和
range manifest/golden。
- [x] `M2-GEO-21` 更新 release checker期望 missing 从 3 降为 2。
M2 退出条件:独立命令连续通过;报告 `triangleCount=10_000_000`;双视口有非空像素;取消和
释放通过evidence 中 `geometry10M=true` 且有唯一成功 record。
## 9. M3 Long Media 发布门
目标:验证 V1 有限 Timeline/Sequencer 在长时间线下的索引、seek、取消、cache 和 Worker 重启,
不把完整媒体编辑器或最终编码器纳入 V1。
### M3.1 范围和 fixture
- [x] `M3-MEDIA-01` 固定长时间线 frame range、strip 数和 preview byte budget。
- [x] `M3-MEDIA-02` 使用本地确定性 PNG/WAV 和 manifest测试不得依赖网络或系统 codec。
- [x] `M3-MEDIA-03` 明确 V1 支持的 IMAGE/SOUND 时间索引子集和排除的 movie codec/encode。
- [x] `M3-MEDIA-04` 为未声明 codec、最终编码、损坏 manifest 定义结构化阻断。
### M3.2 索引和 seek
- [x] `M3-MEDIA-05` 建立有界索引,不按总帧数展开巨型 JSON。
- [x] `M3-MEDIA-06` 验证时间线起点、中点、终点和随机 seek 的精确 strip 命中。
- [x] `M3-MEDIA-07` 验证连续 scrub 合并过期请求,只发布最新 revision/frame。
- [x] `M3-MEDIA-08` 记录冷 seek、热 seek 和索引构建时间。
### M3.3 cache、取消和重启
- [x] `M3-MEDIA-09` 对 media preview bytes 使用显式 byte budget 和 LRU。
- [x] `M3-MEDIA-10` 超预算时逐项淘汰,活动 frame 不被错误淘汰。
- [x] `M3-MEDIA-11` 在索引、seek 和 decode 三个阶段分别验证 AbortSignal。
- [x] `M3-MEDIA-12` 终止 Worker 后从 OPFS/IndexedDB manifest 恢复索引和当前 frame。
- [x] `M3-MEDIA-13` 损坏 session manifest 被隔离,正确 manifest 仍可重建。
### M3.4 证据
- [x] `M3-MEDIA-14` 创建独立 `test:long-media-performance` 命令。
- [x] `M3-MEDIA-15` 输出计数、耗时、峰值 cache bytes、取消和重启结果。
- [x] `M3-MEDIA-16` 将成功 record 绑定 `performance.longMedia`
- [x] `M3-MEDIA-17` 更新 release checker期望 missing 从 2 降为 1。
M3 退出条件确定性长时间线专项通过seek/取消/LRU/restart/unsupported codec 均有断言;
`longMedia=true` 且 evidence 构件可复核。
## 10. M4 OOM 发布门
目标:用确定性故障注入验证内存不足不会损坏当前项目或留下不可恢复会话。测试不能依赖真的
耗尽宿主机内存。
### M4.1 统一故障注入契约
- [x] `M4-OOM-01` 定义仅测试构建可用的 allocation fault point 和 fail-after-bytes/count。
- [x] `M4-OOM-02` fault session 使用 token 隔离,默认关闭且不能泄漏到后续请求。
- [x] `M4-OOM-03` 为 WASM、OPFS staging、GPU geometry/texture、VDB resident 分配映射稳定
错误码和 stage。
- [x] `M4-OOM-04` 统一报告 before/peak/after bytes、revision、临时资源和恢复状态。
### M4.2 WASM 与 Main
- [x] `M4-OOM-05` 在 open/read 临时分配失败时不创建半初始化 handle。
- [x] `M4-OOM-06` 在 edit/save 分配失败时保留旧 Main revision 和 undo 栈。
- [x] `M4-OOM-07` 释放 native buffer/handleWorker 重启后可重开旧项目。
### M4.3 OPFS staging
- [x] `M4-OOM-08` 在 staging write 中途注入 quota/OOM。
- [x] `M4-OOM-09` journal 不提交,新 revision 不替换旧 revision。
- [x] `M4-OOM-10` 清理临时文件;重启后旧项目 hash 不变。
### M4.4 GPU 与 VDB
- [x] `M4-OOM-11` GPU geometry/texture budget 超限不创建部分 scene object。
- [x] `M4-OOM-12` dispose 已创建 GPU buffer/texture随后小场景可渲染。
- [x] `M4-OOM-13` VDB resident budget 超限返回 `NANOVDB_GPU_BUDGET_EXCEEDED`
- [x] `M4-OOM-14` VDB page table/resident pages 唯一释放device/session 可恢复。
### M4.5 证据
- [x] `M4-OOM-15` 创建独立 `test:oom-recovery` 命令,四类 fault 全部执行。
- [x] `M4-OOM-16` 记录每类错误码、旧 revision/hash、释放字节和恢复结果。
- [x] `M4-OOM-17` 将成功 record 绑定 `faults.oom`
- [x] `M4-OOM-18` 更新 release checker期望 missing 为 0、gate 为 `READY`
M4 退出条件:四类确定性故障均通过;不存在静默成功、旧 revision 丢失、临时文件泄漏或只能
刷新浏览器恢复的情况;`faults.oom=true`
完成证据:`npm --prefix web run test:oom-recovery` 在 Chromium 中执行 WASM/Main、OPFS staging、
WebGL GPU 资源组和 NanoVDB WebGPU resident/page-table 四类确定性失败;`release:evidence-oom`
生成第 17 条 record。测试报告分别验证 Main revision/hash、undo/redo、旧 OPFS revision/hash、
临时文件归零、部分 GPU object 不发布、NanoVDB buffer 唯一释放以及同会话/重启恢复。
## 11. M5 V1 发布候选
M5 按 `PREP -> STATIC -> ACCEPT -> LOOP -> PERF -> FAULT -> VDB -> PACKAGE -> AUDIT`
串行推进。每个编号只对应一条命令或一个可独立判断的断言;失败项标为 `[!]` 并附退出码、
错误摘要和重跑命令。浏览器任务统一使用空闲的 `WEB_TEST_PORT`,同一任务的 Web server 退出后
才领取下一任务,避免端口复用掩盖真实启动失败。
### M5.0 环境和输入冻结
- [x] `M5-PREP-01` 开始执行前运行 `git status --short --branch`,确认基线为
`main...origin/main` 且无用户未提交改动。
- [x] `M5-PREP-02` 记录 Node、npm、CMake、Ninja、Emscripten、Chromium 和 desktop Blender
的实际版本或明确缺失项。
- [x] `M5-PREP-03` 运行 `tools/web/check-emscripten.sh`,确认 Web toolchain 可用。
- [x] `M5-PREP-04` 运行 `tools/web/check-local-deps.sh`,确认运行时不依赖 CDN。
- [x] `M5-PREP-05` 检查 `build_web_blender6/bin/web_engine.{js,wasm}` 和安装到 Web app 的
engine manifest/hash 一致。
- [x] `M5-PREP-06` 检查发布所需 fixture、VDB native tools、Chrome 可执行文件和本地
Blender 可执行文件均存在。
- [x] `M5-PREP-07` 记录磁盘空间、内存和 CPU 数;资源不足时在运行长矩阵前停止并记录。
- [x] `M5-PREP-08` 运行 `npm --prefix web ci`,只使用 lockfile 完成 clean install。
- [x] `M5-PREP-09` 运行 `npm audit`;将构建链间接依赖 `nanoid` 从 3.3.17 更新到
3.3.18 后重新 clean install确认 high/critical/total 均为 0。
### M5.1 静态和单元门
- [x] `M5-STATIC-01` 运行 `npm --prefix web run typecheck`
- [x] `M5-STATIC-02` 运行 `npm --prefix web run lint`
- [x] `M5-STATIC-03` 运行 `npm --prefix web test`,记录通过/失败/跳过计数14/0/0。
- [x] `M5-STATIC-04` 运行 `npm --prefix web run build`,确认生产构建可生成。
- [x] `M5-STATIC-05` 运行 `npm --prefix web run test:status-consistency`
- [x] `M5-STATIC-06` 运行 `npm --prefix web run test:release-evidence`,只作为旧证据可解析性
检查,不据此刷新 M5 证据。
- [x] `M5-STATIC-07` 运行 `bash tools/web/check-dual-engine.sh`,确认 native 与 WASM 引擎契约。
- [x] `M5-STATIC-08` 运行 `node tools/web/run-web-engine-smoke.mjs`,确认安装后的生产 WASM
可实际启动。
- [x] `M5-STATIC-09` 重建 standalone single-thread 与 pthread Emscripten 变体;两者均使用
Blender 5.2 的 C++20 标准并成功生成 JS/WASM。
### M5.2 V1 required slice 验收
本节命令来源必须是 `status/parity-ledger.json``families[].acceptance`。重复命令只执行一次;
`web:e2e:<pattern>` 的项转换成 Playwright `-g` 过滤器,不能把协议单测替代为浏览器测试。
- [x] `M5-ACCEPT-01` N-015 non-mesh native roundtrip 与 desktop golden。
- [x] `M5-ACCEPT-02` N-015 non-mesh GLB/USD serialization 和 desktop USD roundtrip 通过;
官方 Blender 5.2.0 LTS runtime `USD=True`
- [x] `M5-ACCEPT-03` N-015 1M binary、selection history 和 curve interaction 浏览器门。
- [x] `M5-ACCEPT-04` N-015 `N-015|non-mesh` 聚合 E2E 与真实 OPFS quota。
- [x] `M5-ACCEPT-05` N-016 Grease Pencil native roundtrip、editor 和聚合 E2E。
- [x] `M5-ACCEPT-06` N-017 Paint/weight native roundtrip 和聚合 E2E。
- [x] `M5-ACCEPT-07` N-018 Physics Main reader、simulation cache 和聚合 E2E。
- [x] `M5-ACCEPT-08` N-019 Lighting Main roundtrip 和 Scene exposure E2E。
- [x] `M5-ACCEPT-09` N-020 Compositor Main reader 和有界 CPU compositor E2E。
- [x] `M5-ACCEPT-10` N-021 Sequencer Main reader 和 timeline/codec gate E2E。
- [x] `M5-ACCEPT-11` N-022 Mask Main reader 和 tracking/mask E2E。
- [x] `M5-ACCEPT-12` N-023 Library Main reader、asset/zip 安全 E2E 和共享 VDB fault 门。
- [x] `M5-ACCEPT-13` N-024 Editor Main reader 和 context/keymap E2E。
- [x] `M5-ACCEPT-14` N-025 Script Main reader、isolation 和默认拒绝 E2E。
- [x] `M5-ACCEPT-15` N-026 release gate E2E断言 Chromium-only 声明和 V1 release 状态。
- [x] `M5-ACCEPT-16` 实现 acceptance coverage checker解析 12 个 family、校验命名空间、
npm script 存在、E2E pattern 非空并去重。
- [x] `M5-ACCEPT-17` 实现 acceptance runner顺序执行去重后的命令浏览器命令使用独立端口
写入 ledger SHA-256、环境版本、退出码、耗时和输出摘要。
- [x] `M5-ACCEPT-18` 对未知命名空间、缺失 script、空 pattern、重复声明、stale source/tool/package、
漏项、失败退出码、空输出和 hash 漂移建立负例/断言。
- [x] `M5-ACCEPT-19` 使用 SHA-256 校验的官方 USD-enabled Blender 5.2 重跑 desktop USD
roundtrip归档 hash 和 executable hash 均写入 acceptance evidence。
- [x] `M5-ACCEPT-20` 运行完整 acceptance runner50 declarations、49 unique、49 passed、
0 failedM6-03 后复验总命令耗时 480,169 ms。
- [x] `M5-ACCEPT-21` 将 acceptance evidence SHA-256
`d5fb0a7b2df92b076f8b05ccd68903d60e3352b9423b0c1404065f6cbcbdd45c` 绑定到最终
`v1-user-loop` release record。
### M5.3 P0 用户闭环和 Chromium 回归
- [x] `M5-LOOP-01` 独立运行 `test:v1-user-loop`,覆盖 import/edit/undo/redo/save。
- [x] `M5-LOOP-02` 在同一 P0 测试中确认 StorageWorker 与 WebEngineWorker 均终止后重建。
- [x] `M5-LOOP-03` 确认重开后 object/mesh/material stable ID 和 geometry hash 不变。
- [x] `M5-LOOP-04` 确认主线程与 OffscreenCanvas 两个生产视口均产生非空像素。
- [x] `M5-LOOP-05` 确认 GLB 严格回读通过且未支持 Shader 返回稳定阻断。
- [x] `M5-LOOP-06` 运行 `test:e2e -- --workers=1` 全套 Chromium E2E122/122 通过,
0 失败、0 跳过,总耗时 6.4 分钟。
- [x] `M5-LOOP-07` 运行 `test:browser` 离线引擎发布配置 smoke3/3 通过。
### M5.4 性能和容量矩阵
- [x] `M5-PERF-01` 运行 100k/1M geometry `test:release-performance`
- [x] `M5-PERF-02` 运行 10M geometry 分块、双视口、取消、释放和恢复门。
- [x] `M5-PERF-03` 校验 10M report 精确为 `triangleCount=10_000_000` 且没有缩小 fixture 的开关。
- [x] `M5-PERF-04` 运行 4K texture decode/upload/budget/release 门。
- [x] `M5-PERF-05` 运行 8K texture decode/upload/budget/release 门。
- [x] `M5-PERF-06` 运行 600 帧 simulation cache 性能、LRU 和 Worker restart 门。
- [x] `M5-PERF-07` 运行 long media index/seek/cancel/LRU/restart 门。
- [x] `M5-PERF-08` 每份性能报告均输出 fixture 规模、耗时、峰值/预算、释放后值和恢复状态。
### M5.5 故障和恶意输入矩阵
- [x] `M5-FAULT-01` 运行 WASM/Main、OPFS、GPU、VDB 四场景 OOM recovery。
- [x] `M5-FAULT-02` 运行主线程 WebGL device-loss 恢复门。
- [x] `M5-FAULT-03` 运行网络 range 中断、续传、hash 和 rollback 门。
- [x] `M5-FAULT-04` 运行 malicious `.blend` 截断、长度溢出和预算门,拒绝 5 类输入。
- [x] `M5-FAULT-05` 运行 asset archive zip-bomb、路径穿越和膨胀预算门。
- [x] `M5-FAULT-06` 运行 OPFS quota/staging/journal rollback 浏览器门。
- [x] `M5-FAULT-07` 核对每个失败均返回稳定 error code/stage旧 revision/hash 不变。
- [x] `M5-FAULT-08` 核对每个故障后同会话或 Worker 重启的小场景恢复成功且临时资源归零。
### M5.6 VDB/WebGPU 发布矩阵
- [x] `M5-VDB-01` 校验 VDB resource catalog、license、固定 SHA-256 和 availability。
- [x] `M5-VDB-02` 运行 desktop OpenVDB -> NanoVDB native converter 正例与畸形输入。
- [x] `M5-VDB-03` 运行 server job isolation/cancel/timeout 和 desktop/server hash 等价。
- [x] `M5-VDB-04` 运行浏览器 conversion boundary 和稳定 capability block。
- [x] `M5-VDB-05` 运行 HTTP range -> OPFS 原子绑定、tamper 和 Worker restart。
- [x] `M5-VDB-06` 运行真实 Float32/Vec3 NanoVDB CPU/WGSL sampling。
- [x] `M5-VDB-07` 运行主线程 WebGL 与 OffscreenCanvas Worker 生产视口非空像素。
- [x] `M5-VDB-08` 运行多 grid 材质、resident LRU、网络/Worker/device-loss fault 恢复。
- [x] `M5-VDB-09` 核对自动 page fault、深度合成、大 bundle 和发布三视角 golden 仍明确排除。
### M5.7 构件、许可证和可复现性
- [x] `M5-PACKAGE-01` 从 lockfile 重新生成 SPDX 2.3 SBOM共 150 个 package。
- [x] `M5-PACKAGE-02` 检查 third-party notices 覆盖 React、Three、Vite、TypeScript、Playwright、
Blender 和本地 native/WASM 依赖。
- [x] `M5-PACKAGE-03` 重新执行生产 build检查 engine JS/WASM 和 manifest 均进入 dist。
- [x] `M5-PACKAGE-04` 检查 dist 的 HTML/JS/CSS/JSON 不引用 HTTP(S) CDN。
- [x] `M5-PACKAGE-05` 生成离线 binary archive大小 7,585,557 bytes。
- [x] `M5-PACKAGE-06` 生成 corresponding source archive 和 `SOURCE_OFFER.txt`,大小
205,827,673 bytes。
- [x] `M5-PACKAGE-07` 第一次记录 binary/source archive SHA-256。
- [x] `M5-PACKAGE-08` 从相同输入再次生成两个 archive。
- [x] `M5-PACKAGE-09` 断言第二次 binary/source SHA-256 分别与第一次完全相同。
- [x] `M5-PACKAGE-10` 生成顶层 `release/SHA256SUMS.txt`
- [x] `M5-PACKAGE-11` 逐行校验 `SHA256SUMS.txt` 引用文件存在且 `sha256sum -c` 通过。
- [x] `M5-PACKAGE-12` 扫描构件中的 CDN、绝对工作区路径、token/password/private key 特征。
- [x] `M5-PACKAGE-13` binary archive 与 manifest 完全一致source archive 无缓存、trace、
build、dist、测试报告或日志。
### M5.8 声明、证据和最终审计
- [x] `M5-AUDIT-01` UI、README 和 scope 统一使用 `Web Blender Modeler V1`,浏览器范围为
Chromium-only。
- [x] `M5-AUDIT-02` UI 不把 `SERVER/EXCLUDED/BLOCKED` 能力呈现为可本地成功。
- [x] `M5-AUDIT-03` 确认 12 个 family 仍为 `parityStatus=BLOCKED`
- [x] `M5-AUDIT-04` 确认 12 个 V1 required slice 均为 `releaseStatus=READY`
- [x] `M5-AUDIT-05` 运行完整 `release:evidence`,用本轮命令输出和构件 hash 替换旧 records
当前生成时间 `2026-08-15T05:37:25.215Z`17 条 record总命令耗时 553,577 ms。
- [x] `M5-AUDIT-06` 检查 17 条 evidence record 均为 exit code 0、非空输出和非空构件 hash。
- [x] `M5-AUDIT-07` 检查 evidence 的 ledger SHA-256 与当前文件完全一致。
- [x] `M5-AUDIT-08` 运行 `test:release-evidence`,结果 `READY``missing=[]`
- [x] `M5-AUDIT-09` 运行 `test:status-consistency`,结果 12 parity blocked、0 release blocked。
- [x] `M5-AUDIT-10` 运行 `git diff --check`
- [x] `M5-AUDIT-11` 运行 `git status --short --ignored`;源码/证据为 tracked 工作项build、dist、
release、node_modules、测试结果和工具链 cache 均为预期 ignored 生成物。
- [x] `M5-AUDIT-12` 将实际命令、计数、耗时、失败重跑和最终 archive hash 写回本计划与
`PROJECT_STATUS_AND_NEXT_WORK.md`,不得把未运行项标完成。
M5 退出条件:所有必需命令退出码 0release gate `READY`;离线包可复现;当前构件、源码、
SBOM、状态和 evidence SHA-256 相互一致。
M5 最终 archive SHA-256binary
`f2903a75026a0a28615aeb5f4834a3859af83022c82bc50e28437dcbed68e549`source
`9a9c1b505c68a618de842be7c248f628b104b11b80e8a40d111f62540fcba327`。当前下一任务:`M7-08`
## 12. V1 后原子里程碑
本节是 V1 RC 之后的领取顺序。每个里程碑控制在一个可独立回归的行为闭环;同一功能域不再
一次领取 reader、writer、UI、GPU 和发布门。前一里程碑未达到退出条件时,后一里程碑只能做
不会改变产品声明的测试准备。
### M6 可部署 RC
M6 固定按 `runtime -> HTTP -> cache/offline -> archive -> CI -> operations` 串行推进。每个
任务只验证一个行为;上一小里程碑未通过时,不把后一小里程碑的准备工作记为完成。
#### M6.1 single-thread 无隔离启动
- [x] `M6-01` 新建机器可读部署合同,固定 MIME、缓存、COOP、COEP、CORP 和 Range 响应头;
`node tools/web/check-deployment-contract.mjs`、typecheck、lint 和 production build 通过。
- [x] `M6-02` 复用 `CapabilityGateResult` 新增纯函数 `gateWasmThreadingCapability`;仅当
`crossOriginIsolated``SharedArrayBuffer``Worker` 同时可用时放行 pthread 引擎,
缺失项逐条返回稳定结构single-thread 初始化路径不调用该门。
- [x] `M6-03A` 增加仅供测试使用的无隔离 Vite profile默认 dev/preview 仍强制部署合同头。
- [x] `M6-03B` 在独立 Chromium context 断言文档响应没有 COOP/COEP/CORP
`crossOriginIsolated=false``SharedArrayBuffer` 不可用、`Worker` 可用。
- [x] `M6-03C` 断言当前 engine manifest 为 `memory.shared=false`,网络请求不包含 pthread
JS/WASM/worker 资产。
- [x] `M6-03D` 在上述环境等待 single-thread WebEngine 返回 `ready`,同时证明 pthread gate
`BLOCKED`,从行为上保证 single-thread 不受该门阻断。
- [x] `M6-03E` 使用真实 `basic_scene.blend` 完成 open 和一个 Main edit证明不是只加载 UI shell。
M6.1 退出条件:专项命令一次启动独立无隔离服务器,以上五项同进程通过,退出码为 0。
#### M6.2 pthread 选择与回退
- [x] `M6-04A` 扩展 engine manifest schema显式声明 single/pthread variant、JS、WASM、
pthread worker、shared memory 和每个文件 SHA-256v2 纯校验器固定 256 至 32768 pages、
variant 资源隔离和稳定错误路径21 个专项正负例断言通过。生产 manifest/安装路径保持 v1
无隔离 single-thread 专项回归通过。
- [x] `M6-04B` 安装脚本从两个独立构建目录复制 variant 资产到显式 single/pthread URL
生成绑定四个物理文件 SHA-256 的生产 schema v2 manifest同目录和缺失资产负例不会改写目标
Node 专项、manifest/local dependency、build 和无隔离 Chromium 回归通过。旧 single Worker 入口
只作为 `M6-05` fallback 接线前的完整 Main 兼容路径保留。
- [x] `M6-04C` 新增纯函数选择 engine variant输入仅为 manifest、用户策略和平台能力
frozen input 重复调用结果一致,未知策略稳定拒绝。
- [x] `M6-04D` `AUTO` 在完整 pthread gate `READY` 时选择 pthread隔离、SharedArrayBuffer 或
Worker 任一缺失时选择 single五组能力矩阵通过。
- [x] `M6-04E` `PTHREAD_REQUIRED` 在任一能力缺失时返回 `selectedVariant=null` 和原样 M6-02
结构,不向调用方暴露可请求的 pthread URL。
- [x] `M6-04F` 隔离 Chromium 实际加载 pthread JS/WASM校验 manifest hash、
`SharedArrayBuffer`、pool worker 二次 JS 请求和 native handle 创建/释放。
- [x] `M6-04G` 同一 manifest 在无隔离 Chromium 由 AUTO 实际加载 single JS/WASM确认非共享
内存、无 pthread 请求,并继续用完整 single Main 打开和编辑真实 `.blend`
- [x] `M6-05A` 为 pthread factory 增加仅测试可用的确定性初始化失败注入点。
- [x] `M6-05B` `AUTO` 下 pthread 初始化失败只回退一次 single不形成重试循环。
- [x] `M6-05C` fallback 前终止已创建的 pthread worker、timer 和 pending request。
- [x] `M6-05D` fallback 过程中未打开项目时只初始化;已有待打开项目时只执行一次 open。
- [x] `M6-05E` fallback 结果公开 selected/attempted/fallbackReasonUI 不显示 pthread READY。
M6.2 退出条件isolated pthread、unisolated single、forced failure fallback 三个专项测试均通过,
每种路径的资产请求、Worker 数和 open 次数可断言。
#### M6.3 HTTP MIME 与 byte range
- [x] `M6-06A` 从 deployment contract 生成测试用扩展名到 MIME 的唯一映射,不复制常量。
- [x] `M6-06B` 对 HTML、JS、CSS、WASM、JSON、PNG、WAV、BLEND、NVDB 分别执行 GET。
- [x] `M6-06C` 对 engine JS/WASM、pthread worker 和 fixture 分别执行 HEAD断言状态与
`Content-Type`,且 HEAD 无响应体。
- [x] `M6-06D` MIME 错误时测试必须报告 URL、expected、actual不能只返回布尔失败。
- [x] `M6-07A` 对 WASM、BLEND、NVDB 各执行一个闭区间 range断言 `206` 和精确字节。
- [x] `M6-07B` 分别验证 open-ended 与 suffix range若合同不支持则稳定返回 `416`
- [x] `M6-07C` malformed、倒序、越界和 multi-range 分别返回 `416`,不得返回截断的 `200`
- [x] `M6-07D` `206` 同时具有 `Accept-Ranges``Content-Range``Content-Length` 和强 ETag。
- [x] `M6-07E` 相同内容跨请求 ETag 稳定;内容变化后 ETag 必须变化。
- [x] `M6-07F` `If-Range` 匹配时返回对应 `206`,不匹配时返回完整 `200`
- [x] `M6-07G` 中断后从精确 offset 续传并校验合并后的 SHA-256不复用旧 revision 字节。
M6.3 退出条件:同一真实 HTTP server 同时通过 MIME 和 range 正负例矩阵。
#### M6.4 缓存、升级与离线运行
- [x] `M6-08A` HTML 和 engine manifest 固定 `no-cache`,每次启动都能重新验证版本。
- [x] `M6-08B` content-hashed JS/CSS/Worker 固定 immutable稳定 engine URL 必须重新验证 hash。
- [x] `M6-08C` manifest 为每个 variant 绑定同一 releaseId禁止跨 release 混用 JS/WASM/worker。
- [x] `M6-08D` 模拟发布切换:旧 HTML 只加载旧 manifest 全套或明确刷新,不加载混合版本。
- [x] `M6-08E` hash 不匹配时保持旧项目未打开并返回稳定错误,不进入 fallback 的错误 variant。
`npm --prefix web run test:deployment-cache` 从 production build 临时副本启动合同服务器:`/`
`/index.html`、manifest 和 4 个 stable engine 资源均为 `no-cache`;实际构建的入口 JS、CSS 和
3 个 Worker 共 5 项均具有 Vite 内容 hash 且为 immutable。HTML、manifest、stable engine 对相同
ETag 返回无 body `304`,换代后对旧 ETag 返回完整 `200` 和新 ETag临时换代不改写 `web/dist`
- [x] `M6-09A` 从 binary archive 解包后使用合同服务器启动,不读取工作区文件。
- [x] `M6-09B` 新浏览器 profile 冷启动时拦截所有非 loopback 请求,断言请求数为 0。
- [x] `M6-09C` 断开外网但保留本地合同服务器,完成 manifest、WASM、字体和基础 UI 冷启动。
- [x] `M6-10A` 在线创建 OPFS 项目、编辑并原子保存,记录 revision、blend hash 和 stable IDs。
- [x] `M6-10B` 重建 Worker 并切换到外网断开状态,从 OPFS 重开同一 revision。
- [x] `M6-10C` 离线重开后继续 Main edit、undo/redo 和保存revision 单调增加。
- [x] `M6-10D` 离线导出 GLB 并严格回读,且无非 loopback 请求。
M6.4 退出条件版本切换负例、archive 冷启动和 OPFS 离线闭环分别有独立命令与报告。
#### M6.5 归档独立复验
- [x] `M6-11A` 使用 `mktemp -d` 解包 binary archive禁止引用仓库 `web/dist`
- [x] `M6-11B` 校验 `SHA256SUMS.txt`、deployment contract、license、SBOM 和 binary manifest。
- [x] `M6-11C` 从临时目录启动合同服务器并运行 browser smoke退出后释放端口和临时 profile。
- [x] `M6-12A` 在另一个空临时目录解包 corresponding source archive。
- [x] `M6-12B` 校验 source offer 指向的版本、许可证、lockfile、CMake 与 Web 源码全部存在。
- [x] `M6-12C` 扫描 source archive拒绝 build、dist、release、cache、trace、绝对开发路径和凭据。
- [x] `M6-12D` 从 source archive 执行 lockfile install、typecheck、build并比对可重现清单。
M6.5 退出条件binary/source 两个归档均在独立目录复验,报告包含 archive 与关键文件 SHA-256。
#### M6.6 CI 分层与机器报告
- [x] `M6-13A` 确定仓库实际 CI provider、runner OS、Node/Chrome/Blender/Emscripten 版本矩阵。
- [x] `M6-13B` quick lane 从 lockfile 安装,执行 typecheck、lint、unit、status 和 evidence schema。
- [x] `M6-13C` quick lane 缓存只以 lockfile/toolchain key 命中,不缓存 release evidence。
- [x] `M6-14A` Chromium lane 执行 P0 user loop 和主线程/Offscreen 双视口 smoke。
- [x] `M6-14B` Chromium lane 执行 network、device-loss、OOM、quota 与 malicious-input fault smoke。
- [x] `M6-14C` Chromium lane 每个 browser server 使用独立动态端口,失败后也必须清理。
- [x] `M6-15A` release lane 顺序执行全 E2E、性能矩阵、VDB、acceptance 和离线复现。
- [x] `M6-15B` release lane 只在受保护 ref 或显式 dispatch 运行,不由普通 quick push 重复触发。
- [x] `M6-15C` 任一 release 子命令失败时证据状态为失败,不能上传旧 READY JSON。
- [x] `M6-16A` 三条 lane 均输出 schema-versioned JSON命令、exitCode、duration、environment。
- [x] `M6-16B` 报告绑定 commit、lockfile、ledger、engine、archive 和测试构件 SHA-256。
- [x] `M6-16C` 上传前运行 schema 与 hash checker报告和构件采用固定 retention。
2026-08-15 完整 release lane 的 19/19 子命令通过,总命令耗时
1,245,732 msfull E2E 126/126V1 acceptance 49/49。quick 6/6、Chromium 9/9 和
release 19/19 报告由 `check-ci-report.mjs` 联合校验,同时绑定 commit
`17ab961485fe2ea1574c5f0b7d3ef9608a2bf424`。失败注入返回 exit code 17 并仅写入
`FAILED` 报告。当前 binary/source archive SHA-256 分别为
`ca09540e8f5c0157bb85d62c98aeb3291ea195a29585bc8e05afb308747a8ff5`
`95b3a747425081a205b1966c004a08da4cb37aab7ba0a649ff076713f7010f74`
M6.6 退出条件fresh runner 上 quick/Chromium/release 三条 lane 通过,失败注入不会保留成功证据。
#### M6.7 运维与 RC 冻结
- [x] `M6-17A` 部署 runbook 从空目录安装 binary archive并验证 HTTPS/loopback 前置条件。
- [x] `M6-17B` 升级 runbook 覆盖新旧 manifest、cache、OPFS schema 和 Worker 版本切换。
- [x] `M6-17C` 回滚 runbook 保留项目数据,只回滚 app/engine releaseId并验证旧版可读策略。
- [x] `M6-17D` 故障诊断表覆盖 MIME、range、isolation、hash、quota、Worker 和 GPU 错误。
- [x] `M6-17E` 在一个全新临时目录逐条实跑部署、升级、回滚命令并记录输出。
- [x] `M6-18A` 固定 RC semver、commit、releaseId、binary/source/SBOM SHA-256。
- [x] `M6-18B` 变更说明只列已验证 V1 能力,并链接明确 excluded/server/blocked 清单。
- [x] `M6-18C` 已知限制包含 Chromium-only、single/pthread 选择、存储和 GPU 预算。
- [x] `M6-18D` 发布恢复说明包含项目备份、升级失败回滚和证据校验命令。
- [x] `M6-18E` 最终运行 quick、Chromium、release lane所有结果绑定同一 RC commit。
M6 退出条件:离线包和一个真实 HTTP 部署均通过同一 P0 流程single/pthread 选择可解释;
CI 可从 lockfile 和对应源码重现当前 binary/source hash。
### M7 核心项目体验硬化
- [x] `M7-01` 记录 import/open/save/save-as/export 五个用户动作的状态机。
- [x] `M7-02` 对重复 open、并发 save 和 close-during-save 建立互斥规则。
- [x] `M7-03` 大文件导入显示真实字节进度并支持取消。
- [x] `M7-04` 取消 import 后释放 input buffer、native handle 和 staging 文件。
- [x] `M7-05` save 中断时旧 revision 和旧 hash 保持不变。
- [x] `M7-06` dirty state 只由成功 Main transaction 改变。
- [x] `M7-07` undo 回到保存 revision 时 dirty state 清除。
- [ ] `M7-08` Worker 崩溃时展示可恢复错误,不清空当前项目列表。
- [ ] `M7-09` 重启 Worker 后恢复 selection、frame、workspace 和项目 revision。
- [ ] `M7-10` recent projects 对缺失/损坏 OPFS 条目执行隔离和修复提示。
- [ ] `M7-11` 存储预算面板报告项目、快照、LOD、媒体、VDB 分项字节。
- [ ] `M7-12` 清理单个项目时只删除该项目 content-addressed 引用的孤儿资源。
- [ ] `M7-13` 键盘焦点、菜单、modal、Escape 取消形成一致上下文规则。
- [ ] `M7-14` 1440x900、1280x720、移动窄屏下无控制重叠和文本溢出。
- [ ] `M7-15` 主线程与 Offscreen 视口的选择、相机和 gizmo 行为一致。
- [ ] `M7-16` P0 用户流程增加无鼠标键盘路径和基础可访问性检查。
- [ ] `M7-17` 用户可见错误只显示稳定短消息,详细诊断进入可导出报告。
- [ ] `M7-18` 完成 30 分钟持续编辑、自动保存、重开 soak 测试。
### M8 VDB 自动分页最小闭环
- [ ] `M8-01` 定义 GPU page-fault feedback buffer schema、容量和 overflow code。
- [ ] `M8-02` shader 对未驻留 leaf 记录唯一 page ID不越界写 feedback。
- [ ] `M8-03` CPU 读取 feedback 后排序、去重并绑定 render revision。
- [ ] `M8-04` stale frame feedback 不触发 I/O。
- [ ] `M8-05` page request 使用现有 manifest range/hash不建立第二套地址模型。
- [ ] `M8-06` 同页并发请求合并,取消最后一个订阅者时中止 range。
- [ ] `M8-07` page hash 错误不写 resident cache并返回稳定错误。
- [ ] `M8-08` LRU 淘汰跳过当前 frame pin 的 page。
- [ ] `M8-09` page upload 成功后只安排一次渐进重绘。
- [ ] `M8-10` 重绘上限防止坏数据造成无限 render loop。
- [ ] `M8-11` 主线程 WebGPU 验证缺页、加载、重绘到确定性像素。
- [ ] `M8-12` Offscreen Worker 验证相同页序列和最终像素。
- [ ] `M8-13` page fetch 中 network interruption 可从精确 byte offset 续传。
- [ ] `M8-14` Worker restart 从 OPFS 恢复 manifest但不信任未复验 resident 状态。
- [ ] `M8-15` device loss 重建 page table并按可见集合有界回放。
- [ ] `M8-16` OOM 释放 page table/resident/feedback buffer 各一次。
- [ ] `M8-17` 64 MiB sparse bundle 性能与取消门。
- [ ] `M8-18` Volume Main、asset binding、双视口联合保存重开。
- [ ] `M8-19` desktop/主线程/Offscreen 三视角 golden 和误差阈值。
- [ ] `M8-20` 只有 M8 全部通过后更新 N-015 对应 sliceN-015 全域仍不自动 COMPLETE。
### M9 非 Mesh、Grease Pencil 与 Paint 增量
- [ ] `M9-01` 外部字体导入先做路径、类型、大小和 hash 校验。
- [ ] `M9-02` 字体进入 OPFS content-addressed asset 后才写 Main VFont。
- [ ] `M9-03` 字体替换/撤销/保存/重开/缺失资产形成闭环。
- [ ] `M9-04` Curve 完整 topology editor 先冻结 operator 白名单和预算。
- [ ] `M9-05` 每个新增 Curve operator 单独完成 Main/undo/save/golden 后再开放 UI。
- [ ] `M9-06` Grease Pencil marquee 只操作当前 drawing 的稳定 point/stroke ID。
- [ ] `M9-07` Grease Pencil 2D canvas 与 3D viewport 使用同一 selection revision。
- [ ] `M9-08` Grease Pencil layer/frame reorder 完成 undo/save/reopen。
- [ ] `M9-09` Paint 建立真实深度可见性采样,不用 CPU proxy 冒充。
- [ ] `M9-10` Paint stroke 分块提交且一次 pointer session 只产生一个 undo step。
- [ ] `M9-11` Texture paint dirty tile 原子写入 packed/UDIM 资产。
- [ ] `M9-12` Weight paint normalize/limit/mirror 与 Blender desktop golden 对比。
- [ ] `M9-13` PBVH 若不进入 WASM则相关笔刷保持明确 capability block。
- [ ] `M9-14` 三个编辑域分别通过 Worker restart、OOM、GPU release 和小场景恢复。
### M10 Geometry Nodes、Shader、NLA 与 Simulation
- [ ] `M10-01` 从 Blender Main 读取图拓扑、socket 默认值、link 和稳定 node ID。
- [ ] `M10-02` 为 Geometry Nodes 建立 allowlist不支持节点保留原数据并阻断求值。
- [ ] `M10-03` 每个 allowlist 节点增加 desktop fixture、WASM 输出和误差阈值。
- [ ] `M10-04` field/domain 转换显式预算,禁止按无限域展开 JSON。
- [ ] `M10-05` Simulation Zone cache 绑定 graph/source/revision hash。
- [ ] `M10-06` cache 取消、LRU、重启和损坏隔离通过后才允许播放。
- [ ] `M10-07` Shader 图只编译声明的 Principled/Image/Normal/Math 子集。
- [ ] `M10-08` shader compile key 包含 graph、texture、color space 和 renderer backend。
- [ ] `M10-09` compile failure 不替换上一份可用 material pipeline。
- [ ] `M10-10` 任意未支持 Shader 节点返回 stable capability block不静默降级。
- [ ] `M10-11` NLA track/strip/action/time mapping 先完成只读精确求值。
- [ ] `M10-12` NLA 单个编辑 operator 分别完成 Main transaction、undo 和保存重开。
- [ ] `M10-13` Physics 本地 solver 按 family 探测;不支持项只消费 desktop/server bake。
- [ ] `M10-14` 每类 cache 验证 source hash、frame range、字节预算和版本。
- [ ] `M10-15` GN/Shader/NLA/Simulation 分别建立浏览器性能、OOM 和恶意图输入门。
### M11 Lighting、Render、Compositor 与 Sequencer
- [ ] `M11-01` Camera/Light/World/Scene color management 建立字段级 parity 表。
- [ ] `M11-02` 每个支持字段通过 Main edit、undo、save/reopen 和 viewport 映射。
- [ ] `M11-03` Three/WebGPU 灯光数量、shadow map 和纹理预算显式化。
- [ ] `M11-04` Web 实时渲染结果与 Blender reference 采用可解释图像误差指标。
- [ ] `M11-05` Cycles/复杂 Eevee/硬件后端固定为 server job不在浏览器伪造等价。
- [ ] `M11-06` server render job 绑定 source hash、Blender build、设置和输出 hash。
- [ ] `M11-07` Compositor allowlist 每新增一个 node 单独增加 CPU/WebGPU golden。
- [ ] `M11-08` unsupported compositor graph 保留原图并阻断执行。
- [ ] `M11-09` Sequencer IMAGE/SOUND/MOVIE codec 由运行时 probe 决定,不按扩展名猜测。
- [ ] `M11-10` long media proxy/cache 绑定源 hash 和 decode capability。
- [ ] `M11-11` seek/scrub/decode 迟到结果全部受 revision gate 控制。
- [ ] `M11-12` 最终视频编码固定 server/export capability不误报本地完成。
- [ ] `M11-13` audio context suspend/resume、设备缺失和静音恢复有专项测试。
- [ ] `M11-14` render/compositor/media 全部覆盖取消、重启、预算释放和恢复。
### M12 Asset、IO、Editor 与工作流
- [ ] `M12-01` asset catalog schema migration 有向前/向后兼容 fixture。
- [ ] `M12-02` append/link/override 分别定义 stable ID、所有权和失效语义。
- [ ] `M12-03` library source 只允许声明 origin路径穿越和符号链接逃逸被拒绝。
- [ ] `M12-04` archive 每个 entry 在解压前检查数量、压缩比、总字节和目标路径。
- [ ] `M12-05` GLB、OBJ、STL、PLY 每种格式建立独立导入/导出能力矩阵。
- [ ] `M12-06` 每种支持格式至少一个 desktop roundtrip 和一个 loss report。
- [ ] `M12-07` USD/Alembic 依赖固定 desktop runtime identity不由本机偶然能力决定 gate。
- [ ] `M12-08` View3D/Outliner/Properties 的 selection/context/revision 使用同一 store。
- [ ] `M12-09` UV/Node/Graph/Dope/NLA editor 每次只开放有 Main writer 的操作。
- [ ] `M12-10` operator search 从 capability registry 生成,不维护第二份成功列表。
- [ ] `M12-11` keymap resolution 按 editor/modal/tool 上下文确定性排序。
- [ ] `M12-12` workspace/layout 保存重开不修改 Blender 场景 revision。
- [ ] `M12-13` editor dispose 后无 DOM listener、Worker request 或 GPU resource 泄漏。
- [ ] `M12-14` 典型建模、动画、资产复用流程建立任务级 E2E不只做控件 smoke。
### M13 Scripting、安全与平台边界
- [ ] `M13-01` Python/Text autorun/add-on 默认拒绝保持产品级不可绕过。
- [ ] `M13-02` script manifest 只读解析限制文本、模块、路径和依赖数量。
- [ ] `M13-03` 若引入签名脚本,先定义签名者、权限、撤销和审计模型。
- [ ] `M13-04` 浏览器 sandbox 不提供 DOM、网络、OPFS、Worker 的隐式全权限。
- [ ] `M13-05` server Blender job 使用一次性目录、只读源、资源限制和网络策略。
- [ ] `M13-06` 所有 server result 验证 source/settings/build/output hash 后才绑定项目。
- [ ] `M13-07` CSP 禁止 inline script、eval 和未声明 origin。
- [ ] `M13-08` fixture 覆盖恶意 blend、图片、字体、媒体、archive、node graph 和 manifest。
- [ ] `M13-09` fuzz crash 不写入 release evidence修复后必须加入最小回归样本。
- [ ] `M13-10` capability report 明确 native window/CUDA/Metal/HIP/OptiX 不等价。
- [ ] `M13-11` 依赖审计区分生产、构建、测试依赖并设置严重级别门。
- [ ] `M13-12` SBOM、license、source offer 与每个 release archive hash 绑定。
### M14 跨浏览器与设备扩展
- [ ] `M14-01` 先冻结 Chromium RC不在同一变更中同时追三个浏览器差异。
- [ ] `M14-02` Firefox capability probe 覆盖 OPFS、WebGL2、WebGPU、Worker 和 isolation。
- [ ] `M14-03` Firefox P0 流程逐项记录 PASS/BLOCKED不启用静默 fallback。
- [ ] `M14-04` Firefox 主线程视口先通过,再领取 Offscreen 路径。
- [ ] `M14-05` WebKit capability probe 和 P0 流程采用相同规则。
- [ ] `M14-06` WebKit 主线程视口先通过,再领取 Offscreen 路径。
- [ ] `M14-07` 浏览器不支持 WebGPU 时只隐藏明确依赖 WebGPU 的能力。
- [ ] `M14-08` 内存上限按浏览器/设备档位选择已声明预算,不自动扩大。
- [ ] `M14-09` 触控、笔、HiDPI、IME 和非 US 键盘分别建立输入 fixture。
- [ ] `M14-10` 每个新增浏览器加入 quick/P0/full 三层 CI 后才进入发布声明。
### M15 全域对标和下一发布
- [ ] `M15-01` 每季度从 Blender 5.2 operator/data-block 清单重新生成 parity 差距。
- [ ] `M15-02` 每个 family 的 `COMPLETE` 必须没有 summary-only、proxy-success 或隐式 loss。
- [ ] `M15-03` LOCAL_EXACT 必须有相同 fixture 的 desktop/WASM 语义或像素 golden。
- [ ] `M15-04` LOCAL_BOUNDED 必须同时验证白名单正例和非白名单稳定阻断。
- [ ] `M15-05` SERVER 必须验证提交、取消、隔离、预算、hash 和结果绑定。
- [ ] `M15-06` EXCLUDED 必须验证 UI 不开放、文件数据不丢失、保存不破坏原项目。
- [ ] `M15-07` 12 个 family 分别达到自身退出条件,禁止由 N-026 聚合状态反推完成。
- [ ] `M15-08` 全域发布候选重新跑 clean build、acceptance、性能、fault 和安全矩阵。
- [ ] `M15-09` 在独立机器复验 binary/source archive 和所有 hash。
- [ ] `M15-10` 发布说明逐项列出支持、受限、server 和 excluded 能力。
实际领取顺序固定为:先完成 M5随后 M6、M7再按产品需求在 M8 至 M13 中一次选择一个
最小闭环M14 只在 Chromium RC 稳定后开始M15 是状态审计,不是把剩余功能一次性打包。